zoukankan      html  css  js  c++  java
  • [转] 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

    每个人都应是守望者,守望我们的心智,我们的理想,以防它在生活中不知不觉地坠落、被操控和被自己遗忘。。。
  • 相关阅读:
    数据库字段太多,批量快速建立实体类方法(适合大量字段建立实体类)
    SQL service 中的 ”输入SQL命令窗口“ 打开了 “属性界面” 回到 ”输入SQL命令窗口“
    计算机软件编程英语词汇集锦
    编程常用英语词汇
    svn上传和下载项目
    当启动tomcat时出现tomcat setting should be set in tomcat preference page
    Implicit super constructor Object() is undefined for default constructor. Must define an explicit constructor
    eclipse中选中一个单词 其他相同的也被选中 怎么设置
    Spring Boot的@SpringBootApplication无法引入的问题
    最全的SpringCloud视频教程
  • 原文地址:https://www.cnblogs.com/pekkle/p/9669432.html
Copyright © 2011-2022 走看看