ansible

ansible介绍及使用
作者:程高翔
邮箱:1805361954@qq.com
有什么建议和意见请至信邮箱
本人赋闲在家

一.Ansible 概述

  • Ansible是最近非常火的一款开源运维自动化工具,通过Ansible可以实现运维自动化,提高运维工程师的工作效率,减少人为失误,Ansible可以通过本身集成的非常丰富的模块实现各种管理任务,其自带模块数量已经超过千个,更重要的是,它的操作非常简单,即使新手比较容易上手,Ansible提供的功能非常丰富,在运维领域几乎可以实现任何事情.目前属于RedHat公司产品,官网地址:
    httpd://www.ansible.com

    在此之外还有许多类似产品如 SHhell perl , expect puppet ansible ,saltstack等

二.Ansible 特点

Ansible自2012年发布以来,很快在全球流行,其特点表现如下
1.Ansible基于python开发,运维工程师对其二次开发相对较为容易
2.Ansible拥有丰富的内置模块,基本可以满足一切要求.
3.管理模式非常简单,一条命令可以影响上千台机器;
4.无客户端模式设计,底层基于ssh通信.
5.Ansible发布后也陆续被: AWS , Google Cloud Platfrom , Microsoft Azure , Cisco , HP , VMware , Twiter等大公司接纳并投入使用.

三.Ansible 应用

Ansible没有客户端,也不需要在被管理主机添加任何代理程序,通过ssh完成底层通信,而ssh在linux的发行版本中默认已经安装并启用,而在windows系统下则依赖于PowerShell Ansible 要求管理端必须是linux系统,在管理节点通过应用模块将指令发送到被管理主机上,并在执行完毕后自动删除产生的临时文件,根据Ansible使用过程中不同角色,可将其分为三个部分
    (1).使用者如何使用Ansible实现自动化运维?
    (2).Ansible的工具集,Ansible可以实现的功能?
    (3).作用对象,Ansible可以影响那些主机

1.使用者:

  • Ansible使用者可以采用多种方式和Ansible交互,

    (1)CMDB:CMDB系统存储和管理着企业IT架构中各种配置信息,是构建ITL项目核心工具,运维人员可以组合CMDB和Ansible,通过CMDB直接下发指令调用Ansible工具完成操作者所希望达到的目标.
    (2)PUBLIC/PRIVATE方式,Ansible除了丰富的内置模块外.同时提供丰富的API语言接口,如PHP,python,PERL等多种语言,基于PUBLIC/PRIVATE,Ansible以API调用的方式运行
    (3)Ad-Hoc命令集,Users直接通过Ad-Hoc命令集调用Ansible工具来完成工作
    (4)playbools:Users预先编写号Ansible Playbooks通过执行Playbooks中预先编排好的任务集按序执行命令

            PUBLIC / PRIVATE CLOUD          CMDB
                _______↓______________________↓_
                |  INVENTORY                    |
                |  API                          |--→HOSTS
        users--→|  MODULES                      |
          |     |  PLUGINS                      |--→NETWORKING
          ↓     |_______________________________|
        Ansible playbook---↑
    

    2.Ansible工具集合
    Ansible工具集合了inventory,moudles,plugins和API,其中,lnventory用来管理设备列表,可以通过分组(不同业务)实现,对组的调用直接影响组内所有主机;Moudles是给中执行模块,几乎所有管理都是通过模块来执行的;PLugins提供了各种附加功能;API为编成人员提供一个调用接口,可以做Ansible的二次开发具体表现如下
    (1)Ansible Playbook :任务脚本(俗称剧本),编排定义Ansible任务集的配置文件,由Ansible按序以此执行,通常是JSON格式的YML/YAML文件
    (2)inventory : Ansible管理主机清单;
    (3)Moudle: Ansible执行命令功能模块,多数为内置的核心模块也可以用户自定义;
    (4)Plugins:模块功能的补充,如果连续类型插件,循环插件,变量插件,过滤插件等功能,该功能不常用
    (5)API:提供第三方程序调用的应用程序编程接口;
    (6)Ansible :组合inventory,APL,Moudles,Plugins可以理解为Ansible命令工具其核心执行工具;
    3.作用对象
    Ansible的作用对象不仅仅是linux和非linux操作系统,也可以作用与各类PUBLIC/PRIVATE,商用和非商用设备的网络设施
    使用者使用Ansible或ANsible-playbooks时,在服务器终端输入Ansible的Ad-Hoc命令或Playbooks后,Ansible会遵循预先定义安排的规则将Playbooks后诼步拆解为Play,再将Play组织成Ansible可以识别的任务,随后调用任务设计的所有模板和插件,根据lnventory中定义的主机列表通过ssh将任务集以临时文件或命令的形式传输到远程客户端执行并返回执行结果,如果时临时文件则执行完毕后删除.

四.Ansbile 搭建

ansible的安装部署非常简单,以rpm安装为例,配置好163或阿里的yun源直接安装就可以了,ansible的管理端只能是linux,如RedHat,Debian,CentOS,下面介绍再Centos7.6上安装部署Ansible

实验环境
    操作系统    IP地址          角色        主机名      CPU核心数
    centos7.6   192.168.1.11    ansible     ansible     1
    centos7.6   192.168.1.22    client      client2     2
    centos7.6   192.168.1.33    client      client3     3    

1.关闭防火墙(所有主机)
    systemctl stop firewalld
    iptables -F
    setenforce 0
