zoukankan      html  css  js  c++  java
  • Ansible之Playbook

    官方文档

    https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html#playbook-keywords
    

    Playbook 核心组件

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

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

    hosts 组件

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

    one.example.com
    one.example.com:two.example.com
    172.16.1.50
    172.16.1.*
    Websrvs:dbsrvs #或者,两个组的并集
    Websrvs:&dbsrvs #与,两个组的交集
    webservers:!dbsrvs #在websrvs组,但不在dbsrvs组
    

    案例:

    - hosts: websrvs:appsrvs
    

    remote_user 组件

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

    - hosts: websrvs
      remote_user: root
      
      tasks:
        - name: test connection
          ping:
          remote_user: wang
          sudo: yes      #默认sudo为root
          sudo_user:long #sudo为long
    

    task列表和action组件

    play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出

    task两种格式:

    action: module arguments    #示例: action: shell wall hello
    module: arguments           #建议使用  #示例: shell: wall hello
    

    注意:shell和command模块后面跟命令,而非key=value
    范例:

    [root@ansible ansible]# cat hello.yaml
    ---
    # first yaml file
    - hosts: websrvs
      remote_user: root
      gather_facts: no  #不收集系统信息,提高执行效率
      
      tasks:
        - name: test network connection
          ping:
        - name: excute command
          command: wall "hello world!"
    

    范例:

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

    其它组件说明

    某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers任务

    还可以通过"tags"给task打标签,可在ansible-playbook命令上使用-t指定进行调用

    playbook 命令

    格式

    ansible-playbook <filename.yml> ... [options]
    

    常见选项

    --syntax-check   #语法检查,可缩写成--syntax, 相当于bash -n
    
    -C --check       #模拟执行,只检测可能会发生的改变,但不真正执行操作,dry run
    
    --list-hosts     #列出运行任务的主机
    
    --list-tags      #列出tag
    
    --list-tasks     #列出task
    
    --limit 主机列表  #只针对主机列表中的特定主机执行
    
    -i INVENTORY     #指定主机清单文件,通常一个项对应一个主机清单文件
    
    --start-at-task START_AT_TASK #从指定task开始执行,而非从头开始,START_AT_TASK为任务的
    name
    
    -v -vv -vvv      #显示过程
    

    范例:

    [root@ansible ansible]# cat hello.yml
    ---
    - hosts: websrvs
      tasks:
        - name: hello
          command: echo "hello ansible"
          
    [root@ansible ansible]#ansible-playbook hello.yml
    
    [root@ansible ansible]#ansible-playbook -v hello.yml
    

    范例

    [root@ansible ansible]# ansible-playbook file.yml --check  #只检测
    [root@ansible ansible]# ansible-playbook file.yml
    [root@ansible ansible]# ansible-playbook file.yml --limit websrvs
    

    ShellScripts VS Playbook 案例

    # SHELL脚本实现
    
    #!/bin/bash
    # 安装Apache
    yum install --quiet -y httpd
    # 复制配置文件
    cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
    cp/tmp/vhosts.conf /etc/httpd/conf.d/
    # 启动Apache,并设置开机启动
    systemctl enable --now httpd
    
    # Playbook实现
    ---
    - hosts: websrvs
      remote_user: root
      gather_facts: no
      
      tasks:
        - name: "安装Apache"
          yum: name=httpd
        - name: "复制配置文件"
          copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
        - name: "复制配置文件"
          copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
        - name: "启动Apache,并设置开机启动"
          service: name=httpd state=started enabled=yes
    

    利用 playbook 创建 mysql 用户

    范例:mysql_user.yml

    ---
    - hosts: dbsrvs
      remote_user: root
      gather_facts: no
      
      tasks:
        - {name: create group, group: name=mysql system=yes gid=306}
        - name: create user
            user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 home=/data/mysql create_home=no
    

    利用 playbook 安装 nginx

    范例:install_nginx.yml

    ---
    # install nginx
    - hosts: websrvs
      remote_user: root
      gather_facts: no
      
      tasks:
        - name: add group nginx
          group: name=nginx state=present
        - name: add user nginx
          user: name=nginx state=present group=nginx
        - name: Install nginx
          yum: name=nginx state=present
        - name: web page
          copy: src=files/index.html dest=/usr/share/nginx/html/index.html
        - name: start nginx
          service: name=nginx state=started enabled=yes
    

    利用 playbook 安装和卸载httpd

    范例:install_httpd.yml

    ---
    # install httpd
    - hosts: websrvs
      remote_user: root
      gather_facts: no
      
      tasks:
        - name: install httpd
          yum: name=httpd
        - name: modify config list port
          lineinfile:
            path: /etc/httpd/conf/httpd.conf
            regexp: '^Listen'
            line: 'Listen 8080'
        - name: modify config data1
          lineinfile:
            path: /etc/httpd/conf/httpd.conf
            regexp: '^DocumentRoot "/var/www/html"'
            line: 'DocumentRoot "/data/html"'
        - name: modify config data2
          lineinfile:
            path: /etc/httpd/conf/httpd.conf
            regexp: '^<Directory "/var/www/html">'
            line: '<Directory "/data/html">'
        - name: mkdir website dir
          file: path=/data/html  state=directory
        - name: web html
          copy: src=/files/index.html dest=/data/html/
        - name: start service
          service: name=httpd state=started  enabled=yes
    

    执行上面的

    [root@centos8 /etc/ansible]# ansible-playbook install_httpd.yml
    

    范例:remove_httpd.yml

    ---
    # remove httpd
    - hosts: websrvs
      remote_user: root
      gather_facts: no
      
      tasks:
        - name: remove httpd package
          yum: name=httpd state=absent
        - name: remove apache user
          user: name=apache state=absent
        - name: remove config file
          file: name=/etc/httpd state=absent
        - name: remove web html
          file: name=/data/html/ state=absent
    

    执行上面的

    [root@centos8 /etc/ansible]# ansible-playbook remove_httpd.yml
    

    案例:安装Mariadb二进制压缩包

    ---
    # install mariadb 
    - hosts: dbserver
      remote_user: root
      gather_facts: no
    
      tasks:
        - name: create group
          group: name=mysql gid=25 system=yes
        - name: create user
          user: name=mysql uid=25 system=yes group=mysql shell=/sbin/nologin home=/data/mysql create_home=no
        - name: mkdir datadir
          file: path=/data/mysql owner=mysql group=mysql state=directory
        - name: unarchive package
          unarchive: src=files/mariadb-10.2.33-linux-x86_64.tar.gz dest=/usr/local/ owner=root group=root
        - name: link
          file: src=/usr/local/mariadb-10.2.33-linux-x86_64 path=/usr/local/mysql state=link
        - name: install database
          shell: chdir=/usr/local/mysql ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
        - name: config file
          copy: src=files/my.cnf dest=/etc/ backup=yes
        - name: service script
          shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/myqld
        - name: start service
          service: name=mysqld state=started enabled=yes
        - name: PATH variable
          copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
    

    忽略错误 ignore_errors

    如果一个task出错,默认将不会继续执行后续的其它task利用 ignore_errors: yes

    可以忽略此task的错误,继续向下执行playbook其它task

    [root@ansible ansible]# cat test_ignore.yml
    ---
    - hosts: websrvs
      tasks:
        - name: error
          command: /bin/false
          ignore_errors: yes
        - name: continue
          command: wall continue
    

    Playbook中使用handlers和notify

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

    注意:

    如果多个task通知了相同的handlers, 此handlers仅会在所有tasks结束后运行一 次。
    只有notify对应的task发生改变了才会通知handlers, 没有改变则不会触发handlers
    handlers 是在所有前面的tasks都成功执行才会执行,如果前面任何一个task失败,会导致handler跳
    过执行,可以使用force_handlers: yes 强制执行handler
    

    范例:

    ---
    - hosts: websrvs
      remote_user: root
      gather_facts: no
      tasks:
        - name: install httpd
          yum: name=httpd state=present
        - name: install configure file
          copy: src=files/httpd.conf dest=/etc/httpd/conf/
          notify:
            - restart httpd
            - wall
        - name: ensure apache is running
          service: name=httpd state=started enabled=yes
          
      handlers:
        - name: restart httpd
          service: name=httpd state=restarted
        - name: wall
          command: wall "The config file is changed"
    

    范例:

    ---
    - hosts: websrvs
      remote_user: root
      gather_facts: no
      tasks:
        - name: add group nginx
          group: name=nginx state=present
        - name: add user nginx
          user: name=nginx state=present group=nginx
        - name: install nginx
          yum: name=nginx state=present
        - name: config
          copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
          notify:
            - Restart nginx
            - check nginx process
              
      handlers:
        - name: Restart nginx
          service: name=nginx state=restarted enabled=yes
        - name: check nginx process
          shell: killall -0 nginx &> /tmp/nginx.log
    

    范例:强制调用handlers

    - hosts: websrvs
      force_handlers: yes #无论task中的任何一个task失败,仍强制调用handlers
      tasks:
        - name: config file
          copy: src=nginx.conf dest=/etc/nginx/nginx.conf
          notify: restart nginx
            - name: install package
              yum: name=no_exist_package
      handlers:
        - name: restart nginx
          service: name=nginx state=restarted
    

    Playbook中使用tags组件

    官方文档:

    https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html
    

    在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特定tags的task,而非整个playbook文件可以一个task对应多个tag,也可以多个task对应一个tag还有另外3个特殊关键字用于标签, tagged, untagged 和 all,它们分别是仅运行已标记,只有未标记和所有任务。

    案例:

    ---
    # tage example
    - hosts: websrvs
      remote_user: root
      gather_facts: no
      tasks:
        - name: install httpd
          yum: name=httpd state=present
        - name: install configure file
          copy: src=files/httpd.conf dest=/etc/httpd/conf/
          tags:
            - conf
            - file
        - name: start httpd service
          tags: service
          service: name=httpd state=started enabled=yes
    

    范例:列出所有标签

    [root@centos8 /etc/ansible]# ansible-playbook --list-tags httpd.yml 
    
    playbook: httpd.yml
    
      play #1 (websrvs): websrvs	TAGS: []
          TASK TAGS: [conf, file, service]
    
    # 选择标签执行
    [root@centos8 /etc/ansible]# ansible-playbook -t conf,service httpd.yml
    
    # 选择跳过文件某个定义的标签执行
    [root@centos8 /etc/ansible]# ansible-playbook --skip-tags conf httpd.yml
    
    # 跳过未标记标签
    [root@centos8 /etc/ansible]# ansible-playbook httpd.yml --skip-tags untagged
    
  • 相关阅读:
    bzoj3729-Gty的游戏【Splay,博弈论】
    pkusc2021游记
    P4922-[MtOI2018]崩坏3?非酋之战!【dp】
    P5782-[POI2001]和平委员会【2-SAT】
    CF1511G-Chips on a Board【倍增】
    noip范围
    [LGOJ5558]心上秋(倍增)
    学习笔记——动态DP
    [NOIP校内集训]不正常的国家
    [BZOJ4712]洪水(树链剖分+DP)
  • 原文地址:https://www.cnblogs.com/xuanlv-0413/p/14815189.html
Copyright © 2011-2022 走看看