• 25 playbook(一)


    YAML语法结构

    playbook使用yml标记语言,这是一种标记语言,这种标记语言在文件的最开始需要使用三个“-”来说明文件开始,然后使用缩进来说明代码块的范围。下面通过一个简易的实例,来说明playbook的语法。

    YAML 官方网站:http://www.yaml.org

    ---                             #标记文件的开始
    - hosts: webservers             #指定该playbook在哪个服务器上执行
      vars:                         #表示下面是定义的变量,
        http_port: 80               #变量的形式,key: value,这里http_port是变量名,80是值
        max_clients: 200
      remote_user: root             #指定远程的用户名,这里缩进和vars保持了一致,说明变量的代码块已经结束。
      tasks:                        #下面构成playbook的tasks,每个task都有 - name: 开始,name指定该任务的名称。
      - name: ensure apache is at the latest version  #指定该任务的名称。
        yum: pkg=httpd state=latest                   #yum说明要是用的模板名称,后面指定对应的参数,这两行结合起来就相当于一个shell命令。
      - name: write the apache config file            #每个task之间可以使用空行来做区分。
        template: src=/srv/httpd.j2 dest=/etc/httpd.conf #需要说明的是缩进的意义和python中缩进的意义是一样,是来区分代码块的。Copy to clipboardErrorCopied
    

    YAML语言特性

    • YAML的可读性好

    • YAML和脚本语言的交互性好

    • YAML使用实现语言的数据类型

    • YAML有一个一致的信息模型

    • YAML易于实现

    • YAML可以基于流来处理

    • YAML表达能力强,扩展性好

      YAML语法简介

    • 在单一文件第一行,用连续三个连字号"-" 开始,还有选择性的连续三个点号( ... )用来表示文件的结尾

    • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能

    • 使用#号注释代码

    • 缩进必须是统一的,不能空格和tab混用

    • 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的

    • YAML文件内容是区别大小写的,key/value的值均需大小写敏感

    • 多个key/value可同行写也可换行写,同行使用,分隔

    • key后面冒号要加一个空格 比如: key: value

    • value可是个字符串,也可是另一个列表

    • YAML文件扩展名通常为yml或yaml

    支持的数据类型

    YAML 支持以下常用几种数据类型:

    • 标量:单个的、不可再分的值
    • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
    • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)

    标量

    不可在分的量。包括字符串,布尔值,整数,浮点数,Null,时间,日期。

    key对应value

    name: chenyangCopy to clipboardErrorCopied
    

    字典

    字典由多个key与value构成,key和value之间用 :分隔, 并且 : 后面有一个空格,所有k/v可以放在一行,或者每个 k/v 分别放在不同行。

    account: 
     name: chenyang
     age: 30Copy to clipboardErrorCopied
    

    列表

    列表由多个元素组成,每个元素放在不同行,且元素前均使用"-"打头,并且 - 后有一个空格, 或者将所有元素用 [ ] 括起来放在同一行。

    course:
     - linux: centos
     - golang: gin
     - python: djangoCopy to clipboardErrorCopied
    

    三种常见的数据格式

    • XML:Extensible Markup Language,可扩展标记语言,可用于数据交换和配置
    • JSON:JavaScript Object Notation, JavaScript 对象表记法,主要用来数据交换或配置,不支持注释
    • YAML:YAML Ain't Markup Language YAML 不是一种标记语言, 主要用来配置,大小写敏感,不支持tab

    可以用工具互相转换,参考网站:

    https://www.json2yaml.com/

    http://www.bejson.com/json/json2yaml/

    Playbook核心组件

    一个playbook 中由列表组成,其中所用到的常见组件类型如下:

    • Hosts 执行的远程主机列表
    • Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最少元素需包括 name 和 task,一个name只能包括一个task
    • Variables 内置变量或自定义变量在playbook中调用
    • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
    • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
    • tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

    host组件

    Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中。

    one.example.com
    one.example.com:two.example.com
    192.168.1.50
    192.168.1.*
    public:private     #或者,两个组的并集
    public:&private   #与,两个组的交集
    public:!private  #在public组,但不在private组Copy to clipboardErrorCopied
    
    • 案例
    - hosts: public:!privateCopy to clipboardErrorCopied
    

    remote_user组件

    remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户。

    - hosts: public
      remote_user: root
      gather_facts: no             #不收集对应主机的信息,这样运行会快点。
      
      tasks:
        - name: test connection
          ping:
          remote_user: chenyang
          sudo: yes                         #默认sudo为root
          sudo_user: shanhe        #sudo为shanheCopy to clipboardErrorCopied
    

    task列表

    playbook的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task。

    task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。

    每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。

    如果未提供name,则action的结果将用于输出

    ---
    - hosts: public
      remote_user: root
      gather_facts: no
      
      tasks:
        - name: install httpd
          yum: name=httpd 
        - name: start httpd
          service: name=httpd state=started enabled=yes
    

    playbook命令

    格式

    ansible-playbook <filename.yml> ... [options]Copy to clipboardErrorCopied
    

    常见选项

    --syntax-check      #语法检查
    -C --check                     #只检测可能会发生的改变,但不真正执行操作
    --list-hosts    #列出运行任务的主机
    --list-tags         #列出tag
    --list-tasks         #列出task
    --tags                     # 只run 一个tag
    --skip-tags        # 跳过某个task
    --limit 主机列表 #只针对主机列表中的特定主机执行
    -v -vv  -vvv #显示过程Copy to clipboardErrorCopied
    
    • 案例
    [root@instance-gvpb80ao ~]# cat hello.yaml 
    - hosts: public
      remote_user: root
      gather_facts: no
      tasks:
        - name: hello world
          command: echo "Hello Chenyang"
    [root@instance-gvpb80ao ~]# ansible-playbook hello.yaml 
    
    PLAY [public] ************************************************************************************************
    
    TASK [hello world] *******************************************************************************************
    changed: [106.13.81.75]
    
    PLAY RECAP ***************************************************************************************************
    106.13.81.75               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   Copy to clipboardErrorCopied
    
    • 案例2
    [root@instance-gvpb80ao ~]# ansible-playbook -v hello.yaml 
    Using /etc/ansible/ansible.cfg as config file
    
    PLAY [public] ************************************************************************************************
    
    TASK [hello world] *******************************************************************************************
    changed: [106.13.81.75] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "cmd": ["echo", "Hello Chenyang"], "delta": "0:00:00.022512", "end": "2021-05-21 10:33:43.493102", "rc": 0, "start": "2021-05-21 10:33:43.470590", "stderr": "", "stderr_lines": [], "stdout": "Hello Chenyang", "stdout_lines": ["Hello Chenyang"]}
    
    PLAY RECAP ***************************************************************************************************
    106.13.81.75               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   Copy to clipboardErrorCopied
    

    Playbook 初步

    利用playbook创建mysql用户

    ---
    - hosts: db
      remote_user: root
      gather_facts: no
      tasks:
        - name: create group
          group:
            name: mysql
            gid: 748
        - name: create user
          user:
            name: mysql
            group: www
            uid: 748
            shell: /sbin/nologin
            create_home: no
            system: yes
    

    利用playbook安装NGINX

    [root@m01 yaml]# cat nginx_install.yaml 
    ---
    - hosts: web01
      remote_user: root
      gather_facts: no
      tasks:
        - name: create group
          group:
            name: www
            gid: 666
        - name: create user
          user:
            name: www
            group: www
            uid: 666
        - name: yum install nginx
          yum:
            name: nginx
            state: present
          notify: restart nginx
        - name: ensure nginx start
          service:
            name: nginx
            state: started
            enabled: yes
          
      handlers:
        - name: restart nginx
          service:
            name: nginx
            state: restarted
    

    利用 playbook 安装和卸载 httpd

    # 安装httpd
    - hosts: public
      remote_user: root
      gather_facts: no
      tasks:
        - name: Create Group
          group: name=www system=yes gid=777
        - name: Create User
          user: name=www shell=/sbin/nologin system=yes group=www uid=777 home=/home/www create_home=no
        - name: Install nginx
          yum: name=httpd state=present
        - name: Start Nginx
          service:  name=httpd state=started enabled=yes
    
    # 卸载httpd
    - hosts: public
      remote_user: root
      tasks:
        - name: remove httpd package
          yum: name=httpd state=absent
        - name: remove apache user
          user: name=www state=absent
        - name: remove config file
          file: name=/etc/httpd state=absent
        - name: remove web html
          file: name=/var/html/ state=absent
    

    Playbook中使用handlers和notify

    Handlers本质是task list ,类似于MySQL中的触发器触发的行为,其中的task与前述的task并没有本质上的不同,主要用于当关注的资源发生变化时,才会采取一定的操作。而Notify对应的action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。

    - hosts: public 
      remote_user: root
      gather_facts: no
    
      tasks:
        - name: Install httpd
          yum: name=httpd state=present
        - name: Install configure file
          copy: src=httpd.conf dest=/etc/httpd/conf/
          notify: restart httpd
        - name: ensure apache is running
          service: name=httpd state=started enabled=yes
    
      handlers:
        - name: restart httpd
          service: name=httpd state=restarted
    
    [root@instance-gvpb80ao ~]# ansible-playbook test.yaml 
    
    PLAY [public] ************************************************************************************************
    
    TASK [Install httpd] *****************************************************************************************
    ok: [106.13.81.75]
    
    TASK [Install configure file] ********************************************************************************
    changed: [106.13.81.75]
    
    TASK [ensure apache is running] ******************************************************************************
    changed: [106.13.81.75]
    
    RUNNING HANDLER [restart httpd] ******************************************************************************
    changed: [106.13.81.75]
    
    PLAY RECAP ***************************************************************************************************
    106.13.81.75               : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    Copy to clipboardErrorCopied
    

    Playbook中使用tags组件

    在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特定tags的task,而非整个playbook文件。

    - hosts: public 
      remote_user: root
      gather_facts: no
    
      tasks:
        - name: Install httpd
          yum: name=httpd state=present
          tags: install
        - name: Install configure file
          copy: src=httpd.conf dest=/etc/httpd/conf/
          notify: restart httpd
        - name: ensure apache is running
          service: name=httpd state=started enabled=yes
    
      handlers:
        - name: restart httpd
          service: name=httpd state=restarted
    
    ansible-playbook –t install httpd.ymlCopy to clipboardErrorCopied
    

    Playbook中使用变量

    变量名:仅能由字母、数字和下划线组成,且只能以字母开头。

    在playbook的开头通过vars进行定义

    [root@m01 project1]# cat  p2.yml 
    - hosts: webservers
      vars:
        - web_package: httpd
        - ftp_package: vsftpd
      tasks:
        - name: Installed Packages
          yum: 
            name: 
              - "{{ web_package }}"
              - "{{ ftp_package }}"
            state: presentCopy to clipboardErrorCopied
    

    playbook中使用vars_files指定文件作为变量文件

    [root@m01 project1]# cat vars.yml 
    web_package: httpd
    ftp_package: vsftpd
    
    [root@m01 project1]# cat p2.yml 
    - hosts: webservers
      vars_files: ./vars.yml
      tasks:
        - name: Installed Packages
          yum: 
            name: 
              - "{{ web_package }}"
              - "{{ ftp_package }}"
            state: present
    Copy to clipboardErrorCopied
    

    在inventory中定义变量,主机变量优先级高于主机组变量(不推荐,容易将环境弄的特别乱)

    [root@m01 project1]# vim /etc/ansible/hosts 
    [webservers]
    web01 ansible_ssh_host=172.16.1.7
    web02 ansible_ssh_host=172.16.1.8
    [webservers:vars]
    filename=group_vars
    
    [root@m01 project1]# cat p3.yml 
    - hosts: webservers
      tasks:
        - name: Create File
          file: path=/tmp/{{ filename }} state=touchCopy to clipboardErrorCopied
    

    更好的方式是在ansible的项目目录中创建额外的两个变量目录

    group_vars目录下必须存放和inventory清单文件中定义的组名一致,如下
    [root@m01 project1]# cat /etc/ansible/hosts 
    [webservers]
    web01 ansible_ssh_host=172.16.1.7
    web02 ansible_ssh_host=172.16.1.8
    
    [root@m01 project1]# cat group_vars/webservers 
    web_package: httpd
    ftp_package: vsftpd
    # 注意:系统提供了特殊的组,all,也就说在group_vars目录下创建一个all文件,定义变量对所有的主机都生效
    
    
    [root@m01 project1]# cat host_vars/web01 
    web_package: zlib-static
    ftp_package: zmap
    
    [root@m01 project1]# cat group_vars/webservers 
    web_package: httpd
    ftp_package: vsftpd
    
    
    [root@m01 project1]#  cat p4.yml 
    - hosts: webservers
      tasks:
        - name: Installed Packages
          yum: 
            name: 
              - "{{ web_package }}"
              - "{{ ftp_package }}"
            state: present
    
    
    [root@m01 project1]# ansible-playbook p4.yml 
    
    PLAY [webservers] ********************************************************************************************************
    
    TASK [Gathering Facts] ***************************************************************************************************
    ok: [web02]
    ok: [web01]
    
    TASK [Installed Packages] ************************************************************************************************
    ok: [web02]
    changed: [web01]
    
    PLAY RECAP ***************************************************************************************************************
    web01                      : ok=2    changed=1    unreachable=0    failed=0   
    web02                      : ok=2    changed=0    unreachable=0    failed=0   
    Copy to clipboardErrorCopied
    

    通过命令行覆盖变量

    令行直接指定变量所覆盖。使用--extra-vars或-e设定变量。
    [root@m01 project1]# ansible-playbook p4.yml -e "web_package=zarafa-devel" -e "ftp_package=zarafa-utils"Copy to clipboardErrorCopied
    

    变量优先级

    命令行变量--->play中的vars_files--->play中的vars变量-->host_vars中定义的变量--->group_vars/组--->group_vars/all

    [root@m01 project1]# cat p5.yml 
    - hosts: webservers
    #  vars:
    #    filename: play_vars
    #  vars_files:
    #    - ./vars.yml
      tasks:
    
        - name: Create 
          shell: mkdir -pv /tmp/{{ filename }}
          register: mk_test
    
        - name: debug
          debug: msg={{ mk_test }}
    
  • 相关阅读:
    JavaEE——SpringMVC(11)--拦截器
    JavaEE——SpringMVC(10)--文件上传 CommonsMultipartResovler
    codeforces 460A Vasya and Socks 解题报告
    hdu 1541 Stars 解题报告
    hdu 1166 敌兵布阵 解题报告
    poj 2771 Guardian of Decency 解题报告
    hdu 1514 Free Candies 解题报告
    poj 3020 Antenna Placement 解题报告
    BestCoder5 1001 Poor Hanamichi(hdu 4956) 解题报告
    poj 1325 Machine Schedule 解题报告
  • 原文地址:https://www.cnblogs.com/zhaokunhao/p/14832616.html
Copyright © 2020-2023  润新知