2.创建密钥验证
  • ansible是通过ssh协议对设备进行管理,而ssh服务包含两种认证方式,一种通过密码登录,另一种是通过密钥对验证,密码方式必须和系统进行交互,而密钥对是免交互登录,如果希望通过ansible自动化管理设备应该配置为免交互登录被管理设备

         [root@ansible ~]# ssh-keygen -t rsa 
         Generating public/private rsa key pair.
         Enter file in which to save the key (/root/.ssh/id_rsa): 
         Created directory '/root/.ssh'.
         Enter passphrase (empty for no passphrase): 
         Enter same passphrase again: 
         Your identification has been saved in /root/.ssh/id_rsa.
         Your public key has been saved in /root/.ssh/id_rsa.pub.
         The key fingerprint is:
         SHA256:jjESd7O6ruRaLTU3U4iaJqASAQBsVSday+f0ShlH2vE root@ansible
         The key's randomart image is:
         +---[RSA 2048]----+
         |X ...+ . o       |
         | +  + +.+.o      |
         |+  ..oo=+o.E     |
         |.o   =+.=+       |
         |o . = =+S.       |
         |.  o +.O.o       |
         |    + +..        |
         |   + . .         |
         |  ..ooo          |
         +----[SHA256]-----+'
    
  • 因为传输密钥时需要输入密码可以借用sshpass,但是首次登录需要输入yes.所以更改ssh配置文件35行免交互登录.以下是更改过后的内容

         [root@ansible ~]# vim /etc/ssh/ssh_config 
             34 #   ConnectTimeout 0
             35 StrictHostKeyChecking no
             36 #   IdentityFile ~/.ssh/identity
         
         [root@ansible ~]# sshpass -p'woaini' ssh-copy-id 192.168.1.22
         [root@ansible ~]# sshpass -p'woaini' ssh-copy-id 192.168.1.33
    
         测试免密连接
         [root@ansible ~]# ssh root@192.168.22
         ssh: connect to host 192.168.22 port 22: Connection refused
         [root@ansible ~]# ssh root@192.168.1.22
         Last login: Mon Oct 28 00:29:59 2019 from 192.168.1.1
         root@client2~$>exit
         登出
         Connection to 192.168.1.22 closed.
         [root@ansible ~]# ssh root@192.168.1.33
         Last login: Mon Oct 28 00:32:05 2019 from 192.168.1.1
         root@cilent3~$>
    

    3.配置/etc/hosts文件

     [root@ansible ~]# vim /etc/hosts
     192.168.1.11 ansible
     192.168.1.22 client2
     192.168.1.33 client3
     [root@ansible ~]# scp /etc/hosts 192.168.1.22:/etc/
     hosts                                         100%  221    77.8KB/s   00:00    
     [root@ansible ~]# scp /etc/hosts 192.168.1.33:/etc/
     hosts                                         100%  221   151.1KB/s   00:00 
    

    4.安装ansible(推荐yum安装)

     [root@ansible yum.repos.d]# cd /etc/yum.repos.d/
     [root@ansible yum.repos.d]# wget http://mirrors.aliyun.com/repo/Centos-7.repo
     [root@ansible yum.repos.d]# yum clean all
     [root@ansible yum.repos.d]# yum makecache 
     [root@ansible yum.repos.d]# yum -y install ansible
    

    5.ansible配置

  • lnventory是ansible管理主机信息的配置文件,相当于系统的hosts文件功能,默认存放再/etc/ansible/hosts.在hosts文件中通过分组来组织设备,ansible通过lnventory来定义主机和分组,通过ansible命令中的-i或者–inventory-file指定lnventory

     [root@ansible ~]# cp /etc/ansible/hosts{,.bak}
     [root@ansible yum.repos.d]# vim /etc/ansible/hosts
         [client]
         192.168.1.22
         192.168.1.33
         可以直接写IP地址还可以根据/etc/hosts文件写主机名,并且可以使用正则如client[2:3]
     [root@ansible ~]# ansible -i /etc/ansible/hosts client -m ping          //测试主机连接状态
         192.168.1.22 | SUCCESS => {
             "changed": false, 
             "ping": "pong"
         }
         192.168.1.33 | SUCCESS => {
             "changed": false, 
             "ping": "pong"
         }
    

五.ansbile的简单操作

  • 配置完成后可以针对hosts定义服务组件进行远程操作,也可以针对组中的指定的某一个或多个主机操作,下面接收如何针对特定的服务器操作.

    1.针对client组中的192.168.1.22主机操作,通过–limit参数限定主机的变更

     [root@ansible ~]# ansible client -m command -a "head -2 /etc/passwd" --limit "192.168.1.22"
         192.168.1.22 | SUCCESS | rc=0 >>
         root:x:0:0:root:/root:/bin/bash
         bin:x:1:1:bin:/bin:/sbin/nologin
    

    2.只针对192.168.1.22主机操作,通过ip限定主机变更

     [root@ansible ~]# ansible 192.168.1.22 -m command -a "head -2 /etc/passwd"
         192.168.1.22 | SUCCESS | rc=0 >>
         root:x:0:0:root:/root:/bin/bash
         bin:x:1:1:bin:/bin:/sbin/nologin
    

    3.只对192.168.1.0网段主机进行操作.通过正则匹配

     [root@ansible ~]# ansible 192.168.1.* -m command -a "head -5 /etc/passwd"
         192.168.1.33 | SUCCESS | rc=0 >>
         root:x:0:0:root:/root:/bin/bash
         bin:x:1:1:bin:/bin:/sbin/nologin
         daemon:x:2:2:daemon:/sbin:/sbin/nologin
         adm:x:3:4:adm:/var/adm:/sbin/nologin
         lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    
         192.168.1.22 | SUCCESS | rc=0 >>
         root:x:0:0:root:/root:/bin/bash
         bin:x:1:1:bin:/bin:/sbin/nologin
         daemon:x:2:2:daemon:/sbin:/sbin/nologin
         adm:x:3:4:adm:/var/adm:/sbin/nologin
         lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    

六.Ansible命令

ansible的维护命令大多也ansible开头,在终端输入ansible后连续按两次tab键.会补全所有ansible字母开头的命令,下面介绍ansible的一些常用命令.

[root@ansible ~]# ansible
    ansible               ansible-doc           ansible-playbook-2
    ansible-2             ansible-doc-2         ansible-playbook-2.7
    ansible-2.7           ansible-doc-2.7       ansible-pull
    ansible-config        ansible-galaxy        ansible-pull-2
    ansible-connection    ansible-galaxy-2      ansible-pull-2.7
    ansible-console       ansible-galaxy-2.7    ansible-vault
    ansible-console-2     ansible-inventory     ansible-vault-2
    ansible-console-2.7   ansible-playbook      ansible-vault-2.7
  • ansible 选项
    ansible是生产环境中使用非常频繁的命令之一,主要在以下场景应用
    (1)非固化需求
    (2)临时一次性操作
    (3)二次开发接口调用

  • 非固化需求是指临时性的维护,如果产看client服务器组的磁盘使用情况,复制一个文件到其他机器等,类似这些没有规律的,临时需要做的任务,我们称为非固化需求,临时一次性操作

     语法: ansible <host-pattern> [options]
    
     可用选项
         ➢ -V    (--verbose):输出详细的执行过程信息,可以得到执行过程所有信息。
         ➢ 4i    PAH--inventory=PATH): 指定inventory 信息,默认为/etc/ansible/hostsv
         ➢ -f    NUM(--forks=NUM):并发线程数,默认为5个线程。
         ➢ --private-key=PRIVATE_ KEY_ FILE  指定秘钥文件。
         ➢ -m NAME,--moudle-name=NAME:   指定执行时使用的模块。
         ➢ -M DIRECTORY (--module path=DIRECTORY):   指定模块存放路径,默认为/usr/share/ansible,也可以通过ANSIBLE_ _LIBRARY 设定默认目录,
         ➢ -a ARGUMENTS (--args=ARGUMENTS) : 指定模块参数+
         ➢ -u USERNAME (-user=USERNAME); 指定远程主机USERNAME运行命令。
         ➢ -I subset (-limit=SUBSET):    限定运行主机。
         ➢ -list-hosts:  列出符合条件的主机列表,不执行任何命令。
     
     主机和主机组注意事项    
         主机组范围      解释
         all             代表所有主机
         webA:webB       可以指定多台主机
         all:\!webA      指定all但不包含webB,注意!前需要加转义符\
    
    1. 实验案例

       (1).检查所有主机是否存活
           [root@ansible ~]# ansible all -f 5 -m ping
           192.168.1.22 | SUCCESS => {
               "changed": false, 
               "ping": "pong"
           }
           client2 | SUCCESS => {
               "changed": false, 
               "ping": "pong"
           }
           192.168.1.33 | SUCCESS => {
               "changed": false, 
               "ping": "pong"
           }
           client3 | SUCCESS => {
               "changed": false, 
               "ping": "pong"
           }
       (2)列出 client 组中所有主机列表
           [root@ansible ~]# ansible client --list-host
           hosts (2):
               192.168.1.22
               192.168.1.33
           [root@ansible ~]# tail -3 /etc/ansible/hosts
           [client]
           192.168.1.22
           192.168.1.33
       (3)批量显示client组中的磁盘使用情况
           [root@ansible ~]# ansible client -m command -a "df -Th"
           192.168.1.22 | SUCCESS | rc=0 >>
           文件系统       类型      容量  已用  可用 已用% 挂载点
           /dev/sda3      xfs        98G  4.6G   93G    5% /
           devtmpfs       devtmpfs  895M     0  895M    0% /dev
           tmpfs          tmpfs     910M     0  910M    0% /dev/shm
           tmpfs          tmpfs     910M  9.8M  900M    2% /run
           tmpfs          tmpfs     910M     0  910M    0% /sys/fs/cgroup
           /dev/sda2      xfs       397M   21M  377M    6% /home
           tmpfs          tmpfs     182M     0  182M    0% /run/user/0
      
           192.168.1.33 | SUCCESS | rc=0 >>
           文件系统       类型      容量  已用  可用 已用% 挂载点
           /dev/sda3      xfs        98G  4.6G   93G    5% /
           devtmpfs       devtmpfs  895M     0  895M    0% /dev
           tmpfs          tmpfs     910M     0  910M    0% /dev/shm
           tmpfs          tmpfs     910M  9.8M  900M    2% /run
           tmpfs          tmpfs     910M     0  910M    0% /sys/fs/cgroup
           /dev/sda2      xfs       397M   21M  377M    6% /home
           tmpfs          tmpfs     182M     0  182M    0% /run/user/0
      
           clinet需要提前在/etc/ansible/hosts文件中定义组
           'ansible的返回结果非常友好,一般会用三种颜色表示执行结果:
               红色表示执行过程中有异常
               橘黄色表示命令执行后目标有状态变化
               绿色表示执行成功且没有对目标机器做修改'
      

    3.ansible-doc

  • ansible-doc用来查询ansible模块文档的说明,类似于man命令,针对每个模块都有详细的用法说明及应用案例介绍

     (1)查看列出所有支持的模块
         [root@ansible ~]# ansible-doc -l        
     (2)查看shell模块的帮助
         [root@ansible ~]# ansible-doc -s shell
         [root@ansible ~]# ansible-doc -s raw        //查看raw的帮助
    

    4.ansible-playbook

  • ansible-playbook是日常应用中使用频率最高的命令,类似linux系统中的sh或者source命令,用来执行系列任务,其工作机制是,通过读取编写好的playbook文件实现集中处理任务,ansible-playbook命令后跟yml格式的playbook文件,playbook文件存放要执行的任务代码

     语法:   ansible-playbook playbook.yml 
     playbook.yml需要预先编写好,建议写playbook.yml的绝对路径
    

    5.ansible-console

  • ansible-console是ansible为用户提供的一款交互工具,类似于windows中的cmd以及linux中的shell,用户可以在ansible-console虚拟出的做像shell一样使用ansible内置的各种命令,这位习惯shell交互方式的用户提供了良好的体验,在终端输入ansible-console命令后显示如下

     [root@ansible ~]# ansible-console
     Vault password: 
     Welcome to the ansible console.
     Type help or ? to list commands.
    
     root@all (2)[f:5]$ cd client
     root@client (2)[f:5]$ list
     192.168.1.22
     192.168.1.33
    
  • 所有操作于shell类似,而且支持tab键补全功能,按快捷键ctrl+d 或者 ctrl + c 即可退出当前虚拟终端

