• 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 }}
    
  • 相关阅读:
    js 和 jquery的宽高
    client、offset、scroll
    web开发中会话跟踪的方法有哪些
    前端需要注意哪些SEO
    ES6 Set和Map数据结构
    ES6实现数组去重
    ES6 Symbol
    ES6对象的拓展
    ES6数组的拓展
    ES6函数的拓展
  • 原文地址:https://www.cnblogs.com/zhaokunhao/p/14832616.html
Copyright © 2020-2023  润新知