• [转] Ansible 系列之 Playbooks 剧本


    [From] https://www.cnblogs.com/hanyifeng/p/6435875.html

    一、Playbooks 介绍

    1.Playbooks是Ansible的配置,部署和编排语言。它们可以描述您希望远程系统执行的策略,或一般IT流程中的一组步骤。

    如果说ansible 模块 是你车间里的工具,那么playbooks 是你的说明书/使用手册,并且资源清单上的主机是你的原材料。

    在基本层面上,剧本可以用于管理远程主机的配置与部署,在更高的一层来说,它们可以对涉及滚动更新的多层发布任务进行排序,并且可以将操作委派给其他主机,同时与监视服务器和负载平衡器进行交互。

    官网介绍的说playbooks 篇章有很多的内容,他们不建议我们一下子学完,重在积累,以及在使用的过程中来学习,建议不错。嘿嘿

    在ansible 上使用Playbooks是一种完全不同于adhoc的任务执行模式,并且特别强大。简单地说,playbooks是一个非常简单的配置管理和多机器部署系统的基础,以及非常适合部署复杂应用程序的系统。
    Playbooks可以对任务进行编排,就像我们要安装一个程序,写个安装shell脚本一样,在哪一步复制配置文件,最后一步启动服务。虽然/usr/bin/ansible 可以运行一些临时任务,但是针对复杂的配置,并且可以将配置标准化,这个时候就需要Playbooks了。
     

    2.Playbooks Language example

     
    Playbooks 语言是以YAML 格式表示,并且有最小的语法,有意的说明它不是一个编程或者脚本语言,它是一种写配置文件的语言。简洁可读性高。
     

    YAML 语法:

    这里我们先大致的看下YAML的语法吧,看看有什么需要遵守和记住的编写规则。
     
    a.对于Ansible来说,几乎每个YAML文件都以列表开头。列表中的每个项目是 键/值对的列表,通常称为“列表”或“字典”。因此,我们需要知道如何在YAML中编写列表和字典。
     
    b.还有一个地方,每个文件都是以  --- 开始,以 ... 结尾。这也是yaml 语言格式的一部分,指出文档的开始和结束。
     
    c.列表中所有的词都是 - (减号和空格)开头的相同缩进的行。如下:
    复制代码
    ---
    # A list of tasty fruits
    fruits:
        - Apple
        - Orange
        - Strawberry
        - Mango
    ...
    复制代码

    d.字典以简单的形式表示 key: value (冒号后面必须跟一个空格),不能使用tab 键如下:

    # An employee record
    martin:
        name: Martin D'vloper
        job: Developer
        skill: Elite

    e.也有复杂的数据结构,例如带有字典的列表。

    下面是一个随意的YAML文件,和ansible无关。

    复制代码
    ---
    # 员工记录
    name: xiaoming
    job: Developer
    skill: Elite
    employed: True
    foods:
        - Apple
        - Orange
        - Strawberry
        - Mango
    languages:
        perl: Elite
        python: Elite
        pascal: Lame
    education: |
        4 GCSEs
        3 A-Levels
        BSc in the Internet of Things
    复制代码

    f.区分大小写,如果在 key:value 里,value里面有冒号,需要用 “” 号将 整个value 包围住。

     

    OK,继续学习palybooks。。。

    每个palybook(剧本)都有一个或多个palys (每一场)组成。palys的目的是将一组主机映射到一些明确定义的角色,由ansible来调用任务。基本来说,一个任务就是调用ansible 的某个模块。

     

     二、真枪实战

    1.看一个基本的palybook

    复制代码
    ---
    - hosts: all
      tasks:
        - name: Installs nginx web server
          yum: name=nginx state=installed update_cache=true
          notify:
            - start nginx
    
      handlers:
        - name: start nginx
          service: name=nginx state=started
    复制代码

    结合着上面YAML遵守的规则来分析下。

    第一行中,文件开头为 ---;这是YAML 将文件解释为正确的文档的要求。YAML 允许多个“文档”存在于一个文件中,每个“文档”由 --- 符号分割,但Ansible只需要一个文件存在一个文档即可,因此这里需要存在于文件的开始行第一行。

    YAML对空格非常敏感,并使用空格来将不同的信息分组在一起,在整个文件中应该只使用空格而不使用制表符,并且必须使用一致的间距,才能正确读取文件。相同缩进级别的项目被视为同级元素。

    以 - 开头的项目被视为列表项目。作为散列或字典操作,它具有key:value格式的项。YAML文档基本上定义了一个分层的树结构,其中位于左侧是包含的元素。

    在第二行

    ---
    - hosts: all
    这是我们在上面学到的YAML中的列表项,但由于它在最左侧的级别,它也是一个Ansible“palys”(某个任务)。plays基本上是在某一组主机上执行的任务组,以允许它们实现要分配给它们的功能。每个play必须指定一个主机或一组主机,正如上面一样,指定了all 所有主机。
     
     
    往下看,看下第一个任务
    复制代码
    ---
    - hosts: all
      tasks:
        - name: Installs nginx web server
          yum: name=nginx state=installed update_cache=true
          notify:
            - start nginx
    复制代码

    在上面,有 “tasks:"与 "hasts:" 同级。它包含一个包含键值对的列表(因为它以一个 "-" 开头).

    第一个,“name”,这是一个任务的描述。可以随意定义。

    下一个key 是 "yum",这里引用的是Ansible 的一个模块,就像我们直接在命令行使用ansible 命令一样,如下面:

    # ansible all -m yum -a "name=nginx state=present update-cache=true"

    "yum" 这个模块允许我们指定一个软件包和它应该在的状态,上面例子中是应“已安装”的状态。update-cache = true 部分告诉我们的远程机器在安装软件之前更新其软件包缓存(相当于yum makecache)。

    “notify”项 包含具有一个项目的列表,它会呼叫 “start nginx”。这不是一个Ansible内部命令,它是对handlers的引用,当从任务中调用该处理程序时,它可以执行某些功能。我们将在下面定义“start nginx” 的处理程序

    复制代码
    ---
    - hosts: all
      tasks:
        - name: Installs nginx web server
          yum: name=nginx state=installed update_cache=true
          notify:
            - start nginx
    
      handlers:
        - name: start nginx
          service: name=nginx state=started
    复制代码

    “handlers” 部分与“hosts”、“tasks” 处于同一级别。handlers就像任务,但它们只有在客户端系统发生了更改的任务被告知时才运行。

    例如,我们在这里有一个handlers,在安装软件包后启动Nginx服务。除非 “Installs nginx web server” 任务导致系统更改,否则不会调用处理程序,这意味着包必须安装,并且之前没有被安装。

     我们将上述内容保存一个nginx_install.yml 文件中。

       本文中文属于作者原创,转载请注明出处。飞走不可http://www.cnblogs.com/hanyifeng/p/6435875.html

    2. 运行Ansible-playbook

    一旦你制作了一个playbook.yml,可以使用这种格式轻松地调用:

    ansible-playbook playbook.yml

    例如,如果我们想在所有的主机上安装和启动Nginx,我们可以使用上面的nginx_install.yml,运行以下命令:

    [root@ansibler task]# ansible-playbook nginx_install.yml

    执行完成后会输出以下信息:

    复制代码
    [root@ansibler task]# ansible-playbook nginx_install.yml
    
    PLAY [all] *********************************************************************
    
    TASK [setup] *******************************************************************
    ok: [192.168.30.177]
    ok: [192.168.30.176]
    
    TASK [Installs nginx web server] ***********************************************
    changed: [192.168.30.176]
    changed: [192.168.30.177]
    
    RUNNING HANDLER [start nginx] **************************************************
    changed: [192.168.30.177]
    changed: [192.168.30.176]
    
    PLAY RECAP *********************************************************************
    192.168.30.176             : ok=3    changed=2    unreachable=0    failed=0
    192.168.30.177             : ok=3    changed=2    unreachable=0    failed=0
    复制代码

    从上面可以看出,ansible 的 任务是按顺序来执行的,并且每个任务执行都会显示该任务的名称及状态,便于我们了解当前任务的执行状态。在结尾处,是每个任务的状态统计。

    上面我们指定了运行playbook的主机为所有hosts 列表中的主机,如果需要指定某些主机可以使用 -l 选项,如下:

    ansible-playbook -l 192.168.30.176 nginx.yml

     

    3.增加一些功能到playbook 中

     接着上面的nginx_install 文件,继续。上面的剧本是服务器安装了软件,并正常运行。我们可以向 palybook中添加任务 来扩展功能。

    添加nginx默认首页

    我们可以通过添加几行内容来,告诉它将文件从我们的Ansible服务器传输到选定的主机上,完整内容如下:

    复制代码
    ---
    - hosts: all
      tasks:
        - name: Installs nginx web server
          yum: name=nginx state=installed update_cache=true
          notify:
            - start nginx
        - name: Upload default index.html for host
          copy: src=static_files/index.html dest=/usr/share/nginx/html/ mode=0644
    
      handlers:
        - name: start nginx
          service: name=nginx state=started
    复制代码

    然后我们可以在我们ansible 主机的当前目录中创建一个名为static_files的目录,并将一个index.html文件放在其中。

    mkdir static_files

    index.html文件内容如下:

    复制代码
    <html>
      <head>
        <title>This is a sample page</title>
      </head>
      <body>
        <h1>Here is a heading!</h1>
        <p>Here is a regular paragraph.  Wow!</p>
      </body>
    </html>
    复制代码

    现在,当我们重新运行playbook时,Ansible会检查每个任务。它会看到Nginx已经安装在选定主机上,所以它会进行下一步。并看到新的任务部分,然后将我们的服务器中的index.html文件替换选定主机上默认的index.html文件。

     

    4.注册结果

    当我们手动安装和配置服务时,几乎总是需要知道当前的操作是否成功。我们可以通过使用“register”,把这个功能放到我们的palybooks中。对于每个任务,我们可以选择将其结果(失败或成功)注册在我们稍后可以检查的变量中。

    当使用这个功能时,我们还必须告诉Ansible忽略该任务的错误,因为如果发生任何错误或异常,它会中止该剧本的执行。因此,如果我们想检查任务是否失败或者不决定后续的步骤,我们可以使用 register 功能。

    例如,index.php如果文件存在,我们可以让我们的playbooks上传index.php文件。如果该任务失败,我们可以尝试上传index.html文件。我们将检查任务中的失败情况,因为我们只想在PHP文件失败时上传HTML文件:

    复制代码
    ---
    - hosts: all
      tasks:
        - name: Installs nginx web server
          yum: name=nginx state=installed update_cache=true
          notify:
            - start nginx
    
        - name: Upload default index.html for host
          copy: src=static_files/index.php dest=/usr/share/nginx/html/ mode=0644
          register: php
          ignore_errors: True
    
        - name: Remove index.html for host
          command: rm /usr/share/nginx/html/index.html
          when: php|success
    
        - name: Upload default index.html for host
          copy: src=static_files/index.html dest=/usr/share/nginx/html/ mode=0644
          when: php|failed
    
      handlers:
        - name: start nginx
          service: name=nginx state=started
    复制代码

    备注:

    目前nginx web环境中还不能处理PHP文件
    上述的playbooks版本,尝试将index.php文件上传到选定的主机上。并将该任务的成功或者失败注册到名为“php”的变量中。

    a.如果此操作成功,则接下来运行删除index.html文件的任务。(该删除操作的前提是index.html 存在于playbooks中选定的主机上)

    b.如果此操作失败,则会上传index.html文件。

     

    三、故障记录

    1. 由于之前的系列文章中,测试环境是docker 平台上的容器,鉴于docker 容器内无法由宿主机安装软件并启动,这篇文章便使用了3台虚拟机,系统是centos 6.6,ansible 版本2.2.1,在运行ansible 时,出现以下错误:

    上一个命令还成功了,下一个就失败了。参考以下链接,更新了内核到2.6.32-642.15.1.el6.x86_64.之后就没问题了。

    也有人说是openssh 的问题,升级openssh即可。如果在有人碰到,请先升级openssh组件。如果不行的话,在升级内核。

     

    本文中文属于作者原创,转载请注明出处。飞走不可http://www.cnblogs.com/hanyifeng/p/6435875.html

    参考资料:

    如何写playbooks  https://www.digitalocean.com/community/tutorials/how-to-create-ansible-playbooks-to-automate-system-configuration-on-ubuntu

    ansible故障:https://github.com/ansible/ansible/issues/13876

    每个人都应是守望者,守望我们的心智,我们的理想,以防它在生活中不知不觉地坠落、被操控和被自己遗忘。。。
  • 相关阅读:
    谈谈Nullable<T>的类型转换问题
    MiniProfiler使用方法
    捕获变量
    web服务相关的问题或技巧
    对接mysql数据库遇见的一些问题
    委托
    导出到Excel
    斐波那契数列的运算时间
    .net framework摘抄与理解
    sql 语句
  • 原文地址:https://www.cnblogs.com/pekkle/p/9669432.html
Copyright © 2020-2023  润新知