七.Ansible模块

  • 1.command模块
    command模块在远程主机上执行命令,不支持管道,重定向等shell特性,常用参数如下(不支持管道,不建议使用)
    (1)chdir:在远程主机上运行命令前提是进入的目录
    (2)creates:在命令运行时创建一个文件,如果文件以及存在,则不会创建任务
    (3)removes: 在命令运行时移除一个文件,如果文件不存在,则不会执行移除任务
    (4)executeble: 指明运行命令的shell程序

     实验案例
         在所有主机上运行'ls ./'命令,运行前切换到/home目录.准备以下环境:在两台client上分布创建client用户和server用户,否则/home下查看不到效果
         [root@client2 ~]# useradd client
         [root@cilent3 ~]# useradd server
    
         ansible端操作
         [root@ansible ~]# ansible all -m command -a "chdir=/home ls ./"
             192.168.1.33 | SUCCESS | rc=0 >>
             server
    
             192.168.1.22 | SUCCESS | rc=0 >>
             client
    
  • 2.shell模块
    shell模块在远程主机上执行命令,相当于调用远程主机的shell进程,然后在该shell下打开一个子shell运行命令,和command模块的区别它支持shell特性,如管道,重定向等

     实验案例
         (1).重定向
             [root@ansible ~]# ansible client -m shell -a "echo '提示符' > /root/1.txt"
             192.168.1.33 | SUCCESS | rc=0 >>
    
             192.168.1.22 | SUCCESS | rc=0 >>
    
             [root@ansible ~]# ansible client -m shell -a "cat /root/1.txt"
             192.168.1.33 | SUCCESS | rc=0 >>
             提示符
    
             192.168.1.22 | SUCCESS | rc=0 >>
             提示符
         (2).管道
             [root@ansible ~]# ansible client -m shell -a "ifconfig | grep -E 192.168.1.??"
    
             192.168.1.33 | SUCCESS | rc=0 >>
                     inet 192.168.1.33  netmask 255.255.255.0  broadcast 192.168.1.255
                     inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
    
             192.168.1.22 | SUCCESS | rc=0 >>
                     inet 192.168.1.22  netmask 255.255.255.0  broadcast 192.168.1.255
                     inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
    

    3.raw模块
    最原始的方式运行命令(不依赖python,仅通过ssh实现)

     (1)清除client2的yum缓存
         [root@ansible ~]# ansible client -m raw -a 'yum clean all' --limit 192.168.1.22
         192.168.1.22 | SUCCESS | rc=0 >>
         已加载插件:fastestmirror, langpacks
         Repository cr is listed more than once in the configuration
         Repository C7.0.1406-base is listed more than once in the configuration
         正在清理软件源: base extras updates
         Shared connection to 192.168.1.22 closed.
     (2)yun安装nmap包(这条命令会卡一会,需要联网)
             [root@ansible ~]# ansible client -m raw -a 'yum -y install nmap' --limit 192.168.1.22
             192.168.1.22 | SUCCESS | rc=0 >>
             已加载插件:fastestmirror, langpacks
             Repository cr is listed more than once in the configuration
             正在解决依赖关系
             --> 正在检查事务
             ---> 软件包 nmap.x86_64.2.6.40-19.el7 将被 安装
             --> 正在处理依赖关系 nmap-ncat = 2:6.40-19.el7,它被软件包 2:nmap-6.40-19.el7.x86_64 需要
             --> 正在检查事务
             ---> 软件包 nmap-ncat.x86_64.2.6.40-16.el7 将被 升级
             ---> 软件包 nmap-ncat.x86_64.2.6.40-19.el7 将被 更新
             --> 解决依赖关系完成
    
             依赖关系解决
    
             ================================================================================
             Package            架构            版本                    源             大小
             ================================================================================
             正在安装:
             nmap               x86_64          2:6.40-19.el7           base          3.9 M
             为依赖而更新:
             nmap-ncat          x86_64          2:6.40-19.el7           base          206 k
    
             事务概要
             ================================================================================
             安装  1 软件包
             升级           ( 1 依赖软件包)
             总计                                               281 kB/s | 4.2 MB  00:15     
             Running transaction check
             Running transaction test
             Transaction test succeeded
             Running transaction
             正在更新    : 2:nmap-ncat-6.40-19.el7.x86_64                              1/3 
             正在安装    : 2:nmap-6.40-19.el7.x86_64                                   2/3 
             清理        : 2:nmap-ncat-6.40-16.el7.x86_64                              3/3 
             验证中      : 2:nmap-ncat-6.40-19.el7.x86_64                              1/3 
             验证中      : 2:nmap-6.40-19.el7.x86_64                                   2/3 
             验证中      : 2:nmap-ncat-6.40-16.el7.x86_64                              3/3 
    
             已安装:
             nmap.x86_64 2:6.40-19.el7                                                     
    
             作为依赖被升级:
             nmap-ncat.x86_64 2:6.40-19.el7                                                
    
             完毕!
             Shared connection to 192.168.1.22 closed.
    

    4.copy模块

  • copy模块用于复制指定主机文件到远程主机的指定位置,常见参数如下
    (1)dest: 指出复制文件的目标目录位置(使用绝对路径).如果源时目录,指目标也要时目录,如果目录目标文件已存在则覆盖
    (2)src : 指出源文件路径(可以使用绝对路径或者相对路径),支持直接指定目录,如果源时目录则目标也要是目录
    (3)mode : 指出复制时,目标文件的权限,可选
    (4)group : 指出复制时,目标文件的数组,可选
    (5)owner : 指出复制时,目标文件的属主,可选
    (6)content: 指出复制到目标主机上的内容,不能与src一起使用,相当与复制content指明书记到目标文件中

     提示:参数backup=yes ===>意思是,如果目标路径下,有与我同名但不同内容的文件时,在覆盖前,对目标先进行备份
    
     所有被管理端节点必须安装libselinux-python包
     [root@ansible ~]# ansible all -m raw -a 'yum -y install libselinux-python' 
    
     实验案例
         将client主中主机的/etc/hosts文件拷贝到/root下指定权限为 777 更改属主为ftp 数组为root
         
         [root@ansible ~]# ansible client -m copy -a "src=/etc/hosts dest=/root/ mode=777 owner=ftp group=root"
         192.168.1.33 | SUCCESS => {
             "changed": true, 
             "checksum": "7c797d67a1570ae32ffd3a6cd6be0321998ba803", 
             "dest": "/root/hosts", 
             "gid": 0, 
             "group": "root", 
             "md5sum": "7e7645a57c10ceaabea79b47dffd205e", 
             "mode": "0777", 
             "owner": "ftp", 
             "size": 221, 
             "src": "/root/.ansible/tmp/ansible-tmp-1572242181.55-99628567601557/source", 
             "state": "file", 
             "uid": 14
         }
         192.168.1.22 | SUCCESS => {
             "changed": true, 
             "checksum": "7c797d67a1570ae32ffd3a6cd6be0321998ba803", 
             "dest": "/root/hosts", 
             "gid": 0, 
             "group": "root", 
             "md5sum": "7e7645a57c10ceaabea79b47dffd205e", 
             "mode": "0777", 
             "owner": "ftp", 
             "size": 221, 
             "src": "/root/.ansible/tmp/ansible-tmp-1572242181.54-171232305387117/source", 
             "state": "file", 
             "uid": 14
         }
    
         [root@ansible ~]# ansible client -m raw -a "ls -l /root/hosts"
         192.168.1.22 | SUCCESS | rc=0 >>
         -rwxrwxrwx 1 ftp root 221 10月 28 05:56 /root/hosts
         Shared connection to 192.168.1.22 closed.
    
         192.168.1.33 | SUCCESS | rc=0 >>
         -rwxrwxrwx 1 ftp root 221 10月 28 05:56 /root/hosts
         Shared connection to 192.168.1.33 closed.
    
  • 5.hostname模块
    hostname模块用于远程管理主机上的主机名,常用参数如下
    name : 指明主机名

         实验案例
    
         更改client2(192.168.1.22)的主机名为client1
         [root@ansible ~]# ansible 192.168.1.22 -m hostname -a "name=client1"
         192.168.1.22 | SUCCESS => {
             "ansible_facts": {
                 "ansible_domain": "", 
                 "ansible_fqdn": "client1", 
                 "ansible_hostname": "client1", 
                 "ansible_nodename": "client1"
             }, 
             "changed": true, 
             "name": "client1"
         }
         [root@ansible ~]# ansible 192.168.1.22 -m raw -a "hostname"
         192.168.1.22 | SUCCESS | rc=0 >>
         client1
         Shared connection to 192.168.1.22 closed.
         注意更改回来否则后面测试主机名会报错
         [root@ansible ~]# ansible 192.168.1.22 -m hostname -a "name=client2"
         192.168.1.22 | SUCCESS => {
             "ansible_facts": {
                 "ansible_domain": "", 
                 "ansible_fqdn": "client2", 
                 "ansible_hostname": "client2", 
                 "ansible_nodename": "client2"
             }, 
             "changed": true, 
             "name": "client2"
             }
    

    6.yun模块

  • yum模块基于yum机制,对远程自己管理程序包,常用参数如下
    (1)name : 程序包名称,可以带上版本包,如果不指定版本号默认安装为最新版本
    (2)state=present | latest | absent 指明对程序包的操作,present表示安装 latest表示安装最新版本程序包,absent表示卸载程序包
    (3)disablerepo: 在用yum安装时禁用某个仓库的ID
    (4)enablerepo: 在用yum安装时启用某个仓库的ID
    (5)conf_file: yum运行时的配置文件而不是使用默认的配置文件
    (6)diable_gpg_check=yes | no :是否启用完整性校验功能

     实验案例
         注意实验前要在client端配置yum仓库
         管理员只是发送yun命令到被管理端,被管理端要存在可用的yum仓库才能安装成功
    
         client端yum安装dhcp
         [root@ansible ~]# ansible client -m yum -a "name=dhcp state=present"
         内容太长就不展示了
    
  • 7.service模块
    service模块为用来管理远程主机上的服务的模块,常见参数如下
    (1)name : 被管理的服务名称
    (2)state=started |stoped | restarted 动作包含启动关闭,重启
    (3)enabled=yes | no : 表示是否设置该服务开机自启
    (4)runlevel: 如果设定了enabled开机自启,则要定义在那些运行目标下自启动

     实验案例
      (1).启动httpd服务并设置为开机自启(没有的化进行安装)
        [root@ansible ~]# ansible client -m yum -a "name=httpd state=present"
        [root@ansible ~]# ansible client -m service -a "name=httpd state=started enabled=yes"
        内容太长不再展示
    
  • 8.user模块
    user模块用于管理远程主机上的用户账户,常见参数如下
    (1)name : 必选参数账号名称
    (2)state=present | absent : 创建账号或者删除 present表示创建,absent表示删除
    (3)system=yes | no :是否为系统账号
    (4)uid : 指定用户uid
    (5)group : 用户基本组
    (6)groups : 用户附加组
    (7)shell : 默认使用的shell
    (8)home : 用户的家目录
    (9)move_home=yes | no :如果设置的家目录已经存在,是否将已经存在的家目录进行移动
    (10)password : 用户的密码,建议使用加密后的字符段
    (11)comment : 用户的注释信息
    (12)remove=yes | no :当state=absent时,是否删除用户家目录

     实验案例:
         1.创建用户
             [root@ansible ~]# ansible client -m user -a 'name=user1 system=yes uid=502 group
             =root groups=sshd shell=/sbin/nologin home=/home/user1 password=123123 comment="test user"'
             192.168.1.33 | SUCCESS => {
                 "changed": true, 
                 "comment": "test user", 
                 "createhome": true, 
                 "group": 0, 
                 "groups": "sshd", 
                 "home": "/home/user1", 
                 "name": "user1", 
                 "password": "NOT_LOGGING_PASSWORD", 
                 "shell": "/sbin/nologin", 
                 "state": "present", 
                 "system": true, 
                 "uid": 502
             }
             192.168.1.22 | SUCCESS => {
                 "changed": true, 
                 "comment": "test user", 
                 "createhome": true, 
                 "group": 0, 
                 "groups": "sshd", 
                 "home": "/home/user1", 
                 "name": "user1", 
                 "password": "NOT_LOGGING_PASSWORD", 
                 "shell": "/sbin/nologin", 
                 "state": "present", 
                 "system": true, 
                 "uid": 502
             }
             [root@ansible ~]# ansible client -m raw -a "cat /etc/passwd | grep user1"
             192.168.1.33 | SUCCESS | rc=0 >>
             user1:x:502:0:test user:/home/user1:/sbin/nologin
             Shared connection to 192.168.1.33 closed.
    
             192.168.1.22 | SUCCESS | rc=0 >>
             user1:x:502:0:test user:/home/user1:/sbin/nologin
             Shared connection to 192.168.1.22 closed.'
         2.删除用户及家目录
             [root@ansible ~]# ansible client -m user -a 'name=user1 state=absent remove=yes'192.168.1.33 | SUCCESS => {
                 "changed": true, 
                 "force": false, 
                 "name": "user1", 
                 "remove": true, 
                 "state": "absent", 
                 "stderr": "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到\n", 
                 "stderr_lines": [
                     "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到"
                 ]
             }
             192.168.1.22 | SUCCESS => {
                 "changed": true, 
                 "force": false, 
                 "name": "user1", 
                 "remove": true, 
                 "state": "absent", 
                 "stderr": "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到\n", 
                 "stderr_lines": [
                     "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到"
                 ]
             }
             [root@ansible /]# ansible client -m raw -a 'ls /home '
             192.168.1.22 | SUCCESS | rc=0 >>
             client
             Shared connection to 192.168.1.22 closed.
    
             192.168.1.33 | SUCCESS | rc=0 >>
             server
             Shared connection to 192.168.1.33 closed.
             [root@ansible /]# ansible client -m raw -a 'tail -2 /etc/passwd'
             192.168.1.22 | SUCCESS | rc=0 >>
             dhcpd:x:177:177:DHCP server:/:/sbin/nologin
             apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
             Shared connection to 192.168.1.22 closed.
    
             192.168.1.33 | SUCCESS | rc=0 >>
             dhcpd:x:177:177:DHCP server:/:/sbin/nologin
             apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
             Shared connection to 192.168.1.33 closed.
    

    9.script模块
    script模块能够实现远程服务器批量运行本地的shell脚本

     案例
         先写个脚本
         [root@ansible ~]# vim ansible.sh
         #!/bin/sh
         #批量发脚本并执行
         ansible client -m copy -a "src=/opt/echo.sh dest=/opt"
         ansible client -m script -a "/opt/echo.sh"
         
         [root@ansible ~]# vim /opt/echo.sh
         #!/bin/bash
         echo '一切正常' > /var/log/messages
         [root@ansible ~]# sh ansible.sh 
         192.168.1.33 | SUCCESS => {
             "changed": true, 
             "checksum": "d2a6a4c6061cc29d9a6ca1b9ad417117148dd05f", 
             "dest": "/opt/echo.sh", 
             "gid": 0, 
             "group": "root", 
             "md5sum": "42bf6f7c7ee27c3982697e75ba79b6e2", 
             "mode": "0644", 
             "owner": "root", 
             "size": 52, 
             "src": "/root/.ansible/tmp/ansible-tmp-1572246699.4-27393012844177/source", 
             "state": "file", 
             "uid": 0
         }
         192.168.1.22 | SUCCESS => {
             "changed": true, 
             "checksum": "d2a6a4c6061cc29d9a6ca1b9ad417117148dd05f", 
             "dest": "/opt/echo.sh", 
             "gid": 0, 
             "group": "root", 
             "md5sum": "42bf6f7c7ee27c3982697e75ba79b6e2", 
             "mode": "0644", 
             "owner": "root", 
             "size": 52, 
             "src": "/root/.ansible/tmp/ansible-tmp-1572246699.4-88189636460715/source", 
             "state": "file", 
             "uid": 0
         }
         192.168.1.22 | SUCCESS => {
             "changed": true, 
             "rc": 0, 
             "stderr": "Shared connection to 192.168.1.22 closed.\r\n", 
             "stdout": "", 
             "stdout_lines": []
         }
         192.168.1.33 | SUCCESS => {
             "changed": true, 
             "rc": 0, 
             "stderr": "Shared connection to 192.168.1.33 closed.\r\n", 
             "stdout": "", 
             "stdout_lines": []
         }
         
         [root@ansible ~]# ansible client -m raw -a 'tail -10 /var/log/messages'
         192.168.1.22 | SUCCESS | rc=0 >>
         一切正常
         Oct 28 07:12:41 ms2 systemd-logind: Removed session 75.
         Oct 28 07:12:45 ms2 systemd-logind: New session 76 of user root.
         Oct 28 07:12:45 ms2 systemd: Started Session 76 of user root.
         Shared connection to 192.168.1.22 closed.
    
         192.168.1.33 | SUCCESS | rc=0 >>
         一切正常
         Oct 28 07:12:41 ms3 systemd-logind: Removed session 68.
         Oct 28 07:12:45 ms3 systemd: Started Session 69 of user root.
         Oct 28 07:12:45 ms3 systemd-logind: New session 69 of user root.
         Shared connection to 192.168.1.33 closed.
    

