zoukankan      html  css  js  c++  java
  • 005.Ansible的palybook简单使用

    一 Ansible Playbook简介

    ansbile-playbook是一系列ansible命令的集合,利用yaml 语言编写。playbook命令根据自上而下的顺序依次执行。同时,playbook开创了很多特性,它可以允许你传输某个命令的状态到后面的指令,如你可以从一台机器的文件中抓取内容并附为变量,然后在另一台机器中使用,这使得你可以实现一些复杂的部署机制,这是ansible命令无法实现的。

    playbook通过ansible-playbook命令使用,它的参数和ansible命令类似,如参数-k(–ask-pass) 和 -K (–ask-sudo) 来询问ssh密码和sudo密码,-u指定用户,这些指令也可以通过规定的单元写在playbook 。
    ansible-playbook的简单使用方法: ansible-playbook example-play.yml 。

    二 Playbook基本语法

    下面是一个简单的ansible-playbook示例,可以了解其构成:

    # cat user.yml
    - name: create user
      hosts: all
      remote_user: root
      gather_facts: false
      vars:
        user:"test"
      tasks:
        - name: create  user
          user: name="{{ user }}"

    配置项说明:

    • name:对该playbook实现的功能做一个概述,后面执行过程中,会打印 name变量的值
    • hosts:指定对哪些被管理机进行操作;
    • remote_user:指定在远程被管理机上执行操作时使用什么用户,如不指定,则使用ansible.cfg中配置的remote_user
    • gather_facts:指定在执行任务之前,是否先执行setup模块获取主机相关信息,如未用到,可不指定
    • vars:定义后续任务中会使用到的变量,如未用到,可不指定
    • tasks:定义具体需要执行的任务name:对任务的描述,在执行过程中会打印出来。
    • user:指定调用user模块;
    • name:user模块里的一个参数,用于指定创建的用户名称

    同样,如果想实现把这个新增的用户删除,只需将该playbook文件的最后一行替换为如下行再执行相应的playbook即可:

    user: name="{{ user }}" state=absent remove=yes

    三 playbook组成

    3.1 palybook简单演示

    - name: configure nginx
      hosts: 192.168.132.133
      tasks:
        - name: install epel-release
          package: 
            name: epel-release 
            state: present
        - name: install nginx
          package: 
            name: nginx 
            state: present
        - name: create directory
          file: 
            path: ./file 
            state: directory 
            owner: nginx 
            group: nginx
        - name: copy file from remote serevr
          fetch: 
            src: /usr/share/nginx/html/index.html 
            dest: file/
        - name: delete file of remote server
          file: 
            path: /usr/share/nginx/html/index.html 
            state: absent
        - name: create a remote server file
          file: 
            path: /usr/share/nginx/html/index.html  
            state: touch  
            owner: nginx 
            group: nginx
        - name: content
          copy: 
            content: "<h3>welcome ansible</h3>"  
            dest: /usr/share/nginx/html/index.html
        - name: start service
          systemd: 
            name: nginx 
            state: started 
            enabled: yes 
            daemon_reload: yes

    [root@node1 ansible]# ansible-playbook nginx_config.yml

    PLAY [configure nginx] ************************************************************************************************************************
    TASK [Gathering Facts] ************************************************************************************************************************
    ok: [192.168.132.133]
    TASK [install epel-release] *******************************************************************************************************************
    changed: [192.168.132.133]
    TASK [install nginx] **************************************************************************************************************************
    changed: [192.168.132.133]
    TASK [create directory] ***********************************************************************************************************************
    ok: [192.168.132.133]
    TASK [copy file from remote serevr] ***********************************************************************************************************
    changed: [192.168.132.133]
    TASK [delete file of remote server] ***********************************************************************************************************
    changed: [192.168.132.133]
    TASK [create a remote server file] ************************************************************************************************************
    changed: [192.168.132.133]
    TASK [content] ********************************************************************************************************************************
    changed: [192.168.132.133]
    TASK [start service] **************************************************************************************************************************
    changed: [192.168.132.133]
    PLAY RECAP ************************************************************************************************************************************
    192.168.132.133            : ok=9    changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

    查看192.168.132.133

    [root@node3 ~]# rpm -qa |grep epel-release
    epel-release-7-11.noarch
    [root@node3 ~]# rpm -qa |grep  nginx
    nginx-mod-http-xslt-filter-1.16.1-1.el7.x86_64
    nginx-all-modules-1.16.1-1.el7.noarch
    nginx-mod-mail-1.16.1-1.el7.x86_64
    nginx-mod-http-image-filter-1.16.1-1.el7.x86_64
    nginx-mod-stream-1.16.1-1.el7.x86_64
    nginx-filesystem-1.16.1-1.el7.noarch
    nginx-mod-http-perl-1.16.1-1.el7.x86_64
    nginx-1.16.1-1.el7.x86_64
    [root@node3 ~]# systemctl status nginx
    ● nginx.service - The nginx HTTP and reverse proxy server
       Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
       Active: active (running) since Wed 2020-04-29 14:06:10 CST; 2min 25s ago
    [root@node3 ~]# systemctl is-enabled nginx
    enabled

    访问

     

    3.2 yml规则

    yml文件它的基本语法规则如下。

    • 大小写敏感
    • 使用缩进表示层级关系
    • 缩进时不允许使用Tab键,只允许使用空格。
    • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

    # 表示注释,从这个字符一直到行尾,都会被解析器忽略。

    YAML 支持的数据结构有三种。

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

    ansible-playbook常用选项

    3.3 ansible其他用法

    1 打印详细信息

    • -v:打印任务运行结果
    • -vv:打印任务运行结果以及任务的配置信息
    • -vvv:包含了远程连接的一些信息
    • -vvvv:Adds extra verbosity options to the connection plug-ins,including the users being used in the managed hosts to execute scripts, and what scripts have been executed

     [root@node1 ansible]# ansible-playbook nginx_config.yml -v

    2. 校验playbook语法

    [root@node1 ansible]# ansible-playbook nginx_config.yml --syntax-check
    
    playbook: nginx_config.yml

    3. 测试运行playbook

    通过-C选项可以测试playbook的执行情况,但不会真的执行:

     [root@node1 ansible]# ansible-playbook -C nginx_config.yml

    4 Multiple Plays

    # This is a simple playbook with two plays
    
    - name: first play
      hosts: web.example.com
      tasks:
        - name: first task
          yum:
            name: httpd
            status: present
        - name: second task
          service:
            name: httpd
            state: started
        
    - name: second play
      hosts: db.example.com
      tasks:
        - name: first task
          yum:
            name: mariadb-server
            status: present
        - name: second task
          service:
            name: mariadb
            state: started

    四 playbook的结构说明

    playbook是由一个或多个"play"组成的列表。play的主要功能就是对一组主机应用play中定义好的task。从根本上来讲一个task就是对ansible一个module的调用。而将多个play按照一定的顺序组织到一个playbook中,我们称之为编排。

    playbook主要有以下四部分构成:

    • Target section: 用于定义将要执行playbook的远程主机组及远程主机组上的用户,还包括定义通过什么样的方式连接远程主机(默认ssh)
    • Variable section: 定义playbook运行时需要使用的变量
    • Task section: 定义将要在远程主机上执行的任务列表
    • Handler section: 定义task执行完成以后需要调用的任务

    4.1 Target section

    playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。

    Playbook中的远程用户

    playbook中的远程用户和ad-hoc中的使用没有区别,默认不定义,则直接使用ansible.cfg配置中的用户相关的配置。也可在playbook中定义如下:

    - name: /etc/hosts is up to date
      hosts: datacenter
      remote_user: automation
      become: yes
      become_mothod: sudo
      become_user: root
      
      tasks:
        - name: server.example.com in /etc/hosts
          lineinfile:
            path: /etc/hosts
            line: '192.168.0.200 server.exmaple.com server'
            state: present

    Playbook中的hosts

    playbook中的hosts即inentory中的定义主机与主机组,在《Ansible Inventory》中我们讲到了如何选择主机与主机组,在这里也完全适用。

    4.2 Variable section

    定义playbook运行时需要使用的变量

    - name : test vars
      hosts: node2
      remote_user: ansible
      become_user: root
      become_method: sudo
    
      vars:
        user:
          name: "user1"
          address: "IPaddr"
      tasks:
        - name: "print"
          debug:
            msg: "{{ user }}"

    执行

    PLAY [test vars] ******************************************************************************************************************************
    TASK [Gathering Facts] ************************************************************************************************************************
    ok: [node2]
    TASK [print] **********************************************************************************************************************************
    ok: [node2] => {
        "msg": {
            "address": "IPaddr", 
            "name": "user1"
        }
    }
    PLAY RECAP ************************************************************************************************************************************
    node2                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

    4.3 Task section

    play的主体部分是任务列表。

    任务列表中的各任务按次序逐个在hosts中指定的所有主机上执行,在所有主机上完成第一个任务后再开始第二个。在自上而下运行某playbook时,如果中途发生错误,则整个playbook会停止执行,由于playbook的幂等性,playbook可以被反复执行,所以即使发生了错误,在修复错误后,再执行一次即可。

    定义task可以使用action: module optionsmodule: options的格式,推荐使用后者以实现向后兼容。

    tasks:
      - name: make sure apache is running
        service: 
          name: httpd
          state: started
          
      - name: disable selinux
        command: /sbin/setenforce 0

    如果命令或脚本的退出码不为零可以使用如下方式替代:

    tasks:
      - name: run this command and ignore the result
        shell: /usr/bin/somecommand || /bin/true

    可以使用ignore_errors来忽略错误信息:

    tasks:
      - name: run this command and ignore the result
        shell: /usr/bin/somecommand
        ignore_errors: True

    4.4 Handler section

    • 在Ansible Playbook中,handler事实上也是个task,只不过这个task默认并不执行,只有在被触发时才执行。

    • handler通过notify来监视某个或者某几个task,一旦task执行结果发生变化,则触发handler,执行相应操作。

    • handler会在所有的play都执行完毕之后才会执行,这样可以避免当handler监视的多个task执行结果都发生了变化之后而导致handler的重复执行(handler只需要在最后执行一次即可)。

    在notify中定义内容一定要和tasks中定义的 - name 内容一样,这样才能达到触发的效果,否则会不生效。

    - name: configure nginx
      hosts: 192.168.132.133
      tasks:
        - name: install epel-release
          package:
            name: epel-release
            state: present
        - name: install nginx
          package:
            name: nginx
            state: present
          notify: restart nginx
        - name: create directory
          file:
            path: ./file
            state: directory
            owner: nginx
            group: nginx
        - name: copy file from remote serevr
          fetch:
            src: /usr/share/nginx/html/index.html
            dest: file/
        - name: delete file of remote server
          file:
            path: /usr/share/nginx/html/index.html
            state: absent
        - name: create a remote server file
          file:
            path: /usr/share/nginx/html/index.html
            state: touch
            owner: nginx
            group: nginx
        - name: content
          copy:
            content: "<h3>welcome ansible</h3>"
            dest: /usr/share/nginx/html/index.html
        - name: start service
          systemd:
            name: nginx
            state: started
            enabled: yes
            daemon_reload: yes
      handlers:
        - name: restart nginx
          systemd:
            name: nginx
            daemon_reload: yes
            state: restarted

    执行

    PLAY [configure nginx] ************************************************************************************************************************
    TASK [Gathering Facts] ************************************************************************************************************************
    ok: [192.168.132.133]
    TASK [install epel-release] *******************************************************************************************************************
    ok: [192.168.132.133]
    TASK [install nginx] **************************************************************************************************************************
    ok: [192.168.132.133]
    TASK [create directory] ***********************************************************************************************************************
    ok: [192.168.132.133]
    TASK [copy file from remote serevr] ***********************************************************************************************************
    ok: [192.168.132.133]
    TASK [delete file of remote server] ***********************************************************************************************************
    changed: [192.168.132.133]
    TASK [create a remote server file] ************************************************************************************************************
    changed: [192.168.132.133]
    TASK [content] ********************************************************************************************************************************
    changed: [192.168.132.133]
    TASK [start service] **************************************************************************************************************************
    ok: [192.168.132.133]
    PLAY RECAP ************************************************************************************************************************************
    192.168.132.133            : ok=9    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

    没有触发,试音并没有change

    - name: configure nginx
      hosts: 192.168.132.133
      tasks:
        - name: install epel-release
          package: 
            name: epel-release 
            state: present
        - name: install nginx
          package: 
            name: nginx 
            state: present
        - name: create directory
          file: 
            path: ./file 
            state: directory 
            owner: nginx 
            group: nginx
        - name: copy file from remote serevr
          fetch: 
            src: /usr/share/nginx/html/index.html 
            dest: file/
        - name: delete file of remote server
          file: 
            path: /usr/share/nginx/html/index.html 
            state: absent
          notify: restart nginx
        - name: create a remote server file
          file: 
            path: /usr/share/nginx/html/index.html  
            state: touch  
            owner: nginx 
            group: nginx
        - name: content
          copy: 
            content: "<h3>welcome ansible</h3>"  
            dest: /usr/share/nginx/html/index.html
        - name: start service
          systemd: 
            name: nginx 
            state: started 
            enabled: yes 
            daemon_reload: yes
      handlers: 
        - name: restart nginx
          systemd: 
            name: nginx
            daemon_reload: yes
            state: restarted  

    执行

    [root@node1 ansible]# ansible-playbook  nginx_config.yml 

    PLAY [configure nginx] ************************************************************************************************************************
    TASK [Gathering Facts] ************************************************************************************************************************
    ok: [192.168.132.133]
    TASK [install epel-release] *******************************************************************************************************************
    ok: [192.168.132.133]
    TASK [install nginx] **************************************************************************************************************************
    ok: [192.168.132.133]
    TASK [create directory] ***********************************************************************************************************************
    ok: [192.168.132.133]
    TASK [copy file from remote serevr] ***********************************************************************************************************
    ok: [192.168.132.133]
    TASK [delete file of remote server] ***********************************************************************************************************
    changed: [192.168.132.133]
    TASK [create a remote server file] ************************************************************************************************************
    changed: [192.168.132.133]
    TASK [content] ********************************************************************************************************************************
    changed: [192.168.132.133]
    TASK [start service] **************************************************************************************************************************
    ok: [192.168.132.133]
    RUNNING HANDLER [restart nginx] ***************************************************************************************************************
    changed: [192.168.132.133]
    PLAY RECAP ************************************************************************************************************************************
    192.168.132.133            : ok=10   changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    触发执行

    一个任务可以触发多个handlers

    notify: 
      - restart nginx
      - restart redis

    默认情况下,在一个play中,只要有task执行失败,则play终止,即使是与handler关联的task在失败的task之前运行成功了,handler也不会被执行。如果希望在这种情况下handler仍然能够执行,则需要使用如下配置:

    - hosts: all
      force_handlers: yes
      tasks:
        - name: a task which always notifies its handler
          command: /bin/true
          notify: restart the database
        - name: a task which fails because the package doesn't exist
          yum:
            name: notapkg
            state: latest
          
      handlers:
        - name: restart the database
          service:
            name: mariadb

    如果与handler关联的task还未执行,在其前的task已经失败,整个play终止,则handler未被触发,也不会执行


    博主声明:本文的内容来源主要来自誉天教育晏威老师,由本人实验完成操作验证,需要的博友请联系誉天教育(http://www.yutianedu.com/),获得官方同意或者晏老师(https://www.cnblogs.com/breezey/)本人同意即可转载,谢谢!

  • 相关阅读:
    在Repeater的FooterTemplate显示某列总计
    对数据库数据操作,工厂方法设计模式(Factory Method)
    网页(aspx)与用户控件(ascx)交互与逻辑处理
    使用反射把用户控件(ASCX)传至网页(ASPX)
    软件研发公司,外观设计模式(Facade)
    看菜谱点餐,迭代设计模式(Iterator)
    There is not enough space on the disk.
    站点某些网页想显示母版页内的用户控件,某些网页不想显示,怎样实现
    C#反射(Reflection)对类的属性get或set值
    MS access 数据定时导入MS SQL Server
  • 原文地址:https://www.cnblogs.com/zyxnhr/p/12804153.html
Copyright © 2011-2022 走看看