• Ansible-基础


    Ansible架构

    • Inventory   主机清单,可以对主机分组
    • ansible-hoc   ansible的命令,适用临时场景
    • ansible-playbook   ansible是一个场景的集合,是YAML语言
    • 被控端: 被管理的主机
    • 连接协议:ansible是用的ssh协议,所以被控端不需要安装额外的agent,这也是

    ansible-galaxy

    连接https://galaxy.ansible.com 下载对应的Role,相当于仓库。从仓库里拉取相关应用

    让我们获取一个nginx的role

    1、安装

    通过Yum安装RPMs适用于 EPEL 6, 7, 以及仍在支持中的Fedora发行版.这里我们直接安装就行。

    sudo yum install ansible

    配置文件

    • /etc/ansible/ansible.cfg   主配置文件,配置ansible工作特性
    • /etc/ansible/hosts   主机清单
    • /etc/ansible/roles/  存放角色目录

    程序

    • /usr/bin/ansible   主程序,临时命令执行工具
    • /usr/bin/ansible-doc  查看配置文档,模块文档
    • /usr/bin/ansible-galaxy  下载上传优秀代码或role模块的官方平台
    • /usr/bin/ansible-playbook  定制自动化任务,编排剧本工具
    • /usr/bin/ansible-pull  远程执行命令工具
    • /usr/bin/ansible-vault  文件加密工具
    • /usr/bin/ansible-console  基于Console界面与用户交互的执行工具

    ansible配置文件详解

    • inventory      = /etc/ansible/hosts   主机列表配置文件
    • library        = /usr/share/my_modules/   库文件存放目录
    • remote_tmp     = ~/.ansible/tmp  临时py命令文件存放在远程主机上的目录
    • local_tmp      = ~/.ansible/tmp  本机的临时命令执行目录
    • forks          = 5    默认并发数
    • sudo_user      = root   默认sudo用户
    • ask_sudo_pass = True  默认sudo用户是否需要密码
    • ask_pass      = True  每次执行ansible命令询问是否需要密码
    • remote_port    = 22   默认ssh端口
    • host_key_checking = False  检查对应主机的host_key,建议取消注释
    • logpath =/var/log/ansible.log 日志文件存放位置

    ansible-doc

    • -a 列出所有模块文档(太多不建议)
    • -l  --list 列出所有模块
    • -s --snippet 显示指定模块的playbook模块

    示例

    • ansible-doc -l   列出所有模块
    • ansible-doc ping   查看ping模块文档
    • ansible-doc -s  ping   查看ping模块帮助用法

    ansible命令用法

    ansible <host-pattern> [-m module_name] [-a args]

    • --version 查看版本
    • -m   指定模块
    • -v  详细过程 -vv -vvv更详细
    • --list-hosts  显示主机列表,可简写--list
    • -k  提示输入ssh连接密码,默认key验证
    • -K 提示输入sudo时候的口令
    • -C --check 检查,但不执行
    • -T 执行超时时间,默认10s
    • -u 指定远程执行的用户
    • -b 代替旧版本的sudo切换

    ansible <host-pattern>的格式

    配置主机列表

    • all 表现所有的主机: ansible all -m ping
    • * 通配符(要加引号):  ansible "*" -m ping  ansible "10.10.3.*" -m ping
    • 或关系: ansible "monserver:ceph*" -m ping
    • 与关系:ansible "monserver:&ceph*" -m ping
    • 非关系(要用‘’号): ansible 'cephserver:!monserver' -m ping

     ansible-galaxy

    连接https://galaxy.ansible.com下载对应的Role,相当于仓库,可以找到自己想要的应用的role。

    下载一个nginx的role

    $ ansible-galaxy install nginxinc.nginx
    - downloading role 'nginx', owned by nginxinc
    - downloading role from https://github.com/nginxinc/ansible-role-nginx/archive/0.11.0.tar.gz

    列出相关的本地的role

    $ ansible-galaxy list
    - nginxinc.nginx, 0.11.0

    删除一个role

    $ ansible-galaxy remove nginxinc.nginx
    - successfully removed nginxinc.nginx

     

    ansible密钥分发

    这里我们需要准备两台主机,我们需要在主机A上生成秘钥

     ssh-keygen -t rsa

    主机清单分组

    普通分组
    [monserver]
    10.10.3.150
    10.10.3.151
    10.10.3.152
    [osdserver]
    10.10.3.153
    10.10.3.154
    10.10.3.155
    嵌套分组
    [cephserver]
    10.10.3.15[0:5]

    测试cephserver 主机组是否可用

    ansible cephserver -m ping -k
    SSH password:
    10.10.3.150 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    10.10.3.152 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    10.10.3.151 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    10.10.3.153 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    10.10.3.154 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    10.10.3.155 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }

    分发密钥

    我们怕密码不同,我们可以把密码配置到主机清单的变量里。

    #方法1
    [cephserver:vars]
    ansible_ssh_user=root
    ansible_ssh_pass=123
    ansible_ssh_port=22
    #方法2
    [osdserver]
    10.10.3.153  ansible_ssh_user=root ansible_ssh_pass=123 ansible_ssh_port=22
    10.10.3.154  ansible_ssh_user=root ansible_ssh_pass=456 ansible_ssh_port=22
    10.10.3.155  ansible_ssh_user=root ansible_ssh_pass=111 ansible_ssh_port=22

    这里我们用方法一,我们使用了authorized_key模块

     ansible cephserver -m  authorized_key -a "user=root key='{{lookup('file','/root/.ssh/id_rsa.pub')}}'"
    10.10.3.150 | CHANGED => {
        "changed": true,
        "comment": null,
        "exclusive": false,
        "follow": false,
        "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuimpsq0vBZHHR9ypSlQjucyliwNQUppIkimDcTYiYg9ttRf0A3foPd01nXiez8TP52csdrEDUnZsy85fugtvRatu9eWi8BWXzVm0/9m7NuCDzyOqeoBHgiPPqdOwX7Djp4D0BRiu4YqhzTTjC+dkMvxJAxVpx6eyJglfPL7fII3iL0b45F812de869rqgP6CFIkNuiZGPtxCa/ngyP/ILCmhLRSOddflE1QKviV6J7+VHPOtvI1iK0TQMI2HZolf9sj7nzzUE0lH8gH4PLh8OF6Yup8QoBvHv6Y+EN3z7ORLEji1Sv2iUClQHgwcd6CWfAgy1NNURCyl92/t8D54f root@ceph-moni-0",
        "key_options": null,
        "keyfile": "/root/.ssh/authorized_keys",
        "manage_dir": true,
        "path": null,
        "state": "present",
        "unique": false,
        "user": "root",
        "validate_certs": true
    }
    10.10.3.152 | CHANGED => {
        "changed": true,
        "comment": null,
        "exclusive": false,
        "follow": false,
        "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuimpsq0vBZHHR9ypSlQjucyliwNQUppIkimDcTYiYg9ttRf0A3foPd01nXiez8TP52csdrEDUnZsy85fugtvRatu9eWi8BWXzVm0/9m7NuCDzyOqeoBHgiPPqdOwX7Djp4D0BRiu4YqhzTTjC+dkMvxJAxVpx6eyJglfPL7fII3iL0b45F812de869rqgP6CFIkNuiZGPtxCa/ngyP/ILCmhLRSOddflE1QKviV6J7+VHPOtvI1iK0TQMI2HZolf9sj7nzzUE0lH8gH4PLh8OF6Yup8QoBvHv6Y+EN3z7ORLEji1Sv2iUClQHgwcd6CWfAgy1NNURCyl92/t8D54f root@ceph-moni-0",
        "key_options": null,
        "keyfile": "/root/.ssh/authorized_keys",
        "manage_dir": true,
        "path": null,
        "state": "present",
        "unique": false,
        "user": "root",
        "validate_certs": true
    }
    ......

    authorized_key

    • - exclusive [default: no]: 是否移除 authorized_keys 文件中其它非指定 key
    • - key: SSH public key(s) 可以是字符串或 url,如:https://github.com/username.keys
    • - key_options [Default: None]: 附加到 key 中的字符串,该字符串会加到 key 的开头
    • - path [Default: (homedir)+/.ssh/authorized_keys]: 指定 authorized_keys 文件存放的位置
    • - state (Choices: present, absent) [Default: present]: present 添加指定 key 到 authorized_keys 文件中;absent 从 authorized_keys 文件中移除指定 key
    • - user: 指定修改远端服务器上哪个用户的 authorized_keys
    • - manage_dir (Choices: yes, no) [Default: yes]: 指定模块是否应该管理 authorized key 文件所在的目录。如果设置为 yes,模块会创建目录,以及设置一个已存在目录的拥有者和权限。如果通过 path 选项,重新指定了一个 authorized key 文件所在目录,那么应该将该选项设置为 no

    2、远程执行命令

    ansible all -m ping
    172.16.138.40 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    172.16.138.41 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }

    我们也可以通过主机组执行命令

    $ ansible webhost -m command -a  "w"
    172.16.138.41 | CHANGED | rc=0 >>
     01:35:17 up 29 days,  3:34,  2 users,  load average: 0.24, 0.33, 0.27
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    172.16.40.86     23:29   41.00s  0.00s  0.00s -bash
    root     pts/1    k8s-master       01:35    0.00s  0.06s  0.00s w
    
    172.16.138.40 | CHANGED | rc=0 >>
     01:35:18 up 29 days,  3:34,  3 users,  load average: 0.98, 0.88, 0.86
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/0    172.16.40.86     23:06    1:08m  0.29s  0.29s -bash
    root     pts/1    172.16.40.86     01:26    6.00s  1.11s  0.00s ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/2c6989e158 -tt 172.16.138.40 /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1553146517.04-153785974352870/AnsiballZ_command.py && sleep 0'
    root     pts/3    k8s-master       01:35    1.00s  0.10s  0.01s w
    • webhost 是指定的主机组
    • -m 是指定模块
    • -a 是执行的命令

    这里还有一个shell模块。同样也支持写一个命令。

    3、管理文件和目录

    ansible 172.16.138.41 -m copy -a "src=/etc/ansible dest=/tmp/ansible_test owner=root group=root mode=755"
    172.16.138.41 | CHANGED => {
        "changed": true,
        "dest": "/tmp/ansible_test/",
        "src": "/etc/ansible"
    }

    我们看一下目标主机下/tmp目录

    [root@node02 tmp]# ls
    ansible_test
    [root@node02 tmp]# ls ansible_test/
    ansible
    [root@node02 tmp]#
    • src 指定源目录
    • dest 指定目标目录

    需要注意的是,如果目标主机没有这个目录会自动创建这个目录,如果拷贝是文件,目标主机指定的名字和源如果不同,并且不是已经存在的目录,相当于copy过去又重命名。但相反,如果目标主机上已经处在的目录,则会直接把文件copy到该目录下。

    Fetch模块

    抓取远程节点上的文件,只能复制远程单个文件,不能复制目录

    $ ansible all -m fetch -a "src=/var/log/messages dest=/root/logs"
    10.10.3.150 | CHANGED => {
        "changed": true,
        "checksum": "1e74d4714c730e75b453868a1a842e05b5e1504a",
        "dest": "/root/logs/10.10.3.150/var/log/messages",
        "md5sum": "32f20a6108ec6a30e5a81435b329c690",
        "remote_checksum": "1e74d4714c730e75b453868a1a842e05b5e1504a",
        "remote_md5sum": null
    }
    .....
    我们用tree查看一下目录
    $ tree
    .
    ├── 10.10.3.150
    │   └── var
    │       └── log
    │           └── messages
    ├── 10.10.3.151
    │   └── var
    │       └── log
    │           └── messages
    ├── 10.10.3.152
    │   └── var
    │       └── log
    │           └── messages
    ├── 10.10.3.153
    │   └── var
    │       └── log
    │           └── messages
    ├── 10.10.3.154
    │   └── var
    │       └── log
    │           └── messages
    └── 10.10.3.155
        └── var
            └── log
                └── messages

    File模块

    创建一个文件夹

    ansible all -m file -a "path=/data state=directory"
    10.10.3.154 | CHANGED => {
        "changed": true,
        "gid": 0,
        "group": "root",
        "mode": "0755",
        "owner": "root",
        "path": "/data",
        "size": 6,
        "state": "directory",
        "uid": 0
    }
    .........

    创建文件

     ansible all -m file -a "path=/data/zzk state=touch"
    10.10.3.150 | CHANGED => {
        "changed": true,
        "dest": "/data/zzk",
        "gid": 0,
        "group": "root",
        "mode": "0644",
        "owner": "root",
        "size": 0,
        "state": "file",
        "uid": 0
    }
    ..........

    删除文件

    ansible all -m file -a "path=/data/zzk state=absent"
    10.10.3.153 | CHANGED => {
        "changed": true,
        "path": "/data/zzk",
        "state": "absent"
    }

    3、脚本管理

    我们先随便写一个脚本

    #!/bin/bash
    date >> /tmp/data.txt

    ansible需要先把脚本copy到对应主机上

    $ ansible 172.16.138.41 -m copy  -a "src=/tmp/1.sh dest=/tmp/test.sh owner=root group=root mode=755"
    172.16.138.41 | CHANGED => {
        "changed": true,
        "checksum": "a0d6b0777539641b9aab412a0297b1273e836bbb",
        "dest": "/tmp/test.sh",
        "gid": 0,
        "group": "root",
        "md5sum": "fc416150a5e218531c550b98e6ea35b6",
        "mode": "0755",
        "owner": "root",
        "size": 36,
        "src": "/root/.ansible/tmp/ansible-tmp-1553151731.05-254487603693246/source",
        "state": "file",
        "uid": 0
    }

    执行远程脚本

    ansible 172.16.138.41 -m shell -a "/tmp/test.sh"
    172.16.138.41 | CHANGED | rc=0 >>

    4、管理任务计划

    ansible 172.16.138.41 -m cron -a "name='test cron' job='touch /tmp/111.txt' weekday=6"
    172.16.138.41 | CHANGED => {
        "changed": true,
        "envs": [],
        "jobs": [
            "test cron"
        ]
    }
    • cron 定时任务模块
    • name 指定定时任务的名字
    • job 指定定时任务的内容
    • weekday 指定是时间计划,也可以使用*****表示

    我们看一下目录主机的定时任务

    $ crontab -l
    #Ansible: test cron
    * * * * 6 touch /tmp/111.txt

    我们看到有个Ansible的表示,下面是定时任务的内容。

    我们可以通过state=absent 来删除定时任务

    $ ansible 172.16.138.41 -m cron -a "name='test cron' state=absent"
    172.16.138.41 | CHANGED => {
        "changed": true,
        "envs": [],
        "jobs": []
    }

    5、Playbook

    playbook就是把一些模块的集合搞到一个文件里。play的主要功能在于将事先归为一组的主机装扮成事先通过ansible中的task定义好的角色,从根本来讲,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中,既可以让他们连通起来按事先编排的机制同唱一台戏。

    核心元素:

    • hosts  执行的主机列表
    • tasks  任务集
    • varniables  内置变量或者自定义变量在playbook中调用
    • templates  模板,可以替换模板中的变量并实现一些简单逻辑文件
    • handlers  和notity结合使用,由特定条件触发的操作,满足条件方可执行,否则不执行。
    • tags  标签  指定某条任务执行,用于选择运行playbook中的部分代码,ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常的长。此时,如果确信没有其他变化, 就可以通过tags跳过这些代码片段。

    例如:

    ---   #表示开始
    - hosts: 172.16.138.41   #指定远程主机
      remote_user: root   #指定远程用户
      tasks:   #任务
        - name: test_playbook   #任务名字
          shell: touch /tmp/playbook.txt   #具体的任务,核心

    执行

    ansible-playbook /etc/ansible/test.yaml
    
    PLAY [172.16.138.41] ******************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************
    ok: [172.16.138.41]
    
    TASK [test_playbook] ******************************************************************************************************************
     [WARNING]: Consider using the file module with state=touch rather than running 'touch'.  If you need to use command because file is
    insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
    
    changed: [172.16.138.41]
    
    PLAY RECAP ****************************************************************************************************************************
    172.16.138.41              : ok=2    changed=1    unreachable=0    failed=0

    在palybook中使用file模块和user模块

    ---
    - host: monserver
      remote_user: root
    
      tasks:
        - name: create new file
          file: name=/data/newfile state=touch
        - name: create net user
          user: name=test1

    这里我们使用-C参数,-C 是测试一下,不执行真正的结果

    ansible-playbook -C test.yaml
    
    PLAY [monserver] ***************************************************************************************
    
    TASK [Gathering Facts] *********************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [create new file] *********************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [create net user] *********************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    PLAY RECAP *********************************************************************************************
    10.10.3.150                : ok=3    changed=1    unreachable=0    failed=0
    10.10.3.151                : ok=3    changed=1    unreachable=0    failed=0
    10.10.3.152                : ok=3    changed=1    unreachable=0    failed=0

    查看playbook执行文件中有哪些主机

    ansible-playbook test.yaml --list-hosts
    
    playbook: test.yaml
    
      play #1 (monserver): monserver    TAGS: []
        pattern: [u'monserver']
        hosts (3):
          10.10.3.152
          10.10.3.150
          10.10.3.151

    查看playbook执行文件中,有哪些任务

    ansible-playbook test.yaml --list-tasks
    
    playbook: test.yaml
    
      play #1 (monserver): monserver    TAGS: []
        tasks:
          create new file    TAGS: []
          create net user    TAGS: []

    在指定主机下执行

    ansible-playbook test.yaml --limit 10.10.3.152
    
    PLAY [monserver] ***************************************************************************************
    
    TASK [Gathering Facts] *********************************************************************************
    ok: [10.10.3.152]
    
    TASK [create new file] *********************************************************************************
    changed: [10.10.3.152]
    
    TASK [create net user] *********************************************************************************
    changed: [10.10.3.152]
    
    PLAY RECAP *********************************************************************************************
    10.10.3.152                : ok=3    changed=2    unreachable=0    failed=0

    6、Playbook变量

    变量的来源:

    • ansible setup facts 来和获取系统变量,举例:ansible monserver  -m  setup  过滤:ansible monserver  -m  setup  -a "filter=ansible_hostname"
    • 在/etc/ansible/hosts中定义
    1. 普通变量:主机组中主机单独定义,优先级高于公共变量
    2. 公共(组)变量:针对主机组中所有主机定义统一变量
    • 通过命令行指定变量,优先级最高。 ansible-playbook -e varname=value
    • 在playbook中定义
    • 在role中定义

    我们创建一个用户。通过变量传过去

    ---
    - name: create_user
      hosts: 172.16.138.41
      remote_user: root
      gather_facts: false
      vars:
        - user: "zzkk"
      tasks:
        - name: create-user
          user: name="{{ user }}"

    执行:

    ansible-playbook /etc/ansible/user.yaml
    
    PLAY [create_user] ********************************************************************************************************************
    
    TASK [create-user] ********************************************************************************************************************
    changed: [172.16.138.41]
    
    PLAY RECAP ****************************************************************************************************************************
    172.16.138.41              : ok=1    changed=1    unreachable=0    failed=0

    测试

    ---
    - hosts: monserver
      remote_user: root
    
      tasks:
        - name: install httpd package
          yum: name={{ pkname }}
        - name: start service
          service: name={{ pkname }} state=started enabled=yes

    执行

    ansible-playbook -e 'pkname=vsftpd' app.yaml
    
    PLAY [monserver] ***************************************************************************************
    
    TASK [Gathering Facts] *********************************************************************************
    ok: [10.10.3.152]
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    
    TASK [install httpd package] ***************************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    
    TASK [start service] ***********************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    PLAY RECAP *********************************************************************************************
    10.10.3.150                : ok=3    changed=2    unreachable=0    failed=0
    10.10.3.151                : ok=3    changed=2    unreachable=0    failed=0
    10.10.3.152                : ok=3    changed=2    unreachable=0    failed=0

     palybook中定义变量

    ---
    - hosts: monserver
      remote_user: root
      vars:
        - pkname: vsftpd
    
      tasks:
        - name: install httpd package
          yum: name={{ pkname }}
        - name: start service
          service: name={{ pkname }} state=started enabled=yes

    执行

    $ ansible-playbook app.yaml
    
    PLAY [monserver] **************************************************************************************************
    
    TASK [Gathering Facts] ********************************************************************************************
    ok: [10.10.3.152]
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    
    TASK [install httpd package] **************************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    TASK [start service] **********************************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    PLAY RECAP ********************************************************************************************************
    10.10.3.150                : ok=3    changed=2    unreachable=0    failed=0
    10.10.3.151                : ok=3    changed=2    unreachable=0    failed=0
    10.10.3.152                : ok=3    changed=2    unreachable=0    failed=0

    主机清单中定义变量

    普遍变量,就是定义单个主机的变量

    [monserver]
    10.10.3.150 http_port=81
    10.10.3.151 http_port=80
    10.10.3.152 http_port=82
    ---
    - hosts: monserver
      remote_user: root
    
      tasks:
        - name: hostname
          hostname: name=user{{ http_port }}

    执行

    ansible-playbook -C host.yaml
    
    PLAY [monserver] **************************************************************************************************
    
    TASK [Gathering Facts] ********************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [hostname] ***************************************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    changed: [10.10.3.152]
    
    PLAY RECAP ********************************************************************************************************
    10.10.3.150                : ok=2    changed=1    unreachable=0    failed=0
    10.10.3.151                : ok=2    changed=1    unreachable=0    failed=0
    10.10.3.152                : ok=2    changed=1    unreachable=0    failed=0

    公共变量

    [cephserver:vars]
    ansible_ssh_user=root
    ansible_ssh_pass=123
    ansible_ssh_port=22

    7、playbook循环

    创建三个文件,并修复其权限为600

    ---
    - hosts: 172.16.138.41
      user: root
      task:
        - name: "touch 1 2 3 file and change file mode"
          file: path=/tmp/{{ item }} state=touch mode=600
          with_items:
            - 1.txt
            - 2.txt
            - 3.txt

    执行:

    ansible-playbook /etc/ansible/while.yaml
    
    PLAY [172.16.138.41] ******************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************
    ok: [172.16.138.41]
    
    TASK [touch 1 2 3 file and change file mode] ******************************************************************************************
    changed: [172.16.138.41] => (item=1.txt)
    changed: [172.16.138.41] => (item=2.txt)
    changed: [172.16.138.41] => (item=3.txt)
    
    PLAY RECAP ****************************************************************************************************************************
    172.16.138.41              : ok=2    changed=1    unreachable=0    failed=0

    8、playbook 条件判断

    我们查看一下gather_facts收集到的信息,来作为我们判断的条件,这里我们要获取IP地址。

    ansible 172.16.138.41 -m setup
    ....
    "ansible_ens160": {
                "active": true,
                "device": "ens160",
    .... 
     "ipv4": {
                    "address": "172.16.138.41",
                    "broadcast": "172.16.138.255",
                    "netmask": "255.255.255.0",
                    "network": "172.16.138.0"
                },
    ....

    我们写一个判断条件 当ansible_ens160.ipv4.address = 172.16.138.41 执行创建文件

    ---
    - hosts: webhost
      user: root
      gather_facts: True
      tasks:
        - name: stady when
          shell: touch /tmp/when.txt
          when: ansible_ens160.ipv4.address == "172.16.138.41"

    执行结果:

    ansible-playbook /etc/ansible/when.yaml
    
    PLAY [webhost] ************************************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************************
    ok: [172.16.138.41]
    ok: [172.16.138.40]
    
    TASK [stady when] *********************************************************************************************************************
    skipping: [172.16.138.40]
     [WARNING]: Consider using the file module with state=touch rather than running 'touch'.  If you need to use command because file is
    insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
    
    changed: [172.16.138.41]
    
    PLAY RECAP ****************************************************************************************************************************
    172.16.138.40              : ok=1    changed=0    unreachable=0    failed=0
    172.16.138.41              : ok=2    changed=1    unreachable=0    failed=0

    这里我们看到跳过172.16.138.40,172.16.138.41中执行。

    8、playbook Handlers

    module 具有”幂等”性,所以当远端系统被人改动时,可以重放 playbooks 达到恢复的目的. playbooks 本身可以识别这种改动,并且有一个基本的 event system(事件系统),可以响应这种改动.

    (当发生改动时)’notify’ actions 会在 playbook 的每一个 task 结束时被触发,而且即使有多个不同的 task 通知改动的发生, ‘notify’ actions 只会被触发一次.

    举例来说,比如多个 resources 指出因为一个配置文件被改动,所以 apache 需要重新启动,但是重新启动的操作只会被执行一次.

    样例:

    安装http服务,并将配置文件copy到远程服务里

    ---
    - hosts: monserver
      remote_user: root

      tasks:
        - name: install httpd package
          yum: name=httpd
        - name: copy conf file
          copy: src=files/httpd.conf dest=/etc/httpd/ backup=yes
        - name: start service
          service: name=httpd state=started enabled=yes

    执行:

    $ ansible-playbook httpd.yaml

    PLAY [monserver] ***************************************************************************************

    TASK [Gathering Facts] *********************************************************************************
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    ok: [10.10.3.150]

    TASK [install httpd package] ***************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]

    TASK [start service] ***********************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]

    PLAY RECAP *********************************************************************************************
    10.10.3.150                : ok=3    changed=2    unreachable=0    failed=0
    10.10.3.151                : ok=3    changed=2    unreachable=0    failed=0
    10.10.3.152                : ok=3    changed=2    unreachable=0    failed=0

    确认是否安装成功

    ansible monserver -m shell -a "ss -ntlp | grep :80"
    10.10.3.152 | CHANGED | rc=0 >>
    LISTEN     0      128         :::80                      :::*                   users:(("httpd",pid=7626,fd=4),("httpd",pid=7625,fd=4),("httpd",pid=7624,fd=4),("httpd",pid=7623,fd=4),("httpd",pid=7622,fd=4),("httpd",pid=7621,fd=4))
    
    10.10.3.151 | CHANGED | rc=0 >>
    LISTEN     0      128         :::80                      :::*                   users:(("httpd",pid=20020,fd=4),("httpd",pid=20019,fd=4),("httpd",pid=20018,fd=4),("httpd",pid=20017,fd=4),("httpd",pid=20016,fd=4),("httpd",pid=20015,fd=4))
    
    10.10.3.150 | CHANGED | rc=0 >>
    LISTEN     0      128         :::80                      :::*                   users:(("httpd",pid=3437,fd=4),("httpd",pid=3436,fd=4),("httpd",pid=3435,fd=4),("httpd",pid=3434,fd=4),("httpd",pid=3433,fd=4),("httpd",pid=3432,fd=4))

    这里我们将配置文件的http端口改成81

    .....
    # directive.
    #
    # Change this to Listen on specific IP addresses as shown below to
    # prevent Apache from glomming onto all bound IP addresses.
    #
    #Listen 12.34.56.78:80
    Listen 81
    
    .....

    让我们重新执行palybook,看看会发生什么

    $ ansible-playbook httpd.yaml
    
    PLAY [monserver] ***************************************************************************************
    
    TASK [Gathering Facts] *********************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [install httpd package] ***************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [copy conf file] **********************************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    
    TASK [start service] ***********************************************************************************
    ok: [10.10.3.152]
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    
    PLAY RECAP *********************************************************************************************
    10.10.3.150                : ok=4    changed=1    unreachable=0    failed=0
    10.10.3.151                : ok=4    changed=1    unreachable=0    failed=0
    10.10.3.152                : ok=4    changed=1    unreachable=0    failed=0

    其实这里我们发现,任务只执行了“copy conf file”这个task,我们再坚持一下远程端口看看有没有启动81

    $ ansible monserver -m shell -a "ss -ntlp | grep :81"
    10.10.3.150 | FAILED | rc=1 >>
    non-zero return code
    
    10.10.3.152 | FAILED | rc=1 >>
    non-zero return code
    
    10.10.3.151 | FAILED | rc=1 >>
    non-zero return code

    我们可以看到这里报错, 没有返回对应的端口,说明就没有启动81端口,我们需要的发现配置文件发送变化,就自动重启。这里我们使用handler来实现

    ---
    - hosts: monserver
      remote_user: root
    
      tasks:
        - name: install httpd package
          yum: name=httpd
        - name: copy conf file
          copy: src=files/httpd.conf dest=/etc/httpd/ backup=yes
          notify: restart service
        - name: start service
          service: name=httpd state=started enabled=yes
    
      handlers:
        - name: restart service
          service: name=httpd state=restarted

    执行验证:

    $ ansible-playbook httpd.yaml
    
    PLAY [monserver] ***************************************************************************************
    
    TASK [Gathering Facts] *********************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    
    ▽
    ok: [10.10.3.152]
    
    TASK [install httpd package] ***************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [copy conf file] **********************************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    
    TASK [start service] ***********************************************************************************
    ok: [10.10.3.152]
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    
    RUNNING HANDLER [restart service] **********************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    
    PLAY RECAP *********************************************************************************************
    10.10.3.150                : ok=5    changed=2    unreachable=0    failed=0
    10.10.3.151                : ok=5    changed=2    unreachable=0    failed=0
    10.10.3.152                : ok=5    changed=2    unreachable=0    failed=0

    $ ansible monserver -m shell -a "ss -ntlp | grep :81"
    10.10.3.150 | CHANGED | rc=0 >>
    LISTEN     0      128         :::81                      :::*                   users:(("httpd",pid=6255,fd=4),("httpd",pid=6254,fd=4),("httpd",pid=6253,fd=4),("httpd",pid=6252,fd=4),("httpd",pid=6251,fd=4),("httpd",pid=6250,fd=4))

    10.10.3.151 | CHANGED | rc=0 >>
    LISTEN     0      128         :::81                      :::*                   users:(("httpd",pid=21469,fd=4),("httpd",pid=21468,fd=4),("httpd",pid=21467,fd=4),("httpd",pid=21466,fd=4),("httpd",pid=21465,fd=4),("httpd",pid=21464,fd=4))

    10.10.3.152 | CHANGED | rc=0 >>
    LISTEN     0      128         :::81                      :::*                   users:(("httpd",pid=9087,fd=4),("httpd",pid=9086,fd=4),("httpd",pid=9085,fd=4),("httpd",pid=9084,fd=4),("httpd",pid=9083,fd=4),("httpd",pid=9082,fd=4))

     9、template模板

    • 文本文件
    • Jinjia2语言,有下面形式:
    1. 字符串:使用单引号或者双引号
    2. 数字:整数,浮点数
    3. 列表:[item1,item2....]
    4. 元组:(item1,item2...)
    5. 字典:{key1:value1,key2:value2....}
    6. 布尔型:true/false
    • 算术运算:“+”,“-”,“*”,“/”,“//”,“%”,“**”
    • 比较操作:==,!=,>,>=,<,<=
    • 逻辑运算:and,or,not
    • 流表达式:For If When

    简单使用方法:

    在当前目录下创建templates目录,下负责nginx的配置文件

    创建一个playbook

    ---
    - hosts: monserver
      remote_user: root
    
      tasks:
        - name: install nginx
          yum: name=nginx
        - name: copy template
          template: src=templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
        - name: start nginx
          service: name=nginx state=started enabled=yes

    执行:

    ansible-playbook  temp.yaml
    
    PLAY [monserver] **************************************************************************************************
    
    TASK [Gathering Facts] ********************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    ok: [10.10.3.152]
    
    TASK [install nginx] **********************************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    TASK [copy template] **********************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [start nginx] ************************************************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    changed: [10.10.3.150]
    
    PLAY RECAP ********************************************************************************************************
    10.10.3.150                : ok=4    changed=2    unreachable=0    failed=0
    10.10.3.151                : ok=4    changed=2    unreachable=0    failed=0
    10.10.3.152                : ok=4    changed=2    unreachable=0    failed=0

    我们使用系统变量修改nginx work进程数:

    获取变量的方法,我们可以使用 ansible monserver -m setup | grep "processor" 获取CPU个数

    修改nginx模板文件

    $ vim templates/nginx.conf.j2
    # For more information on configuration, see:
    #   * Official English Documentation: http://nginx.org/en/docs/
    #   * Official Russian Documentation: http://nginx.org/ru/docs/
    
    user nginx;
    worker_processes {{ ansible_processor_vcpus**2 }};
    error_log /var/log/nginx/error.log;
    .....

    修改playbook使用handlers

    ---
    - hosts: monserver
      remote_user: root
    
      tasks:
        - name: install nginx
          yum: name=nginx
        - name: copy template
          template: src=templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
          notify: restart nginx
        - name: start nginx
          service: name=nginx state=started enabled=yes
    
      handlers:
        - name: restart nginx
          service: name=nginx state=restarted

    执行:

    ansible-playbook temp.yaml
    
    PLAY [monserver] **************************************************************************************************
    
    TASK [Gathering Facts] ********************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    ok: [10.10.3.152]
    
    ▽
    
    TASK [install nginx] **********************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    ok: [10.10.3.152]
    
    TASK [copy template] **********************************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    TASK [start nginx] ************************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    RUNNING HANDLER [restart nginx] ***********************************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    PLAY RECAP ********************************************************************************************************
    10.10.3.150                : ok=5    changed=2    unreachable=0    failed=0
    10.10.3.151                : ok=5    changed=2    unreachable=0    failed=0
    10.10.3.152                : ok=5    changed=2    unreachable=0    failed=0

    验证:

    $ ansible monserver -m shell -a "ps -ef  | grep nginx "
    10.10.3.151 | CHANGED | rc=0 >>
    root     24713     1  0 14:40 ?        00:00:00 nginx: master process /usr/sbin/nginx
    nginx    24714 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24715 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24716 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24717 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24718 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24719 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24720 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24721 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24722 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24723 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24724 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24725 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24726 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24727 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24728 24713  0 14:40 ?        00:00:00 nginx: worker process
    nginx    24729 24713  0 14:40 ?        00:00:00 nginx: worker process
    root     24850 24849  0 14:41 pts/0    00:00:00 /bin/sh -c ps -ef | grep nginx
    root     24852 24850  0 14:41 pts/0    00:00:00 grep nginx
    
    ....

    同样也可以引用主机清单、playbook等里面的变量。

    when用法

    when 既中文含义是“当”,当怎么怎么就怎么怎么

    当hostname=ceph-osd-1的时候安装服务

    ---
    - hosts: cephserver
      remote_user: root
      tasks:
        - name: install nginx
          when: ansible_hostname == "ceph-osd-1"
          yum: name=nginx
        - name: copy template
          when: ansible_hostname == "ceph-osd-1"
          template: src=templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
          notify: restart nginx
        - name: start nginx
          when: ansible_hostname == "ceph-osd-1"
          service: name=nginx state=started enabled=yes
      handlers:
        - name: restart nginx
          service: name=nginx state=restarted

    迭代机制, with_items

    ---
    - hosts: monserver
      remote_user: root
    
      tasks:
        - name: create some file
          file: name=/data/{{ item }} state=touch
          with_items:
            - file1
            - file2
            - file3
        - name: install spme packages
          yum: name= {{ item }}
          with_items:
            - htop
            - sl
            - hping3

    执行:

    ansible-playbook -C testitem.yaml
    
    PLAY [monserver] **********************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    ok: [10.10.3.152]
    
    TASK [create some file] ***************************************************************************************************
    ok: [10.10.3.150] => (item=file1)
    ok: [10.10.3.152] => (item=file1)
    ok: [10.10.3.151] => (item=file1)
    ok: [10.10.3.150] => (item=file2)
    ok: [10.10.3.152] => (item=file2)
    ok: [10.10.3.151] => (item=file2)
    ok: [10.10.3.150] => (item=file3)
    ok: [10.10.3.152] => (item=file3)
    ok: [10.10.3.151] => (item=file3)
    
    TASK [install spme packages] **********************************************************************************************
    ok: [10.10.3.152] => (item=htop)
    ok: [10.10.3.150] => (item=htop)
    ok: [10.10.3.151] => (item=htop)
    ok: [10.10.3.152] => (item=sl)
    ok: [10.10.3.150] => (item=sl)
    ok: [10.10.3.151] => (item=sl)
    ok: [10.10.3.152] => (item=hping3)
    ok: [10.10.3.150] => (item=hping3)
    ok: [10.10.3.151] => (item=hping3)
    
    PLAY RECAP ****************************************************************************************************************
    10.10.3.150                : ok=3    changed=0    unreachable=0    failed=0
    10.10.3.151                : ok=3    changed=0    unreachable=0    failed=0
    10.10.3.152                : ok=3    changed=0    unreachable=0    failed=0
    
    [root@ceph-moni-0 ansible]# ansible-playbook testitem.yaml
    
    PLAY [monserver] **********************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [create some file] ***************************************************************************************************
    changed: [10.10.3.152] => (item=file1)
    changed: [10.10.3.151] => (item=file1)
    
    ▽
    changed: [10.10.3.150] => (item=file1)
    changed: [10.10.3.150] => (item=file2)
    changed: [10.10.3.152] => (item=file2)
    changed: [10.10.3.151] => (item=file2)
    changed: [10.10.3.150] => (item=file3)
    changed: [10.10.3.152] => (item=file3)
    changed: [10.10.3.151] => (item=file3)
    
    TASK [install spme packages] **********************************************************************************************
    ok: [10.10.3.152] => (item=htop)
    ok: [10.10.3.151] => (item=htop)
    ok: [10.10.3.150] => (item=htop)
    ok: [10.10.3.151] => (item=sl)
    ok: [10.10.3.152] => (item=sl)
    ok: [10.10.3.150] => (item=sl)
    ok: [10.10.3.151] => (item=hping3)
    ok: [10.10.3.152] => (item=hping3)
    ok: [10.10.3.150] => (item=hping3)
    
    PLAY RECAP ****************************************************************************************************************
    10.10.3.150                : ok=3    changed=1    unreachable=0    failed=0
    10.10.3.151                : ok=3    changed=1    unreachable=0    failed=0
    10.10.3.152                : ok=3    changed=1    unreachable=0    failed=0

    验证:

    ansible  monserver  -m shell -a "ls /data"
    10.10.3.150 | CHANGED | rc=0 >>
    file1
    file2
    file3
    
    10.10.3.152 | CHANGED | rc=0 >>
    file1
    file2
    file3
    newfile
    
    10.10.3.151 | CHANGED | rc=0 >>
    file1
    file2
    file3

    迭代嵌套子变量,使用字典

    ---
    - hosts: monserver
      remote_user: root
    
      tasks:
        - name: create some group
          group: name={{ item }}
          with_items:
            - g1
            - g2
            - g3
        - name: create some users
          user: name={{ item.name }} group={{ item.group }}
          with_items:
            - {name: 'user1',group: 'g1'}
            - {name: 'user2',group: 'g2'}
            - {name: 'user3',group: 'g3'}

    执行:

    $ ansible-playbook testitem2.yaml
    
    PLAY [monserver] **********************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************
    ok: [10.10.3.152]
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    
    TASK [create some group] **************************************************************************************************
    
    ▽
    changed: [10.10.3.150] => (item=g1)
    changed: [10.10.3.152] => (item=g1)
    changed: [10.10.3.151] => (item=g1)
    changed: [10.10.3.152] => (item=g2)
    changed: [10.10.3.150] => (item=g2)
    changed: [10.10.3.151] => (item=g2)
    changed: [10.10.3.152] => (item=g3)
    changed: [10.10.3.150] => (item=g3)
    changed: [10.10.3.151] => (item=g3)
    
    TASK [create some users] **************************************************************************************************
    changed: [10.10.3.152] => (item={u'group': u'g1', u'name': u'user1'})
    changed: [10.10.3.151] => (item={u'group': u'g1', u'name': u'user1'})
    changed: [10.10.3.150] => (item={u'group': u'g1', u'name': u'user1'})
    changed: [10.10.3.152] => (item={u'group': u'g2', u'name': u'user2'})
    changed: [10.10.3.150] => (item={u'group': u'g2', u'name': u'user2'})
    changed: [10.10.3.151] => (item={u'group': u'g2', u'name': u'user2'})
    changed: [10.10.3.152] => (item={u'group': u'g3', u'name': u'user3'})
    changed: [10.10.3.150] => (item={u'group': u'g3', u'name': u'user3'})
    changed: [10.10.3.151] => (item={u'group': u'g3', u'name': u'user3'})
    
    PLAY RECAP ****************************************************************************************************************
    10.10.3.150                : ok=3    changed=2    unreachable=0    failed=0
    10.10.3.151                : ok=3    changed=2    unreachable=0    failed=0
    10.10.3.152                : ok=3    changed=2    unreachable=0    failed=0

    for 循环在template模板中:

    我们创建一个变量字段

    ---
    - hosts: monserver
      remote_user: root
      vars:
        ports:
          - web1:
            name: webhs1
            port: 81
            rootdir: /data/web1
          - web2:
            name: webhs2
            port: 82
            rootdir: /data/web2
          - web3:
            name: webhs3
            port: 83
            rootdir: /data/web3
      tasks:
        - name: copy conf
          template: src=for3.conf.j2 dest=/data/for1.conf

    创建template模板配置文件

    {% for p in ports %}
    server{
       listen {{ p.port }}
       servername {{ p.name }}
       documentroot: {{ p.rootdir }}
    }
    {% endfor %}

    执行:

    ansible-playbook  for.yaml
    
    PLAY [monserver] **********************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************
    ok: [10.10.3.152]
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    
    TASK [copy conf] **********************************************************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    changed: [10.10.3.150]
    
    PLAY RECAP ****************************************************************************************************************
    10.10.3.150                : ok=2    changed=1    unreachable=0    failed=0
    10.10.3.151                : ok=2    changed=1    unreachable=0    failed=0
    10.10.3.152                : ok=2    changed=1    unreachable=0    failed=0

    循环嵌套if判断

    需求是,如果name有定义就添加这个配置,如果没有就不添加,这里我们在前面定义的变量里注释两个name

    ---
    - hosts: monserver
      remote_user: root
      vars:
        ports:
          - web1:
      #      name: webhs1
            port: 81
            rootdir: /data/web1
          - web2:
      #      name: webhs2
            port: 82
            rootdir: /data/web2
          - web3:
            name: webhs3
            port: 83
            rootdir: /data/web3
      tasks:
        - name: copy conf
          template: src=for1.conf.j2 dest=/data/for3.conf

    在template中增加判断

    {% for p in ports %}
    server{
       listen {{ p.port }}
    {% if p.name is defined %}
       servername {{ p.name }}
    {% endif %}
       documentroot: {{ p.rootdir }}
    }
    {% endfor %}

    执行:

    ansible-playbook  for1.yaml
    
    PLAY [monserver] **********************************************************************************************************
    
    TASK [Gathering Facts] ****************************************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [copy conf] **********************************************************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    changed: [10.10.3.150]
    
    PLAY RECAP ****************************************************************************************************************
    10.10.3.150                : ok=2    changed=1    unreachable=0    failed=0
    10.10.3.151                : ok=2    changed=1    unreachable=0    failed=0
    10.10.3.152                : ok=2    changed=1    unreachable=0    failed=0

    查看结果:

    ansible monserver -m shell -a "cat /data/for3.conf  "
    10.10.3.150 | CHANGED | rc=0 >>
    server{
       listen 81
       documentroot: /data/web1
    }
    server{
       listen 82
       documentroot: /data/web2
    }
    server{
       listen 83
       servername webhs3
       documentroot: /data/web3
    }
    .......

    Role

    用于层次性,结构化地组织playbook,roles能够根据层次型结构自动装载变量文件,tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单讲,roles就是通过将变量、文件、任务、模板及处理器放置于单独的目录里。并可以便捷的include他们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

    Role各目录作用:

    • files/ 存放由copy和script模块等调用文件
    • templates/ template模块查找所需要的模板目录
    • tasks/ 定义task,role的基本元素,至少应该包含一个名为main.yaml的文件,其他文件需要在此文件中通过include进行包含
    • handlers/ 至少包含一个名为main.yaml的文件,其他文件需要在此文件中通过include进行包含
    • vars/ 至少包含一个名为main.yaml的文件,其他文件需要在此文件中通过include进行包含
    • mete/ 定义当前角色的特殊设定及其依赖关系,至少包含一个名为main.yaml的文件,其他文件需要在此文件中通过include进行包含
    • default/ 设定默认变量时使用此目录中的main.yaml文件

    需求:

    通过role安装nginx,安装nginx的步骤:

    1. 创建nginx用户组,group:nginx
    2. 创建nginx用户,user:nginx
    3. yum安装nginx  yum:nginx
    4. 拷贝模板:template:nginx.conf.j2
    5. 启动服务,service:nginx

    我们根据需求和上面的解释,场景对应的目录:

    mkdir -p testroles/roles/nginx/{tasks,templates}

    上面的1、2、3是tasks任务,所以我们会再tasks目录下一一创建

    $ vim group.yaml
    - name: create group
      group: name=nginx
    $ vim user.yaml
    - name: create user
      user: name=nginx group=nginx system=yes shell=/sbin/nologin
    $ vim yum.yaml
    - name: install package
      yum: name=nginx
    $ vim start.yaml 
    - name: start nginx
      service: name=nginx state=started
    $ vim restart.yaml 
    - name: restart nginx
      service: name=nginx state=restarted
    $ vim temp.yaml
    - name: copy config
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

    创建配置文件模板

    $ vim ../templates/nginx.conf.j2
    
     For more information on configuration, see:
    #   * Official English Documentation: http://nginx.org/en/docs/
    #   * Official Russian Documentation: http://nginx.org/ru/docs/
    
    user nginx;
    worker_processes {{ ansible_processor_vcpus**2 }};
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    ........

    这里我们的配置文件准备完成了。接下来是关键是怎么调用,这时候我们需要一个总的tasks文件(main.yaml)。

    $ vim roles/nginx/tasks/main.yaml
    - include: group.yaml
    - include: user.yaml
    - include: yum.yaml
    - include: temp.yaml
    - include: start.yaml

    这里我们在role目录平级的目录创建一个剧本,写具体怎么调用:

    $ vim nginx-role.yaml
    
    - hosts: monserver
      remote_user: root
      roles:
        - role: nginx

    执行:

    ansible-playbook -C  nginx-role.yaml
    
    PLAY [monserver] *******************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.152]
    ok: [10.10.3.151]
    
    TASK [nginx : create group] ********************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    changed: [10.10.3.150]
    
    TASK [nginx : create user] *********************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    TASK [nginx : install package] *****************************************************************
    changed: [10.10.3.151]
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    
    TASK [nginx : copy config] *********************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    changed: [10.10.3.150]
    
    TASK [nginx : start nginx] *********************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    changed: [10.10.3.150]
    
    PLAY RECAP *************************************************************************************
    10.10.3.150                : ok=6    changed=5    unreachable=0    failed=0
    10.10.3.151                : ok=6    changed=5    unreachable=0    failed=0
    10.10.3.152                : ok=6    changed=5    unreachable=0    failed=0
    
    [root@ceph-moni-0 testroles]# ansible-playbook  nginx-role.yaml
    
    PLAY [monserver] *******************************************************************************
    
    TASK [Gathering Facts] *************************************************************************
    ok: [10.10.3.150]
    ok: [10.10.3.151]
    ok: [10.10.3.152]
    
    TASK [nginx : create group] ********************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    
    TASK [nginx : create user] *********************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    
    TASK [nginx : install package] *****************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    
    TASK [nginx : copy config] *********************************************************************
    changed: [10.10.3.150]
    changed: [10.10.3.152]
    changed: [10.10.3.151]
    
    TASK [nginx : start nginx] *********************************************************************
    changed: [10.10.3.152]
    changed: [10.10.3.150]
    changed: [10.10.3.151]
    
    PLAY RECAP *************************************************************************************
    10.10.3.150                : ok=6    changed=5    unreachable=0    failed=0
    10.10.3.151                : ok=6    changed=5    unreachable=0    failed=0
    10.10.3.152                : ok=6    changed=5    unreachable=0    failed=0
  • 相关阅读:
    BigDecimal加减乘除计算方式
    Element-UI 关于table中fixed使用和table样式混乱问题处理
    java集合框架中contains(),containsKey()和containsValue()的用法
    Vue中子组件watch监听props中父组件对象的变化的坑
    js中使用splice在一次循环删除数组中的多个元素
    Java中instanceof关键字的理解
    List.contains(Object object)方法,比较对象是否相同
    Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制
    sql中#与$的区别
    Vue自定义指令实现按钮级权限控制功能
  • 原文地址:https://www.cnblogs.com/xzkzzz/p/10573651.html
Copyright © 2020-2023  润新知