- [ ] 八.playbook配置文件

       1.执行配置文件
           playbook配置文件使用yaml语法,具有简洁明了,结构清晰等特点.playbook配置文件类似与shell脚本,是一个yaml格式的文件,用于保存针对特定需求的任务列表,前面介绍的ansible命令虽然可以完成各种任务,但是当配置一系列任务时,逐条输入命令就显得效率非常低下,更有效的方式在playbook配置中配置所有的任务代码,利用ansible-playbook命令执行该文件,可以实现自动化运维,yaml文件的扩展名通常为.yaml或.yml

    yaml语法和其他高级语言类似,其结构通过缩进来展示"-"来代表选项,通过冒号":"来分隔键和值.整个文件以"---"开始,并且以"..."结尾,如下所示\
    [root@ansible ~]# vim /etc/ansible/test.yml
        ---                                     //开始格式
        - host: 192.168.1.22                    //操作的主机
        remote_user: root                       //以root用户
        tasks:                                  //任务标签
            - name: adduser                     //任务名称
            user: name=user2 state=present      //使用user模块,创建user2用户
            tags:                               //标签
                - 创建user2用户
            - name: addgroup                    //任务名称
            group: name=root system=yes         //创建root组
            tags:                               //任务标签
                - 创建root组                    
        - hosts: 192.168.1.33                   //操作的主机
        remote_user: root                       //以root用户 
        tasks:                                  //任务标签
            - name: copy                        //任务名称
            copy: src=/etc/passwd dest=/home    //使用copy模块,cp本地passwd文件到/home下
            tags:                               //任务标签
                - 拷贝passwd文件    
        ...                                     //结尾格式

    所有的"-"和":"后面均有空格,而且注意缩进和对齐
    playbook的核心元素
        (1)hosts :任务的目标主机,多个主机用冒号分隔,一般调用/etc/ansible/hosts中的分组信息
        (2)remote_user : 远程主机上,运行此任务的用户默认为root
        (3)tasks : 任务,即定义的具体任务,由模块定义的操作列表
        (4)handlers:触发器,类似tasks,只是在特定的条件下才会触发任务.某任务的状态在运行后为changed时,可通过"notify" 通知给相应的handlers进行触发执行.
        (5)roles:角色,将hosts剥离出去,由tasks,handlersd等所组成的一种特定的结构集合.
    
    用法:ansible-playbook [option] /PATH/TO/PLAYBOOK.yaml
    1.--syntax-check: 检测yaml文件的语句
    2.-C (--check): 测试,不会改变主机的任何配置
    3.--list-hosts:列出yaml文件影响的主机列表
    4.--list-tasks:列出yaml文件中的任务列表
    5.--list-tags:列出yaml文中的标签
    6.-t TAGS(-tags=TAGS):表示只执行指定标签的任务
    7.--skip-tags=SKIP_TAGSS:表示除了指定标签任务,执行其他任务
    8.--start-at-task=STAPR_AT:从指定任务开始往下运行.

    实验案例:
        1.检测yaml文件的语句
            root@ansible~$>ansible-playbook --syntax-check /etc/ansible/test.yml
            playbook: /etc/ansible/test.yml             //没有提示报错

        2.测试,不改变主机任何配置
            root@ansible~$>ansible-playbook -C /etc/ansible/test.yml

            PLAY [server1] **************************************************************************

            TASK [Gathering Facts] ******************************************************************
            ok: [192.168.1.22]

            TASK [adduser] **************************************************************************
            changed: [192.168.1.22]

            TASK [addgroup] *************************************************************************
            ok: [192.168.1.22]

            PLAY [server2] **************************************************************************

            TASK [Gathering Facts] ******************************************************************
            ok: [192.168.1.33]

            TASK [copy] *****************************************************************************
            changed: [192.168.1.33]

            PLAY RECAP ******************************************************************************
            192.168.1.22               : ok=3    changed=1    unreachable=0    failed=0
            192.168.1.33               : ok=2    changed=1    unreachable=0    failed=0
        3.列出yaml文件影响的主机
            root@ansible~$>ansible-playbook --list-hosts /etc/ansible/test.yml

            playbook: /etc/ansible/test.yml

            play #1 (server1): server1    TAGS: []
                pattern: [u'server1']
                hosts (1):
                192.168.1.22

            play #2 (server2): server2    TAGS: []
                pattern: [u'server2']
                hosts (1):
                192.168.1.33
        4.列出yuaml文件中的任务标签
            root@ansible~$>ansible-playbook --list-tasks /etc/ansible/test.yml

            playbook: /etc/ansible/test.yml

            play #1 (server1): server1    TAGS: []
                tasks:
                adduser   TAGS: [创建user2用户]
                addgroup  TAGS: [创建root组]

            play #2 (server2): server2    TAGS: []
                tasks:
                copy      TAGS: [拷贝passwd文件]
        5.列出yaml文中的标签
            root@ansible~$>ansible-playbook --list-tags /etc/ansible/test.yml

            playbook: /etc/ansible/test.yml

            play #1 (server1): server1    TAGS: []
                TASK TAGS: [创建root组, 创建user2用户]

            play #2 (server2): server2    TAGS: []
                TASK TAGS: [拷贝passwd文件]
        6.只执行指定标签的任务
            root@ansible~$>ansible-playbook -t 拷贝passwd文件 /etc/ansible/test.yml

            PLAY [server1] **************************************************************************

            TASK [Gathering Facts] ******************************************************************
            ok: [192.168.1.22]

            PLAY [server2] **************************************************************************

            TASK [Gathering Facts] ******************************************************************
            ok: [192.168.1.33]

            TASK [copy] *****************************************************************************
            changed: [192.168.1.33]

            PLAY RECAP ******************************************************************************
            192.168.1.22               : ok=1    changed=0    unreachable=0    failed=0
            192.168.1.33               : ok=2    changed=1    unreachable=0    failed=0
        7.执行输出
            root@ansible~$>vim /etc/ansible/test.yml
                - hosts: server1
                remote_user: root
                tasks:
                    - name: adduser
                    user: name=user2 state=present
                    register: print_result       #将之前命令的输出保存在变量print_result中
                    tags:
                        - 创建user2用户
                    - debug: var=print_result    #将变量的值作为debug输出
                    - name: addgroup
                    group: name=root system=yes
                    tags:
                        - 创建root组

            root@ansible~$>ansible-playbook /etc/ansible/test.yml

                PLAY [server1] **************************************************************************

                TASK [Gathering Facts] ******************************************************************
                ok: [192.168.1.22]

                TASK [adduser] **************************************************************************
                changed: [192.168.1.22]

                TASK [debug] ****************************************************************************
                ok: [192.168.1.22] => {
                    "print_result": {
                        "changed": true,
                        "comment": "",
                        "createhome": true,
                        "failed": false,
                        "group": 1001,
                        "home": "/home/user2",
                        "name": "user2",
                        "shell": "/bin/bash",
                        "state": "present",
                        "system": false,
                        "uid": 1001
                    }
                }

                TASK [addgroup] *************************************************************************
                ok: [192.168.1.22]

                PLAY [server2] **************************************************************************

                TASK [Gathering Facts] ******************************************************************
                ok: [192.168.1.33]

                TASK [copy] *****************************************************************************
                ok: [192.168.1.33]

                PLAY RECAP ******************************************************************************
                192.168.1.22               : ok=4    changed=1    unreachable=0    failed=0
                192.168.1.33               : ok=2    changed=0    unreachable=0    failed=0
2.触发器
  • 需要触发才能执行的任务,在之前定义在tasks中的任务执行完成后,若希望在基础上触发其他的任务,这就需要到了触发器,这是就需要handlers.例如当通过ansible的模块对目标主机的配置文件进行修改后,如果任务执行成功,可以触发一个触发器,在触发器中定义目标主机的服务重启操作,以便使配置文件生效,handlers触发器具有以下优点.
    (1)handlers使Ansible提供的条件机制之一,handlers和task类似,但是他在被task通知时才会触发执行
    (2)handlers只会在所有任务执行完成后执行,而且即使被通知了多次,它也只会执行一次,handlers按照定义顺序依次执行

     案例
         root@ansible~$>ansible client -m shell -a "netstat -lntp | grep httpd"
             192.168.1.33 | SUCCESS | rc=0 >>
             tcp6       0      0 :::80                   :::*                    LISTEN      6681/httpd
    
             192.168.1.22 | SUCCESS | rc=0 >>
             tcp6       0      0 :::80                   :::*                    LISTEN      6369/httpd
         root@ms1~$>vim /etc/ansible/httpd.yml
             ---
             - hosts: client
             remote_user: root
             tasks:
                 - name: change port
                 command: sed -i 's/Listen 80/Listen 8080/g' /etc/httpd/conf/httpd.conf
                 notify:                         //完成任务后调用restat httpd server触发器
                     - restart httpd server
             handlers:
                 - name: restart httpd server    //指定触发器的名字
                 service: name=httpd state=restarted    //指定触发条件为重启httpd服务
             ...
         root@ms1~$>ansible-playbook --syntax-check /etc/ansible/httpd.yml    //检测语法
             playbook: /etc/ansible/httpd.yml                                 //没有错误
         root@ms1~$>ansible-playbook /etc/ansible/httpd.yml                   //执行httpd.yml
    
             PLAY [client] ***************************************************************************
    
             TASK [Gathering Facts] ******************************************************************
             ok: [192.168.1.22]
             ok: [192.168.1.33]
    
             TASK [change port] **********************************************************************
             [WARNING]: Consider using template or lineinfile module rather than running sed
             附加:考虑使用模板或lineinfile模块,而不是运行sed
             changed: [192.168.1.33]
             changed: [192.168.1.22]
    
             RUNNING HANDLER [restart httpd server] **************************************************
             changed: [192.168.1.22]
             changed: [192.168.1.33]
    
             PLAY RECAP ******************************************************************************
             192.168.1.22               : ok=3    changed=2    unreachable=0    failed=0
             192.168.1.33               : ok=3    changed=2    unreachable=0    failed=0
         root@ms1~$>ansible client -m shell -a "netstat -lntp | grep httpd"
             192.168.1.33 | SUCCESS | rc=0 >>
             tcp6       0      0 :::8080                 :::*                    LISTEN      9430/httpd
    
             192.168.1.22 | SUCCESS | rc=0 >>
             tcp6       0      0 :::8080                 :::*                    LISTEN      17779/httpd
         http服务的端口变为了80
     3.角色
         将多种不同的tasks的文件集中的文件存储在某一个目录下,则该目录就是角色,角色一般存放在/etc/ansible/roles目录下,可通过ansible的配置文件来调整默认的角色目录./etc/ansible/roles目录下有很多的子目录,其中每一个子目录对应一个角色.每个角色也有自己的目录结构.
    
                                 /etc/ansible/roles(角色目录)
                                            |
         +-------------------+--------------+---------------+---------------+
         |                   |                              |               |
       FTP角色            apache角色                     mariadb角色       nginx角色
                                                            |
                                     +--------------+-------+--------+----------+
                                   files          tasks            handiers   templates
    
         /etc/ansible/roles/为角色集合,该目录下有自定义的各个子目录
         1.mariadb: MySQL角色
         2.apache:  httpd角色
         3.nginx:   nginx角色
         
         每个角色的定义,以特定的层级目录结构进行组织,以mariadb(mysql角色)为例
         1.files:存放copy或script等模块调用的文件
         2.templates:存放template模块查找所需要的模板文件的目录,如mysql配置文件等模板
         3.tasks:任务存放目录
         4.handlers:存放相关触发器执行器的目录
         5.vars:变量存放的目录
         6.meta:用于存放此角色云数据
         7.default:默认变量存放目录,文件中定义了此角色使用的默认变量
    
         上述目录tasks,handlkers,vars,meta,drfault至少包含一个main.yml,该目录下也可以有其他的yaml文件,但需要在manin.yml文件中用include指定将其他.yml文件包含进来.
         
         有了角色之后,可以直接在yaml文件中(playbook配置文件)中调用角色,示例如下
             - hosts: test01
               remote_user: root 
               roles:
                 - mysql     //调用角色名
                 - httpd     //调用角色名
         可以只调用一个角色,也可以调用多个角色,当定义了角色后,用ansible-playbook playbook文件执行即可,此时ansible会到角色集合的目录下(/etc/ansible/roles)去找MySQL和httpd目录,然后依次运行mysql目录和httpd目录下的代码.
    
         实验案例
           配置数据库角色
             root@ansible~$>mkdir -pv /etc/ansible/roles/mariadb/{files,tasks,handlers}  //创建需要的文件,路径注意不要写错
             root@ansible~$>vim /etc/ansible/mariadb.yml
              ---                                                                                 - hosts: client                                                                       remote_user: root                                                                   roles:                                                                                - mariadb                                                                 
              ...   
             root@ansible~$>ls /etc/ansible/roles/mariadb/
                 files  handlers  tasks
             root@ansible~$>vim /etc/ansible/roles/mariadb/tasks/main.yml
                 ---
                 - name: install mariadb
                 yum: name=mariadb-server state=present
                 - name: move config file
                 shell: "[ -e /etc/my.cof] && mv /etc/my.cnf /etc/my.cnf.bak"
                 - name: provide a new config file
                 copy: src=my.cnf dest=/etc/my.cnf
                 - name: roload mariadb
                 service: name=mariadb state=started
                 - name: create database testdb
                 shell: mysql -uroot -e "create database testdb;grant all privileges on testdb.* to 'test'@'192.168.1.%' identifi ed by '123456'; flush privileges;"
                 notify:
                 - restart mariadb                                                 
             root@ansible~$>vim /etc/ansible/roles/mariadb/handlers/main.yml    
                 ---   
                 - name: restart mariadb                                                          
                   service: name=mariadb state=restarted                                          
                 ...      
             root@ansible~$>cp /etc/my.cnf /etc/ansible/roles/mariadb/files/
                 /etc/ansible/
                 ├── ansible.cfg
                 ├── hosts
                 ├── hosts.bak
                 ├── mariadb.yml
                 └── roles
                     └── mariadb
                         ├── files
                         │   └── my.cnf
                         ├── handlers
                         │   └── main.yml
                         └── tasks
                             └── main.yml
                 5 directories, 7 files
             以下这些是我们需要的文件
                 ├── mariadb.yml
                 └── roles
                     └── mariadb
                         ├── files
                         │   └── my.cnf
                         ├── handlers
                         │   └── main.yml
                         └── tasks
                             └── main.yml
             预执行
             root@ansible/etc/ansible/roles$>ansible-playbook -C /etc/ansible/mariadb.yml
    
                 PLAY [client] ***************************************************************************
    
                 TASK [Gathering Facts] ******************************************************************
                 ok: [192.168.1.22]
                 ok: [192.168.1.33]
    
                 TASK [mariadb : install mariadb] ********************************************************
                 changed: [192.168.1.22]
                 changed: [192.168.1.33]
    
                 TASK [mariadb : move config file] *******************************************************
                 skipping: [192.168.1.33]
                 skipping: [192.168.1.22]
    
                 TASK [mariadb : provide a new config file] **********************************************
                 ok: [192.168.1.33]
                 ok: [192.168.1.22]
    
                 TASK [mariadb : roload mariadb] *********************************************************
                 changed: [192.168.1.33]
                 changed: [192.168.1.22]
    
                 TASK [mariadb : create database testdb] *************************************************
                 skipping: [192.168.1.22]
                 skipping: [192.168.1.33]
    
                 PLAY RECAP ******************************************************************************
                 192.168.1.22               : ok=4    changed=2    unreachable=0    failed=0
                 192.168.1.33               : ok=4    changed=2    unreachable=0    failed=0
             没有问题可以自己执行以下试试
     4.变量
         (1).在playbook中使用自定义变量
             root@ansible/etc/ansible/roles$>vim /etc/ansible/test.vars.yml
                 ---
                 - hosts: all
                 vars:                   //定义变量
                 - names: "cloud"        //第一个name变量
                   age: "3"              //第二个变量
                 tasks:
                 - name: "{{ names }}"   //{{}}两对大括号引用变量,变量名两头空格
                     shell: echo "myname {{ names }},myage {{ age }}"
                     register: var_result
                 - debug: var=var_result
                 ...
             引用变量需要在双引号中使用
             root@ansible/etc/ansible/roles$>ansible-playbook /etc/ansible/test.vars.yml
    
                 PLAY [all] ******************************************************************************
    
                 TASK [Gathering Facts] ******************************************************************
                 ok: [192.168.1.22]
                 ok: [192.168.1.33]
    
                 TASK [cloud] ****************************************************************************
                 changed: [192.168.1.33]
                 changed: [192.168.1.22]
    
                 TASK [debug] ****************************************************************************
                 ok: [192.168.1.22] => {
                     "var_result": {
                         "changed": true,
                         "cmd": "echo \"myname cloud,myage 3\"",
                         "delta": "0:00:00.004182",
                         "end": "2019-10-30 03:12:59.549906",
                         "failed": false,
                         "rc": 0,
                         "start": "2019-10-30 03:12:59.545724",
                         "stderr": "",
                         "stderr_lines": [],
                         "stdout": "myname cloud,myage 3",
                         "stdout_lines": [
                             "myname cloud,myage 3"
                         ]
                     }
                 }
                 ok: [192.168.1.33] => {
                     "var_result": {
                         "changed": true,
                         "cmd": "echo \"myname cloud,myage 3\"",
                         "delta": "0:00:00.006277",
                         "end": "2019-10-30 03:12:59.540761",
                         "failed": false,
                         "rc": 0,
                         "start": "2019-10-30 03:12:59.534484",
                         "stderr": "",
                         "stderr_lines": [],
                         "stdout": "myname cloud,myage 3",
                         "stdout_lines": [
                             "myname cloud,myage 3"
                         ]
                     }
                 }
    
                 PLAY RECAP ******************************************************************************
                 192.168.1.22               : ok=3    changed=1    unreachable=0    failed=0
                 192.168.1.33               : ok=3    changed=1    unreachable=0    failed=0
         (2).在playbook中使用内置变量
            使用ansible all -m setup | more查看ansible内置变量
           root@ansible~$>vim /etc/ansible/test.setupvars.ymlcd
             ---
             - hosts: all                                                                          gather_facts: True                                                                
               tasks:                                                                            
               - name: setup var                                                                 
                 shell: echo "ip {{ ansible_all_ipv4_addresses }} cpu {{ ansible_processor_count }}"     
                 register: var_result                                                          
               - debug: var=var_result                                                           
             ...       
           root@ansible/etc/ansible/roles$>ansible-playbook /etc/ansible/test.setupvars.yml
    
             PLAY [all] ******************************************************************************
    
             TASK [Gathering Facts] ******************************************************************
             ok: [192.168.1.22]
             ok: [192.168.1.33]
    
             TASK [setup var] ************************************************************************
             changed: [192.168.1.22]
             changed: [192.168.1.33]
    
             TASK [debug] ****************************************************************************
             ok: [192.168.1.22] => {
                 "var_result": {
                     "changed": true,
                     "cmd": "echo \"ip [u'192.168.1.22', u'192.168.242.129', u'192.168.122.1'] cpu 1\"",
                     "delta": "0:00:00.004165",
                     "end": "2019-10-30 03:23:05.562660",
                     "failed": false,
                     "rc": 0,
                     "start": "2019-10-30 03:23:05.558495",
                     "stderr": "",
                     "stderr_lines": [],
                     "stdout": "ip [u'192.168.1.22', u'192.168.242.129', u'192.168.122.1'] cpu 1",
                     "stdout_lines": [
                         "ip [u'192.168.1.22', u'192.168.242.129', u'192.168.122.1'] cpu 1"
                     ]
                 }
             }
             ok: [192.168.1.33] => {
                 "var_result": {
                     "changed": true,
                     "cmd": "echo \"ip [u'192.168.242.130', u'192.168.1.33', u'192.168.122.1'] cpu 1\"",
                     "delta": "0:00:00.004659",
                     "end": "2019-10-30 03:23:05.566662",
                     "failed": false,
                     "rc": 0,
                     "start": "2019-10-30 03:23:05.562003",
                     "stderr": "",
                     "stderr_lines": [],
                     "stdout": "ip [u'192.168.242.130', u'192.168.1.33', u'192.168.122.1'] cpu 1",
                     "stdout_lines": [
                         "ip [u'192.168.242.130', u'192.168.1.33', u'192.168.122.1'] cpu 1"
                     ]
                 }
             }
    
             PLAY RECAP ******************************************************************************
             192.168.1.22               : ok=3    changed=1    unreachable=0    failed=0
             192.168.1.33               : ok=3    changed=1    unreachable=0    failed=0    
     5.模板
         配置文件如果使用copy模板去下发的话,那配置都是一样的; 如果下发的配置文件里有可变的配置,需要用到template模板.
    
         实验案例
           1.下发可变配置变量
             root@ansible~$>cat /etc/ansible/filevars.yml
                 ---
                 - hosts: all
                 gather_facts: True          //开启系统变量
                 vars:
                 - myname: "cloud"           //自定义变量
                 tasks:
                 - name: template test
                     template: src=/root/test dest=/root/test
                 ...
             root@ansible~$>cat  /root/test
                 my name is {{ myname }}
                 my name is {{ ansible_all_ipv4_addresses[1] }}
             root@ansible~$>ansible-playbook /etc/ansible/filevars.yml
    
                 PLAY [all] ******************************************************************************
    
                 TASK [Gathering Facts] ******************************************************************
                 ok: [192.168.1.22]
                 ok: [192.168.1.33]
    
                 TASK [template test] ********************************************************************
                 changed: [192.168.1.33]
                 changed: [192.168.1.22]
    
                 PLAY RECAP ******************************************************************************
                 192.168.1.22               : ok=2    changed=1    unreachable=0    failed=0
                 192.168.1.33               : ok=2    changed=1    unreachable=0    failed=0
             root@ansible~$>ansible client -m raw -a "cat /root/test"
                 192.168.1.22 | SUCCESS | rc=0 >>
                 my name is cloud
                 my name is 192.168.242.129
                 Shared connection to 192.168.1.22 closed.
    
                 192.168.1.33 | SUCCESS | rc=0 >>
                 my name is cloud
                 my name is 192.168.1.33
                 Shared connection to 192.168.1.33 closed.
           2.下发配置文件里面使用判断语句
             root@ansible~$>cat /root/if.j2
                 {% if PORT %}               //if PORT存在
                 ip=0.0.0.0:{{ PORT }}
                 {% else %}                  //否则的话
                 ip=0.0.0.0:80
                 {% endif %}                 //结尾
             root@ansible~$>cat /etc/ansible/test_ifvars.yml
                 ---
                 - hosts: all
                 gather_facts: True
                 vars:
                 - PORT: 90
                 tasks:
                 - name: jinja2 if test
                     template: src=/root/if.j2 dest=/root/test
                 ...
             root@ansible~$>ansible-playbook /etc/ansible/test_ifvars.yml
    
                 PLAY [all] ******************************************************************************
    
                 TASK [Gathering Facts] ******************************************************************
                 ok: [192.168.1.22]
                 ok: [192.168.1.33]
    
                 TASK [jinja2 if test] *******************************************************************
                 changed: [192.168.1.33]
                 changed: [192.168.1.22]
    
                 PLAY RECAP ******************************************************************************
                 192.168.1.22               : ok=2    changed=1    unreachable=0    failed=0
                 192.168.1.33               : ok=2    changed=1    unreachable=0    failed=0
             root@ansible~$>ansible client -m raw -a 'cat /root/test'
                 192.168.1.22 | SUCCESS | rc=0 >>
                 ip=0.0.0.0:90
    
                 Shared connection to 192.168.1.22 closed.
    
                 192.168.1.33 | SUCCESS | rc=0 >>
                 ip=0.0.0.0:90
    
                 Shared connection to 192.168.1.33 closed.
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值