目录

简介

ansible是自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:

(1)、连接插件connection plugins:负责和被监控端实现通信;

(2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;

(3)、各种模块核心模块、command模块、自定义模块;

(4)、借助于插件完成记录日志邮件等功能;

(5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。

ansible架构图

 上图中我们看到的主要模块如下:

Ansible:Ansible核心程序。
HostInventory:记录由Ansible管理的主机信息,包括端口、密码、ip等。
Playbooks:“剧本”YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能。
CoreModules:核心模块,主要操作是通过调用核心模块来完成管理任务。
CustomModules:自定义模块,完成核心模块无法完成的功能,支持多种语言。
ConnectionPlugins:连接插件,Ansible和Host通信使用

ansible 任务执行模式

Ansible 系统由控制主机对被管节点的操作方式可分为两类,即adhocplaybook

  • ad-hoc模式(点对点模式),测试用
      使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell。
  • playbook模式(剧本模式)
      是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。

ansible执行流程

简单理解就是Ansible在运行时, 首先读取ansible.cfg中的配置, 根据规则获取Inventory中的管理主机列表, 并行的在这些主机中执行配置的任务, 最后等待执行返回的结果。

ansible 命令执行过程

  1. 加载自己的配置文件,默认/etc/ansible/ansible.cfg
  2. 查找对应的主机配置文件,找到要执行的主机或者组;
  3. 加载自己对应的模块文件,如 command;
  4. 通过ansible将模块或命令生成对应的临时py文件(python脚本), 并将该文件传输至远程服务器;
  5. 对应执行用户的家目录的.ansible/tmp/XXX/XXX.PY文件;
  6. 给文件 +x 执行权限;
  7. 执行并返回结果;
  8. 删除临时py文件,sleep 0退出;

ansible 配置详解

ansible 安装方式

  ansible安装常用两种方式,yum安装pip程序安装。下面我们来详细介绍一下这两种安装方式。

使用 pip(python的包管理模块)安装

  首先,我们需要安装一个python-pip包,安装完成以后,则直接使用pip命令来安装我们的包,具体操作过程如下:

 yum install python-pippip install ansible

使用 yum 安装

  yum 安装是我们很熟悉的安装方式了。我们需要先安装一个epel-release包,然后再安装我们的 ansible 即可。

 yum install epel-release -yyum install ansible –y

ansible 程序结构

安装目录如下(yum安装):
  配置文件目录:/etc/ansible/
  执行文件目录:/usr/bin/
  Lib库依赖目录:/usr/lib/pythonX.X/site-packages/ansible/
  Help文档目录:/usr/share/doc/ansible-X.X.X/
  Man文档目录:/usr/share/man/man1/

/etc/ansible
/etc/ansible/ansible.cfg
/etc/ansible/hosts
/etc/ansible/roles
/usr/bin/ansible
/usr/bin/ansible-2
/usr/bin/ansible-2.7
/usr/bin/ansible-config
/usr/bin/ansible-connection
/usr/bin/ansible-console
/usr/bin/ansible-console-2
/usr/bin/ansible-console-2.7
/usr/bin/ansible-doc
/usr/bin/ansible-doc-2
/usr/bin/ansible-doc-2.7
/usr/bin/ansible-galaxy
/usr/bin/ansible-galaxy-2
/usr/bin/ansible-galaxy-2.7
/usr/bin/ansible-inventory
/usr/bin/ansible-playbook
/usr/bin/ansible-playbook-2
/usr/bin/ansible-playbook-2.7
/usr/bin/ansible-pull
/usr/bin/ansible-pull-2
/usr/bin/ansible-pull-2.7
/usr/bin/ansible-vault
/usr/bin/ansible-vault-2
/usr/bin/ansible-vault-2.7

ansible配置文件查找顺序

  ansible与我们其他的服务在这一点上有很大不同,这里的配置文件查找是从多个地方找的,顺序如下:

  1. 检查环境变量ANSIBLE_CONFIG指向的路径文件(export ANSIBLE_CONFIG=/etc/ansible.cfg);
  2. ~/.ansible.cfg,检查当前目录下的ansible.cfg配置文件;
  3. /etc/ansible.cfg检查etc目录的配置文件。

配置文件

  1. /etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
  2. /etc/ansible/hosts  主机清单
  3. /etc/ansible/roles/  存放角色的目录
程序:/usr/bin/ansible 主程序,临时命令执行工具/usr/bin/ansible-doc 查看配置文档,模块功能查看工具/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具。/usr/bin/ansible-vault 文件加密工具/usr/bin/ansible-console 基于console界面与用户交互的执行工具

ansible配置文件

  ansible 的配置文件为/etc/ansible/ansible.cfg,ansible 有许多参数,下面我们列出一些常见的参数:

inventory = /etc/ansible/hosts #这个参数表示资源清单inventory文件的位置library = /usr/share/ansible #指向存放Ansible模块的目录,支持多个目录方式,只要用冒号(:)隔开就可以forks = 5 #并发连接数,默认为5
remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录sudo_user = root #设置默认执行命令的用户remote_port = 22 #指定连接被管节点的管理端口,默认为22端口,建议修改,能够更加安全host_key_checking = False #设置是否检查SSH主机的密钥,值为True/False。关闭后第一次连接不会提示配置实例timeout = 60 #设置SSH连接的超时时间,单位为秒log_path = /var/log/ansible.log #指定一个存储ansible日志的文件(默认不记录日志)

ansuble主机清单

  在配置文件中,我们提到了资源清单,这个清单就是我们的主机清单,里面保存的是一些 ansible 需要连接管理的主机列表。我们可以来看看他的定义方式:

1、 直接指明主机地址或主机名:## green.example.com## blue.example.com## 192.168.100.1# 192.168.100.10
2、 定义一个主机组[组名]把地址或主机名加进去[mysql_test]192.168.253.159192.168.253.160192.168.253.153

  需要注意的是,这里的组成员可以使用通配符来匹配,这样对于一些标准化的管理来说就很轻松方便了。
  我们可以根据实际情况来配置我们的主机列表,具体操作如下:

[root@server ~]# vim /etc/ansible/hosts[web]192.168.37.122192.168.37.133

ansible 常用命令

ansible 命令集

/usr/bin/ansible  Ansibe AD-Hoc 临时命令执行工具,常用于临时命令的执行
/usr/bin/ansible-doc   Ansible 模块功能查看工具
/usr/bin/ansible-galaxy  下载/上传优秀代码或Roles模块 的官网平台,基于网络的
/usr/bin/ansible-playbook  Ansible 定制自动化的任务集编排工具
/usr/bin/ansible-pull  Ansible远程执行命令的工具,拉取配置而非推送配置(使用较少,海量机器时使用,对运维的架构能力要求较高)
/usr/bin/ansible-vault  Ansible 文件加密工具
/usr/bin/ansible-console  Ansible基于Linux Consoble界面可与用户交互的命令执行工具

ansible-doc 命令

  ansible-doc 命令常用于获取模块信息及其使用帮助,一般用法如下:

 ansible-doc -l              #获取全部模块的信息ansible-doc -s MOD_NAME       #获取指定模块的使用帮助

  我们也可以查看一下ansible-doc的全部用法:

[root@server ~]# ansible-doc
Usage: ansible-doc [options] [module...]Options:-h, --help            show this help message and exit  # 显示命令参数API文档-l, --list            List available modules  #列出可用的模块-M MODULE_PATH, --module-path=MODULE_PATH  #指定模块的路径specify path(s) to module library (default=None)-s, --snippet         Show playbook snippet for specified module(s)  #显示playbook制定模块的用法-v, --verbose         verbose mode (-vvv for more, -vvvv to enable  # 显示ansible-doc的版本号查看模块列表:connection debugging)--version             show program's version number and exit

  我们可以来看一下,以mysql相关的为例:

[root@server ~]# ansible-doc -l |grep mysql
mysql_db                           Add or remove MySQL databases from a remote...
mysql_replication                  Manage MySQL replication
mysql_user                         Adds or removes a user from a MySQL databas...
mysql_variables                    Manage MySQL global variables
[root@server ~]# ansible-doc -s mysql_user

ansible 命令详解

  命令的具体格式如下:

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

  也可以通过ansible -h来查看帮助,下面我们列出一些比较常用的选项,并解释其含义:

-a MODULE_ARGS   #模块的参数,如果执行默认COMMAND的模块,即是命令参数,如: “date”,“pwd”等等
-k,--ask-pass #ask for SSH password。登录密码,提示输入SSH密码而不是假设基于密钥的验证
--ask-su-pass #ask for su password。su切换密码
-K,--ask-sudo-pass #ask for sudo password。提示密码使用sudo,sudo表示提权操作
--ask-vault-pass #ask for vault password。假设我们设定了加密的密码,则用该选项进行访问
-B SECONDS #后台运行超时时间
-C #模拟运行环境并进行预运行,可以进行查错测试
-c CONNECTION #连接类型使用
-f FORKS #并行任务数,默认为5
-i INVENTORY #指定主机清单的路径,默认为/etc/ansible/hosts
--list-hosts #查看有哪些主机组
-m MODULE_NAME #执行模块的名字,默认使用 command 模块,所以如果是只执行单一命令可以不用 -m参数
-o #压缩输出,尝试将所有结果在一行输出,一般针对收集工具使用
-S #用 su 命令
-R SU_USER #指定 su 的用户,默认为 root 用户
-s #用 sudo 命令
-U SUDO_USER #指定 sudo 到哪个用户,默认为 root 用户
-T TIMEOUT #指定 ssh 默认超时时间,默认为10s,也可在配置文件中修改
-u REMOTE_USER #远程用户,默认为 root 用户
-v #查看详细信息,同时支持-vvv,-vvvv可查看更详细信息

ansible 配置公私钥

  上面我们已经提到过 ansible 是基于 ssh 协议实现的,所以其配置公私钥的方式与 ssh 协议的方式相同,具体操作步骤如下:

#1.生成私钥
[root@server ~]# ssh-keygen
#2.向主机分发私钥
[root@server ~]# ssh-copy-id root@192.168.37.122
[root@server ~]# ssh-copy-id yzg@192.168.37.133

  这样的话,就可以实现无密码登录,我们的实验过程也会顺畅很多。
  注意,如果出现了一下报错:

 -bash: ssh-copy-id: command not found

  那么就证明我们需要安装一个包:

 yum -y install openssh-clientsansible

  把包安装上即可。

ansible 常用模块

1)主机连通性测试

  我们使用ansible web -m ping命令来进行主机连通性测试,效果如下:

[root@ansible ~]# ansible dbserver -m ping
192.168.245.129 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": false, "ping": "pong"
}

  这样就说明我们的主机是连通状态的。接下来的操作才可以正常进行。

这里的ping模块不是走的ICMP协议,可以打开关闭ICMP协议测试

关闭ICMP协议(echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all)

打开ICMP协议(echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all)

2)command 模块

  这个模块可以直接在远程主机上执行命令,并将结果返回本主机。
  举例如下:

[root@ansible ~]# ansible web -m command -a "ss -ntl"
192.168.245.130 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128          *:22                       *:*
LISTEN     0      100    127.0.0.1:25                       *:*
LISTEN     0      128       [::]:22                    [::]:*
LISTEN     0      100      [::1]:25                    [::]:*  

  命令模块接受命令名称,后面是空格分隔的列表参数。给定的命令将在所有选定的节点上执行。它不会通过shell进行处理,比如$HOME和操作如"<",">","|",";","&" 工作(需要使用(shell)模块实现这些功能)。注意,该命令不支持| 管道命令
  下面来看一看该模块下常用的几个命令:

chdir       # 在执行命令之前,先切换到该目录
executable             # 切换shell来执行命令,需要使用命令的绝对路径
free_form            # 要执行的Linux指令,一般使用Ansible的-a参数代替。
creates                # 一个文件名,当这个文件存在,则该命令不执行,可以用来做判断,不存在则执行
removes                 # 一个文件名,这个文件不存在,则该命令不执行,存在则执行。

  下面我们来看看这些命令的执行效果:

[root@ansible ~]# ansible web -m command -a "chdir=/tmp/ ls"
192.168.245.131 | CHANGED | rc=0 >>
ansible_command_payload_zKgszH
[root@ansible ~]# ansible web -m command -a "creates=/etc/fstab touch /etc/fstab"
192.168.245.132 | SUCCESS | rc=0 >>
skipped, since /etc/fstab exists
[root@ansible ~]# ansible web -m command -a "creates=/etc/fstabtest touch /etc/fstabtest"
rid of this message.
192.168.245.131 | CHANGED | rc=0 >>[root@ansible ~]# ansible web -m command -a "ls -l /etc/fstabtest"
192.168.245.131 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 12月  7 01:38 /etc/fstabtest
[root@ansible ~]# ansible web -m command -a "removes=/etc/fstab cat  /etc/fstab"
192.168.245.133 | CHANGED | rc=0 >>#
# /etc/fstab
# Created by anaconda on Tue Nov 23 21:29:45 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=bad63c62-92c6-49ff-9040-28dbc52d1c23 /boot                   xfs     defaults        0 0
/dev/mapper/centos-home /home                   xfs     defaults        0 0
/dev/mapper/centos-var  /var                    xfs     defaults        0 0

3)shell 模块

  shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等。

[root@server ~]# ansible web -m shell -a 'cat /etc/passwd |grep "keer"'
192.168.37.122 | SUCCESS | rc=0 >>
keer:x:10001:1000:keer:/home/keer:/bin/sh192.168.37.133 | SUCCESS | rc=0 >>
keer:x:10001:10001::/home/keer:/bin/sh

4)copy 模块

  这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限等。
  其相关选项如下:

src    #被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于"rsync"
content   #用于替换"src",可以直接指定文件的值
dest    #必选项,将源文件复制到的远程主机的绝对路径
backup   #当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode    #递归设定目录的权限,默认为系统默认权限
force    #当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others    #所有的 file 模块中的选项可以在这里使用

用法举例如下:
① 复制文件:

[root@ansible tmp]# ansible web -m copy -a 'src=/tmp/lsblk.sh dest=/tmp/'
192.168.245.131 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "checksum": "e1655e430bc0d0bb97dea7e9a7ea8711786279f6", "dest": "/tmp/lsblk.sh", "gid": 0, "group": "root", "md5sum": "531c25d2ad160eaa4fb01e0cc91a5c97", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 37, "src": "/root/.ansible/tmp/ansible-tmp-1638814130.7-78317-182378212980552/source", "state": "file", "uid": 0
}

② 给定内容生成文件,并制定权限,(如果文件存在则直接覆盖)

[root@ansible tmp]# ansible web -m copy -a 'content="I an keer \n" dest=/tmp/lsblk.sh
mode=600 owner=usertest'
192.168.245.132 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "checksum": "62c6cfacc06b9cb29635c49dfee4cc6d6e8088e6", "dest": "/tmp/lsblk.sh", "gid": 0, "group": "root", "md5sum": "dad17665841753e7c8ea7fc32f40e467", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:admin_home_t:s0", "size": 11, "src": "/root/.ansible/tmp/ansible-tmp-1638814262.52-80986-149502365496099/source", "state": "file", "uid": 0
}

③ 关于覆盖
  我们把文件的内容修改一下,然后选择覆盖备份:

[root@server ~]# ansible web -m copy -a 'content="I am keerya\n" backup=yes dest=/data/name mode=666'
192.168.37.122 | SUCCESS => {"backup_file": "/data/name.4394.2017-12-06@09:46:25~", "changed": true, "checksum": "064a68908ab9971ee85dbc08ea038387598e3778", "dest": "/data/name", "gid": 0, "group": "root", "md5sum": "8ca7c11385856155af52e560f608891c", "mode": "0666", "owner": "root", "size": 12, "src": "/root/.ansible/tmp/ansible-tmp-1512438383.78-228128616784888/source", "state": "file", "uid": 0
}

5)file 模块

  该模块主要用于设置文件的属性,比如创建文件、创建链接文件、删除文件等。
  下面是一些常见的命令:

force  #需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group  #定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限
owner  #定义文件/目录的属主。后面必须跟上path:定义文件/目录的路径
recurse  #递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况
dest  #被链接到的路径,只应用于state=link的情况
state  #状态,有以下选项:directory:如果目录不存在,就创建目录
file:即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent:删除目录、文件或者取消链接文件

  用法举例如下:
 创建文件:

# 创建文件
# ansible web -m file -a 'path=/tmp/testfile state=touch mode=600 owner=yzg'
# 创建链接
# ansible web -m file -a 'src=/tmp/testfile path=/tmp/testfile-link state=link'
# 创建文件夹
# ansible web -m file -a 'path=/tmp/dir1 state=directory'
# 删除文件
# ansible web -m file -a 'path=/tmp/testfile state=absent'
# 删除目录
# ansible web -m file -a 'path=/tmp/ state=absent'

6)fetch 模块

  该模块用于从远程某主机获取(复制)文件到本地。
  有两个选项:

dest:用来存放文件的目录
src:在远程拉取的文件,并且必须是一个file,不能是目录

  具体举例如下:

[root@ansible tmp]# ansible all -m fetch -a 'src=/tmp/lsblk.sh dest=/tmp/'
192.168.245.132 | CHANGED => {"changed": true, "checksum": "62c6cfacc06b9cb29635c49dfee4cc6d6e8088e6", "dest": "/tmp/192.168.245.132/tmp/lsblk.sh", "md5sum": "dad17665841753e7c8ea7fc32f40e467", "remote_checksum": "62c6cfacc06b9cb29635c49dfee4cc6d6e8088e6", "remote_md5sum": null
}

  我们可以在本机上查看一下文件是否复制成功。要注意,文件保存的路径是我们设置的接收目录下的被管制主机ip目录下:

[root@ansible tmp]# tree .
.
├── 192.168.245.130
│   └── tmp
│       └── lsblk.sh

7)cron 模块

  该模块适用于管理cron计划任务的。
  其使用的语法跟我们的crontab文件中的语法一致,同时,可以指定以下选项:

day= #日应该运行的工作( 1-31, *, */2, )
hour= # 小时 ( 0-23, *, */2, )
minute= #分钟( 0-59, *, */2, )
month= # 月( 1-12, *, /2, )
weekday= # 周 ( 0-6 for Sunday-Saturday,, )
job= #指明运行的命令是什么
name= #定时任务描述
reboot # 任务在重启时运行,不建议使用,建议使用special_time
special_time #特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
state #指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user # 以哪个用户的身份执行

  举例如下:
① 添加计划任务

[root@ansible tmp]# ansible centos8 -m cron -a 'minute=*/5 weekday=0,6 job="/usr/bin/wall cron job " name=testcron'
192.168.245.129 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "envs": [], "jobs": ["testcron"]
}
[root@ansible tmp]# ansible centos8 -m shell -a 'crontab -l'
192.168.245.129 | CHANGED | rc=0 >>
#Ansible: testcron
*/5 * * * 0,6 /usr/bin/wall cron job 

② 删除计划任务  如果我们的计划任务添加错误,想要删除的话,则执行以下操作:首先我们查看一下现有的计划任务:

[root@ansible tmp]# ansible centos8 -m shell -a 'crontab -l'
192.168.245.129 | CHANGED | rc=0 >>
#Ansible: testcron
#*/5 * * * 0,6 /usr/bin/wall cron job
# state=absent  删除掉计划任务
# disabled=true 注释掉计划任务,true /false yes/no
[root@ansible tmp]# ansible centos8 -m cron -a 'state=absent minute=*/5 weekday=0,6 job="/usr/bin/wall cron job " name=testcron'192.168.245.129 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "envs": [], "jobs": ["testcron"]
}
[root@ansible tmp]# ansible centos8 -m shell -a 'crontab -l'
192.168.245.129 | CHANGED | rc=0 >>
#Ansible: testcron
#*/5 * * * 0,6 /usr/bin/wall cron job 

[root@ansible tmp]# ansible centos8 -m cron -a 'disabled=true minute=*/5 weekday=0,6 job="/usr/bin/wall cron job " name=testcron'
192.168.245.129 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "envs": [], "jobs": ["testcron"]
}
[root@ansible tmp]# ansible centos8 -m shell -a 'crontab -l'
192.168.245.129 | CHANGED | rc=0 >>
#Ansible: testcron
#*/5 * * * 0,6 /usr/bin/wall cron job 

8)yum 模块

  顾名思义,该模块主要用于软件的安装。
  其选项如下:

name=  #所安装的包的名称
state=  #present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache=yes  #强制更新yum的缓存
conf_file  #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check=  #是否禁止GPG checking,只用于presentor latest。yes or no
disablerepo  #临时禁止使用yum库。 只用于安装或更新时。
enablerepo  #临时使用的yum库。只用于安装或更新时。

  下面我们就来安装一个包试试看:

# 安装软件包
[root@ansible ~]# ansible web -m yum -a 'name=dstat state=present'
192.168.245.133 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "changes": {"installed": ["dstat"]}, "msg": "", "rc": 0, "results": ["Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.ustc.edu.cn\n * extras: mirrors.ustc.edu.cn\n * updates: mirrors.163.com\nResolving Dependencies\n--> Running transaction check\n---> Package dstat.noarch 0:0.7.2-12.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package         Arch             Version                  Repository      Size\n================================================================================\nInstalling:\n dstat           noarch           0.7.2-12.el7             base           163 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 163 k\nInstalled size: 752 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : dstat-0.7.2-12.el7.noarch                                    1/1 \n  Verifying  : dstat-0.7.2-12.el7.noarch                                    1/1 \n\nInstalled:\n  dstat.noarch 0:0.7.2-12.el7                                                   \n\nComplete!\n"]
}
# 删除软件包
[root@ansible ~]# ansible web -m yum -a 'name=dstat state=absent'
192.168.245.130 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "changes": {"removed": ["dstat"]}, "msg": "", "rc": 0, "results": ["已加载插件:fastestmirror\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 dstat.noarch.0.0.7.2-12.el7 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package         架构             版本                    源               大小\n================================================================================\n正在删除:\n dstat           noarch           0.7.2-12.el7            @base           752 k\n\n事务概要\n================================================================================\n移除  1 软件包\n\n安装大小:752 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  正在删除    : dstat-0.7.2-12.el7.noarch                                   1/1 \n  验证中      : dstat-0.7.2-12.el7.noarch                                   1/1 \n\n删除:\n  dstat.noarch 0:0.7.2-12.el7                                                   \n\n完毕!\n"]
}
# 查看是否安装
[root@ansible ~]# ansible web -m shell -a 'rpm -q dstat'
192.168.245.132 | FAILED | rc=1 >>
未安装软件包 dstat non-zero return code
192.168.245.131 | FAILED | rc=1 >>
未安装软件包 dstat non-zero return code
192.168.245.130 | FAILED | rc=1 >>
未安装软件包 dstat non-zero return code
192.168.245.133 | FAILED | rc=1 >>
未安装软件包 dstat non-zero return code

9)service 模块

  该模块用于服务程序的管理。
  其主要选项如下:

arguments #命令行提供额外的参数
enabled #设置开机启动。
name= #服务名称
runlevel #开机启动的级别,一般不用指定。
sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state #有四种状态,分别为:started--->启动服务, stopped--->停止服务, restarted--->重启服务, reloaded--->重载配置

  下面是一些例子:
① 开启服务并设置自启动

# 启动服务
[root@ansible ~]# ansible web -m service -a 'name=httpd state=started enabled=true'
192.168.245.130 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"},
...
# 查看服务是否启动
[root@ansible ~]# ansible web -m shell -a 'ss -ntl '
192.168.245.131 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128          *:22                       *:*
LISTEN     0      100    127.0.0.1:25                       *:*
LISTEN     0      128       [::]:80                    [::]:*
LISTEN     0      128       [::]:22                    [::]:*
LISTEN     0      100      [::1]:25                    [::]:*              

② 关闭服务

# 关闭服务
[root@ansible ~]# ansible web -m service -a 'name=httpd state=stopped'
192.168.245.133 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"},
...
# 查看端口
[root@ansible ~]# ansible web -m shell -a 'ss -ntl'
192.168.245.131 | CHANGED | rc=0 >>
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
LISTEN     0      128          *:22                       *:*
LISTEN     0      100    127.0.0.1:25                       *:*
LISTEN     0      128       [::]:22                    [::]:*
LISTEN     0      100      [::1]:25                    [::]:*             

10)user 模块

  该模块主要是用来管理用户账号。
  其主要选项如下:

comment  # 用户的描述信息
createhome  # 是否创建家目录
force  # 在使用state=absent时, 行为与userdel –force一致.
group  # 指定基本组
groups  # 指定附加组,如果指定为(groups=)表示删除所有组
home  # 指定用户家目录
move_home  # 如果设置为home=时, 试图将用户主目录移动到指定的目录
name  # 指定用户名
non_unique  # 该选项允许改变非唯一的用户ID值
password  # 指定用户密码
remove  # 在使用state=absent时, 行为是与userdel –remove一致,会产出家目录
shell=  # 指定默认shell
state  # 设置帐号状态,不指定为创建,指定值为absent表示删除
system=yes  # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid  # 指定用户的uid

  举例如下:
① 添加一个用户并指定其 uid

# 创建用户
[root@ansible ~]# ansible web -m user -a 'name=test1 comment="testuser 1" uid=2000 home=/tmp/test1 group=yzg groups=root,bin'
192.168.245.132 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "testuser 1", "create_home": true, "group": 1000, "groups": "root,bin", "home": "/tmp/test1", "name": "test1", "shell": "/bin/bash", "state": "present", "system": false, "uid": 2000
}# 查看用户
[root@ansible ~]# ansible web -m shell -a 'getent passwd test1'
192.168.245.131 | CHANGED | rc=0 >>
test1:x:2000:1000:testuser 1:/tmp/test1:/bin/bash# 删除用户
[root@ansible ~]# ansible web -m user -a 'name=test1 state=absent'
192.168.245.130 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "force": false, "name": "test1", "remove": false, "state": "absent"
}

11)group 模块

  该模块主要用于添加或删除组。
  常用的选项如下:

gid=  #设置组的GID号
name=  #指定组的名称
state=  #指定组的状态,默认为创建,设置值为absent为删除
system=  #设置值为yes,表示创建为系统组

  举例如下:

# 创建组
[root@ansible ~]# ansible web -m group -a 'name=grouptest gid=1234'
192.168.245.130 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "gid": 1234, "name": "grouptest", "state": "present", "system": false
}# 查看组
[root@ansible ~]# ansible web -a 'getent group grouptest'
192.168.245.131 | CHANGED | rc=0 >>
grouptest:x:1234:# 删除组
[root@ansible ~]# ansible web -m group -a 'name=grouptest state=absent'
192.168.245.132 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "name": "grouptest", "state": "absent"
}

12)script 模块

  该模块用于将本机的脚本在被管理端的机器上运行。
  该模块直接指定脚本的路径即可,我们通过例子来看一看到底如何使用的:
  首先,我们写一个脚本,并给其加上执行权限:

[root@server ~]# vim /tmp/df.sh#!/bin/bashdate >> /tmp/disk_total.logdf -lh >> /tmp/disk_total.log
[root@server ~]# chmod +x /tmp/df.sh [root@server ~]# ansible web -m script -a '/tmp/df.sh'
192.168.37.122 | SUCCESS => {"changed": true, "rc": 0, "stderr": "Shared connection to 192.168.37.122 closed.\r\n", "stdout": "", "stdout_lines": []
}

13)setup 模块

  该模块主要用于收集信息,是通过调用facts组件来实现的。
  facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
  facts就是变量,内建变量 。每个主机的各种信息,cpu颗数、内存大小等。会存在facts中的某个变量中。调用后返回很多对应主机的信息,在后面的操作中可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。
① 查看信息
  我们可以直接用命令获取到变量的值,具体我们来看看例子:

# 查看所有变量
# ansible web -m setup -a
# ansible web -m setup -a  'filter=*hostname*'
# ansible web -m setup -a  'filter=ansible_hostname'
# 显示完整地主机名,如yzg-101.com.cn,ansible_hostname只显示yzg-101,ansible_nodename则可以显示完整主机名。
# ansible web -m setup -a  'filter=ansible_nodename'
# 显示完整地主机名
# ansible web -m setup -a  'filter=ansible_fqdn'
# 查看内存
[root@ansible ~]# ansible web -m setup -a 'filter="*mem*"'
192.168.245.130 | SUCCESS => {"ansible_facts": {"ansible_memfree_mb": 1521, "ansible_memory_mb": {"nocache": {"free": 1619, "used": 223}, "real": {"free": 1521, "total": 1842, "used": 321}, "swap": {"cached": 0, "free": 0, "total": 0, "used": 0}}, "ansible_memtotal_mb": 1842, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false
}

② 保存信息
  我们的setup模块还有一个很好用的功能就是可以保存我们所筛选的信息至我们的主机上,同时,文件名为我们被管制的主机的IP,这样方便我们知道是哪台机器出的问题。
  我们可以看一看例子:

# 结果保存到facts文件,方便查看
[root@ansible ~]# ansible web -m setup -a 'filter="*mem*"' --tree /tmp/facts
192.168.245.131 | SUCCESS => {"ansible_facts": {"ansible_memfree_mb": 1521, "ansible_memory_mb": {"nocache": {"free": 1621, "used": 221}, "real": {"free": 1521, "total": 1842, "used": 321}, "swap": {"cached": 0, "free": 0, "total": 0, "used": 0}}, "ansible_memtotal_mb": 1842, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false
}[root@ansible ~]# cat /tmp/facts/192.168.245.132
{"ansible_facts": {"ansible_memfree_mb": 1516, "ansible_memory_mb": {"nocache": {"free": 1616, "used": 226}, "real": {"free": 1516, "total": 1842, "used": 326}, "swap": {"cached": 0, "free": 0, "total": 0, "used": 0}}, "ansible_memtotal_mb": 1842, "discovered_interpreter_python": "/usr/bin/python"}, "changed": false}

下载角色

ansible-galaxy

ansible-galaxy collection install nginxinc.nginx_core

ansible-galaxy install geerlingguy.nginx

Ansible-vault

功能:管理加密解密yml文件

ansible-vault [create|decrypt|edit|encrypt|rekey|view]

# 加密yml文件
ansible-vault encrypt hello.yml
# 解密
ansible-vault decrypt hello.yml
# 查看
ansible-vault view hello.yml
# 编辑加密文件
ansible-vault edit hello.yml
# 修改口令
ansible-vault rekey hello.yml
# 创建新文件
ansible-vault create new.yml 

Ansible-console:

2.0+新增,可交互执行命令,支持tab

root@test (2)[f:10] $ 执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$

设置并发数: forks n 例如: forks 10

切换组: cd 主机组 例如: cd web

列出当前组主机列表: list

列出所有的内置命令: ?或help

示例:

root@all (2)[f:5]$ list

root@all (2)[f:5]$ cd appsrvs

root@appsrvs (2)[f:5]$ list

root@appsrvs (2)[f:5]$ yum name=httpd state=present

root@appsrvs (2)[f:5]$ service name=httpd state=started

Ansible playbook格式

1)格式简介

  playbook由YMAL语言编写。YAML( /ˈjæməl/ )参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822,Clark Evans在2001年5月在首次发表了这种语言,另外Ingy döt Net与OrenBen-Kiki也是这语言的共同设计者。
  YMAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。首先学习了解一下YMAL的格式,对我们后面书写playbook很有帮助。以下为playbook常用到的YMAL格式:
  1、文件的第一行应该以 "---" (三个连字符)开始,表明YMAL文件的开始。
  2、在同一行中,#之后的内容表示注释,类似于shell,python和ruby。
  3、YMAL中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容。
  4、同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。
  5、play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以":"分隔表示,":"后面还要增加一个空格。
  下面是一个举例:

---
#安装与运行mysql服务
- hosts: node1remote_user: roottasks:- name: install mysql-server packageyum: name=mysql-server state=present- name: starting mysqld serviceservice: name=mysql state=started

我们的文件名称应该以.yml结尾,像我们上面的例子就是mysql.yml。其中,有三个部分组成:

host部分:使用 hosts 指示使用哪个主机或主机组来运行下面的 tasks ,每个 playbook 都必须指定 hosts ,hosts也可以使用通配符格式。主机或主机组在 inventory 清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,指定清单的位置即可。在运行清单文件的时候,–list-hosts选项会显示那些主机将会参与执行 task 的过程中。remote_user:指定远端主机中的哪个用户来登录远端系统,在远端系统执行 task 的用户,可以任意指定,也可以使用 sudo,但是用户必须要有执行相应 task 的权限。tasks:指定远端主机将要执行的一系列动作。tasks 的核心为 ansible 的模块,前面已经提到模块的用法。tasks 包含 name 和要执行的模块,name 是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。

  使用ansible-playbook运行playbook文件,得到如下输出信息,输出内容为JSON格式。并且由不同颜色组成,便于识别。一般而言
| 绿色代表执行成功,系统保持原样
| 黄色代表系统代表系统状态发生改变
| 红色代表执行失败,显示错误输出
  执行有三个步骤:1、收集facts 2、执行tasks 3、报告结果

2)核心元素

  Playbook的核心元素:

Hosts:主机组;
Tasks:任务列表;
Variables:变量,设置方式有四种;
Templates:包含了模板语法的文本文件;
Handlers:由特定条件触发的任务;

3)基本组件

  Playbooks配置文件的基础组件:

Hosts:运行指定任务的目标主机
remoute_user:在远程主机上执行任务的用户;
sudo_user:
tasks:任务列表格式:tasks:– name: TASK_NAMEmodule: argumentsnotify: HANDLER_NAMEhandlers:– name: HANDLER_NAMEmodule: arguments
模块,模块参数:格式:(1) action: module arguments(2) module: arguments注意:shell和command模块后面直接跟命令,而非key=value类的参数列表;
handlers:任务,在特定条件下触发;接收到其它任务的通知时被触发;

  (1) 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;
  (2) 任务可以通过“tags“打标签,而后可在ansible-playbook命令上使用-t指定进行调用;

举例

[root@ansible ansible]# cat test1.yml
---
- hosts: centos8remote_user: roottasks: - name: install packyum: name: httpd state: present- name: start service service: name: httpd state: startedenabled: true[root@ansible ansible]# cat nginx.yml
---
- hosts: webremote_user: roottasks:- name: install nginxyum: name: nginx state: present- name: copy nginx.confcopy: src: /tmp/nginx.conf dest: /etc/nginx/nginx.conf backup: yesnotify: reload    #当nginx.conf发生改变时,通知给相应的handlerstags: reloadnginx   #打标签- name: start nginx serviceservice: name: nginx state: startedtags: startnginx   #打标签handlers:  #注意,前面没有-,是两个空格- name: reloadservice: name: nginx state: restarted  #为了在进程中能看出来[root@ansible ansible]# ansible-playbook test1.yml --list-hostsplaybook: test1.ymlplay #1 (centos8): centos8    TAGS: []pattern: [u'centos8']hosts (1):192.168.245.129
[root@ansible ansible]# ansible-playbook test1.yml --list-tasksplaybook: test1.ymlplay #1 (centos8): centos8    TAGS: []tasks:install pack      TAGS: []start service     TAGS: []# 指定某台机器执行ansible-playbook --limit 192.168.245.131 httpd.yml

案例

# 安装httpd ,拷贝配置文件,启动服务
[root@ansible ansible]# cat httpd.yml
---
- hosts: webremote_user: roottasks: - name: install httpdyum:name: httpd- name: copy configcopy: src: /app/httpd.conf dest: /etc/httpd/conf/backup: yes- name: start httpdservice: name: httpdstate: startedenabled: yes

Handlers

是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作。

notify这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。

# 当copy模块发生变化时执行notify任务,hadlers
[root@ansible ansible]# cat httpd.yml
---
- hosts: webremote_user: roottasks: - name: install httpdyum:name: httpd- name: copy configcopy: src: /app/httpd.conf dest: /etc/httpd/conf/backup: yesnotify: restart httpd- name: start httpdservice: name: httpdstate: startedenabled: yeshandlers:- name: restart httpdservice: name: httpd state: restarted

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

- hosts: webremote_user: roottasks:- name: test connectionping:remote_user: yzgsudu: yes    #默认sudo为rootsudo_user: testuser  # sudo为testuser
# 如果命令或脚本的退出码不为零,可以使用如下方式替代tasks: - name: run this command and ignore the resultshell: /usr/bin/somecommand || /bin/true
# 或者使用ignore_errors来忽略错误信息tasks:- name: run this command and ignore the resultshell: /usr/bin/somecommand ignore_errors: True

tags标签的使用(标签名可以重复)

[root@ansible ansible]# cat httpd.yml
---
- hosts: webremote_user: roottasks: - name: install httpdyum:name: httpd- name: copy configcopy: src: /app/httpd.conf dest: /etc/httpd/conf/backup: yesnotify: restart httpdtags: conf- name: start httpdservice: name: httpdstate: startedenabled: yestags: servicehandlers:- name: restart httpdservice: name: httpd state: restarted# 执行时指定标签,则单独执行标签内的语句
# ansible-playbook -t conf httpd.yml

playbook 中变量使用

变量名:仅能由字母、数字和下划线组成,且只能以字母开头

变量来源:

ansible setup facts 远程主机的所有变量都可直接调用在/etc/ansible/hosts中定义普通变量:主机组中主机单独定义,优先级高于公共变量公共(组)变量:针对主机组中所有主机定义统一变量通过命令行指定变量,优先级最高ansible-playbook -e varname-value在playbook中定义vars:- var1: value1- var2: value2在role中定义

变量应用

[root@ansible ansible]# cat pack.yml
---
- hosts: webremote_user: roottasks:- name: install packageyum: name: "{{ pkname }}"- name: copyfilecopy: src: /app/{{ filename }}dest: /app/# ansible-playbook -e "pkname=vsftpd filename=httpd.conf"  pack.yml
[root@ansible ansible]# cat v.yml
---
- hosts: webremote_user: rootvars:   - username: user1- groupname: group1tasks: - name: create groupgroup: name: "{{ groupname }}"- name: create useruser:name: "{{ username }}"group: "{{ groupname }}"home: /app/{{ username }}dir#执行
# ansible-playbook v.yml
# ansible web -a 'getent passwd user1'
# ansible web -a 'id user1'
# ansible web -m shell -a 'ls /app/user1dir/'
# 利用setup变量
[root@ansible ansible]# cat file.yml
---
- hosts: webremote_user: roottasks:- name: create filefile:name: /app/{{ ansible_hostname }}.txt state: touch
# ansible-playbook file.yml
# cat /etc/ansible/hosts
[web]
192.168.245.130   http_port=80
192.168.245.131   http_port=81
192.168.245.132   http_port=82
192.168.245.133   http_port=83# ansible web -m hostname -a 'name=web{{ http_port }}'
# cat /etc/ansible/hosts
[web]
192.168.245.130   http_port=80 hname=httpd
192.168.245.131   http_port=81 hname=nginx
192.168.245.132   http_port=82 hname=firefox
192.168.245.133   http_port=83 hname=chrome[root@ansible ansible]# cat name.yml
---
- hosts: webremote_user: roottasks: - name: set hostnamehostname: name: '{{ hname }}-{{ http_port }}'# ansible-playbook  name.yml 
#  vim /etc/ansible/hosts
[web]
192.168.245.130   http_port=80
192.168.245.131   http_port=81
192.168.245.132   http_port=82
192.168.245.133   http_port=83
[web:vars]
hname=web
#定义web组公共变量[root@ansible ansible]# cat name.yml
---
- hosts: webremote_user: roottasks: - name: set hostnamehostname: name: '{{ hname }}-{{ http_port }}'# ansible-playbook  name.yml
# 定义和调用变量yml文件
[root@ansible ansible]# cat vars.yml
var1: httpd
var2: nginx[root@ansible ansible]# cat var1.yml
---
- hosts: webremote_user: rootvars_files:- vars.ymltasks: - name: create filefile: name: /app/{{ var1 }}-{{ var2 }}.logstate: touchmode: 600 owner: yzg# ansible-playbook  var1.yml
# playbook和变量文件在同一个目录内[root@ansible ansible]# ansible web -m shell -a 'ls /app/'
192.168.245.132 | CHANGED | rc=0 >>
httpd-nginx.log

模板 templates

文本文件,嵌套有脚本(使用模板编程语言编写)

Jinja2语言,使用字面量,有下面形式

字符串:使用单引号或双引号

数字:整数,浮点数

列表:[item1, item2, ...]

元组:(item1, item2, ...)

字典:{key1:value1, key2:value2, ...}

布尔型:true/false

算术运算:+, -, *, /, //, %, **

// 除取整数,** 指数(4**2,4的2次方16   )

比较操作:==, !=, >, >=, <, <=

逻辑运算:and, or, not

流表达式:For If When

templates功能:根据模块文件动态生成对应的配置文件。

templates文件必须存放于templates目录下,且命名为.j2 结尾

yaml/yml 文件需和templates目录平级,目录结构如下:

[root@ansible temp]# tree ./
./
├── templates
│   └── test.conf.j2
└── temptest.yml

实例

# templates 目录里httpd.conf.j2是httpd的配置文件,把配置文件拷贝到web组主机[root@ansible ansible]# cat temphttpd.yml
---
- hosts: webremote_user: roottasks: - name: templatetemplate: src: httpd.conf.j2dest: /etc/httpd/conf/httpd.conf

实例

# cat /etc/ansible/hosts  #定义变量,每台机器的端口
[web]
192.168.245.130   http_port=80
192.168.245.131   http_port=81
192.168.245.132   http_port=82
192.168.245.133   http_port=83# 模板文件配置,进程数根据cpu核心数*2,端口号来自hosts文件定义的变量
[root@ansible ansible]# cat templates/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus*2 }};
server {listen       {{http_port}};listen       [::]:{{http_port}};server_name  _;root         /usr/share/nginx/html;...# 安装、修改配置,启动服务
[root@ansible ansible]# cat temnginx.yml
---
- hosts: webremote_user: root#vars: #  - http_port: 8080tasks:- name: installyum: name: nginxstate: present- name: copytmptemplate:src: nginx.conf.j2dest: /etc/nginx/nginx.conftags: copytmpnotify: restart nginx    - name: service startservice:name: nginxstate: startedenabled: yeshandlers:- name: restart nginxservice: name: nginxstate: started

when

条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要做到条件测试,通过when语句实现,在task中使用,jinja2的语句格式。

when语句

在task后添加when字句即可使用条件测试;when语句支持jinja2表达式语法

实例:

# templates 目录里httpd.conf.j2是httpd的配置文件,把配置文件拷贝到web组主机[root@ansible ansible]# cat temphttpd.yml
---
- hosts: webremote_user: roottasks: - name: template 7template: src: httpd_7.conf.j2dest: /etc/httpd/conf/httpd.confwhen: ansible_distribution_major_version=="7"- name: template 8template: src: httpd_8.conf.j2dest: /etc/httpd/conf/httpd.confwhen: ansible_distribution_major_version=="8"- name: startservice: name: httpdstate: started

迭代:with_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制

对迭代项的引用,固定变量名为“item”

要在task中使用with_items给定要迭代的元素列表

列表格式:

字符串

字典

# 实例:#  创建用户,复制文件
---
- hosts: webremote_root: roottasks:- name: add usersuser:name: {{ item }} state: presentgroups: wheelwith_items:- testuser1- testuser2- name: copyfilecopy:src: /app/{{ item }} dest: /etc/{{ item }}with_items:- file1- file2- name: copyfile2copy:src: {{ item }} dest: /app/with_items:- /app/file1- /app/file2- name: install yum: name: {{ item }}state: presentwith_items:- httpd- vsftpd- apr
# 等同于下面的语句- name: add usersuser:name: testuser1 state: presentgroups: wheel- name: add usersuser:name: testuser2 state: presentgroups: wheel- name: copyfile1copy:src: /app/file1 dest: /etc/file1- name: copyfile2copy:src: /app/file2 dest: /etc/file2

迭代嵌套子变量

# 实例
---
- hosts: webremote_user: roottasks:- name: create groupsgroup: user: {{ item }}with_items:- newgoups1- newgoups2- newgoups3- name: create useruser: name: {{ item.newuser }}group: {{ item.groups }}with_items:- {newuser:'newuser1',groups:'newgroups1'}- {newuser:'newuser2',groups:'newgroups2'}       - {newuser:'newuser3',groups:'newgroups3'}

Playbook中template for if

# Playbook中template for if
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen | default('80 default_server') }};
{% endfor %}{% if vhost.server_name is defined %}
server_name {{ vhost.server_name }};
{% endif %}{% if vhost.root is defined %}
root {{ vhost.root }};
{% endif %}
# 实例
[root@ansible ansible]# cat templates/for1.conf.j2
{%for port in ports%}
server{listen {{ port }};
}
{%endfor%}[root@ansible ansible]# cat for1.yml
---
- hosts: webremote_user: rootvars: ports:- 81- 82- 83- 84tasks: - name: test for1template: src: for1.conf.j2dest: /app/for1.conf
[root@ansible ansible]# cat templates/for2.conf.j2
{%for vhost in vhosts%}
server{listen {{ vhost.port }};servername {{ vhost.name }};rootdir {{ vhost.root }};
}
{%endfor%}[root@ansible ansible]# cat for2.yml
---
- hosts: webremote_user: rootvars: vhosts:- web1:port: 82name: web1.yzg.comroot: /app/webroot1- web2:port: 83name: web3.yzg.comroot: /app/webroot3- web3:port: 84name: web4.yzg.comroot: /app/webroot4tasks:- name: test for2template: src: for2.conf.j2dest: /app/for2.conf
[root@ansible ansible]# cat templates/for3.conf.j2
{%for vhost in vhosts%}
server{listen {{ vhost.port }};
# 判断vhost.name的值是否被定义,如果定义了就引用,没定义就不管
{%if vhost.name is defined%}servername {{ vhost.name }};
{%endif%}rootdir {{ vhost.root }};
}
{%endfor%}[root@ansible ansible]# cat for3.yml
---
- hosts: webremote_user: rootvars: vhosts:- web1:port: 82root: /app/webroot1- web2:port: 83root: /app/webroot3- web3:port: 84name: web4.yzg.comroot: /app/webroot4tasks:- name: test for2template: src: for3.conf.j2dest: /app/for3.conf

roles

ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。

roles能够根据层次型结构自动装载变量文件、 tasks以及handlers等。

要使用roles只需要在playbook中使用 import_tasks指令即可。

简单来讲,roles就是通过分别将变量、文件 、任务、模板及处理器放置于单独的目录中,并可以便捷地 include它们的一种机制。

角色一般用于基于主机构建服务的场 景中,但也可以是用于构建守护进程等场景中

复杂场景:建议使用roles,代码复用度高

变更指定主机或主机组

如命名不规范维护和传承成本大

某些功能需多个Playbook,通过Includes即可实现

角色(roles):角色集合roles/mysql/httpd/nginx/memcached/

roles目录结构

# 每个角色,以特定的层级目录结构进行组织
# roles目录结构:playbook.ymlroles/project/tasks/files/vars/      #不常用default/   #不常用templates/handlers/meta/   #不常用

实例

# roles目录结构
[root@ansible ansible]# tree
.
├── filecopy_roles.yml
├── nginx_roles.yml
├── roles
│   ├── filecopy
│   │   ├── files
│   │   │   └── fstab
│   │   └── tasks
│   │       └── main.yml
│   ├── memcached
│   └── nginx
│       ├── tasks
│       │   ├── groupadd.yml
│       │   ├── install.yml
│       │   ├── main.yml
│       │   ├── start.yml
│       │   ├── stop.yml
│       │   └── useradd.yml
│       ├── templates
│       └── vars
└── roles-tags.yml[root@ansible ansible]# cat roles/nginx/tasks/groupadd.yml
- name: add groupgroup:name: nginx
[root@ansible ansible]# cat roles/nginx/tasks/install.yml
- name: install packyum: name: nginx
[root@ansible ansible]# cat roles/nginx/tasks/start.yml
- name: install serviceservice:  name: nginxstate: startedenabled: yes
[root@ansible ansible]# cat roles/nginx/tasks/stop.yml
- name: stop serviceservice: name: nginxstate: stopped
[root@ansible ansible]# cat roles/nginx/tasks/useradd.yml
- name: add useruser: name: nginxgroup: nginxsystem: yesshell: /sbin/nologin# 按执行顺序写
[root@ansible ansible]# cat roles/nginx/tasks/main.yml
- import_tasks: groupadd.yml
- import_tasks: useradd.yml
- import_tasks: install.yml
- import_tasks: stop.yml
- import_tasks: start.yml# 这里拷贝和创建文件写在一起了,拷贝的文件放在files文件夹内,src可以不写具体路径。
[root@ansible ansible]# cat roles/filecopy/tasks/main.yml
- name: filecopycopy: src: fstabdest: /app/
- name: create filefile: name: /app/testfile mode: '600'state: touch
# 这里是在filecopy角色中调用了nginx的stop任务。跨角色调用
- import_tasks: roles/nginx/tasks/stop.yml[root@ansible ansible]# cat nginx_roles.yml
---
- hosts: webremote_user: rootroles:- role: nginx- role: filecopy      #  这里还可以调用多个roles角色[root@ansible ansible]# cat filecopy_roles.yml
---
- hosts: webremote_user: rootroles:- role: filecopy# 给角色打标签,每个角色可以打多个标签,执行的时候可以写多个角色。
[root@ansible ansible]# cat roles-tags.yml
---
- hosts: webremote_user: rootroles:- { role: nginx, tags: ['nginx','web'] }- { role: httpd, tags: ['httpd','web'] }- { role: memcached, tags: 'cache' }- { role: mysql, tags: 'db' }
# 短格式写法 roles:- role: nginxtags: '"nginx" "web"'- role: httpdtags: '"httpd" "web"'- role: memcached tags: cache- role: mysqltags: db#
# 执行web标签角色,会执行nginx角色和httpd角色。
ansible-playbook -C -t web roles-tags.yml
#
ansible-playbook -C -t "web,db" roles-tags.yml

roles案例

# 安装nginx服务,拷贝模板、启动
# 目录结构
[root@ansible ansible]# tree roles/nginx/
roles/nginx/
├── handlers
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
│   └── nginx.conf.j2
└── vars[root@ansible ansible]# cat roles/nginx/tasks/main.yml
- name: install packageyum: name: nginx
- name: templatetemplate: src: nginx.conf.j2dest: /etc/nginx/nginx.confnotify: restart servicetags: tempfile   # 给任务加标签 ,执行标签任务ansible-playbook -t tempfile test_roles.yml
- name: start serviceservice: name: nginx state: started
#
[root@ansible ansible]# cat roles/nginx/handlers/main.yml
- name: restart serviceservice: name: nginxstate: restarted# 模板这里进程数引用ansible的变量来获取并乘以2
[root@ansible ansible]# cat roles/nginx/templates/nginx.conf.j2 | grep ansible
worker_processes {{ ansible_processor_vcpus*2}};# 执行测试验证
ansible-playbook test_roles.ymlansible web -m shell -a 'ps aux | grep nginx'
ansible web -m shell -a 'ss -ntlp'# 加入变量测试
[root@ansible ansible]# cat roles/nginx/vars/main.yml
http_port: 8080[root@ansible ansible]# cat roles/nginx/templates/nginx.conf.j2 | grep -C3 listeninclude /etc/nginx/conf.d/*.conf;server {listen       {{ http_port }};listen       [::]:{{ http_port }};server_name  _;root         /usr/share/nginx/html;3[root@ansible ansible]# cat test_roles.yml
- hosts: webremote_user: rootroles: - role: nginx# 执行测试验证
ansible-playbook test_roles.ymlansible web -m shell -a 'ps aux | grep nginx'
ansible web -m shell -a 'ss -ntlp'# 加入条件判断,只有centos7版本才执行
[root@ansible ansible]# cat test_roles.yml
- hosts: allremote_user: rootroles: - role: nginxwhen: ansible_distribution_major_version=='7'http_port: 9090   # 这里还可以定义变量,会替代vars里定义的变量# 执行测试验证
ansible-playbook test_roles.yml# 执行多个角色
[root@ansible ansible]# cat test_roles.yml
- hosts: allremote_user: rootroles: - role: nginxwhen: ansible_distribution_major_version=='7' http_port: 9090- role: filecopywhen: ansible_nodename=='yzg_01'  #条件为主机名为yzg_01才执行filecopy角色

实例:安装memcached

[root@ansible roles]# tree memcached/
memcached/
├── tasks
│   └── main.yml
└── templates└── memcached.j2[root@ansible roles]# cat memcached/tasks/main.yml
- name: install packageyum: name: memcached
- name: templatetemplate: src: memcached.j2dest: /etc/sysconfig/memcached
- name: start serviceservice: name: memcachedstate: startedenabled: yes
# 模板文件,缓存大小调整为内存大小的四分之一,取整
[root@ansible roles]# cat memcached/templates/memcached.j2
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ ansible_memtotal_mb//4 }}"
OPTIONS=""[root@ansible ansible]# cat test_roles1.yml
- hosts: allremote_user: rootroles: - role: memcachedwhen: ansible_distribution_major_version=='7'

企业级自动化运维工具-ansible相关推荐

  1. 自动化运维工具----ansible

    自动化运维工具----ansible ansible是新出现的运维工具是基于Python研发的糅合了众多老牌运维工具的优点实现了批量操作系统配置.批量程序的部署.批量运行命令等功能. 主要模块以及功能 ...

  2. 自动化运维工具ansible(安装与模块介绍)

    自动化运维工具ansible(安装与模块介绍) 一.ansible运维工具概述 (一).ansible的特点 (二).ansible的原理 (三)ansible的优点 二.安装ansible 三.an ...

  3. 自动化运维工具Ansible详细部署 - 人生理想在于坚持不懈 - 51CTO技术博客

    自动化运维工具Ansible详细部署 - 人生理想在于坚持不懈 - 51CTO技术博客 自动化运维工具Ansible详细部署 - 人生理想在于坚持不懈 - 51CTO技术博客 自动化运维工具Ansib ...

  4. 自动化运维工具Ansible实战---常用模块

    Ansible默认提供了很多模块来供我们使用.在Linux中,我们可以通过 ansible-doc -l 命令查看到当前Ansible支持哪些模块,通过 ansible-doc -s [模块名] 又可 ...

  5. 自动化运维工具ansible的安装管理以及模块介绍

    自动化运维工具ansible的安装管理以及模块介绍 目录 自动化运维工具ansible的安装管理以及模块介绍 一.ansible概述 1.几种常用运维工具比较 2.Ansible简介 3.Ansibl ...

  6. 自动化运维工具-Ansible的Playbook的使用

    Playbook的使用 前言 一.Playbook是什么? 二.playbook使用场景 三.Playbook格式说明 四.Play book变量的使用 1 在主机列表定义变量 2 在playbook ...

  7. 自动化运维工具-Ansible实战指南

    Ansible实战 前言 一.Ansible简介 1.ansible是什么? 2.ansible特点 3.ansible架构 主要模块 工作流程 命令执行过程 二.Ansible 配置 1 安装ans ...

  8. 自动化运维工具——Ansible(三)——分组管理

    自动化运维工具--Ansible(三)--分组管理 1. 通过ip地址分组 1.1 写法一 1.2 写法二 2. 通过主机名分组 2.1 写法一 2.2 写法二 3. 子组 1. 通过ip地址分组 1 ...

  9. 自动化运维工具Ansible

    ansible简介: ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了批量系统配置.批 ...

  10. 自动化运维工具Ansible详细部署

    一.基础介绍 ================================================================================= 1.简介 ansibl ...

最新文章

  1. 关于创建zeromq消息队列,设置和更改IP地址,远程可以访问,不只是本地链接。python代码。
  2. SHELL 技能树(持续更新)
  3. 服务器响应的生成:HTTP响应报头——HttpServletResponse接口的应用
  4. python-- Image 模块
  5. 微型小乐器 : MicroSynth 小巧而优美
  6. ci框架mysql多条件_CI框架同时连接不同的数据库(或不同表前缀)
  7. python写后台接口请求出错_python登录接口测试问题记录与解决
  8. c++11 你需要知道这些就够了
  9. python列表生成时 if_Python列表生成式
  10. python交叉编译环境_交叉编译Python
  11. python——zip()、map()、enumerate()、filter()、apply函数
  12. php 0x颜色 转换,rgb和十六进制颜色互转
  13. SQLHelp sql数据库的DAL
  14. 最新nodejs的开发学习实战(1)从一个博客开始
  15. gsonformat安装
  16. torch tensor去掉1维_代数拓扑笔记(1) —— 胞腔复形
  17. JDK7官方下载地址
  18. android传感器获取运动方向,Android 重力感应获取手机运动方向和角度
  19. 所有浏览器主页都变成hao123,hao123劫持浏览器(亲测有效)
  20. 盘点为下个牛市做准备的10个新Layer1

热门文章

  1. 单片机——A/D数模转换篇
  2. Xcode6使用iOS7模拟器调试的方法
  3. Failed opening .rdb for saving: Permission denied
  4. ubuntu 刷新频率 如何查看_Ubuntu 7.04救命啊!屏幕刷新频率只有50HZ眼不行啦!显示器是CRT...
  5. 基于Android的本地电子书阅读器的设计与实现Ebook(2)
  6. Songtaste,酷到不行的音乐网站
  7. TCGA肿瘤样本基因信息库(一)
  8. 线性变换的不变子空间和特征子空间的关系
  9. 北京大学计算机科学李丰,北京大学
  10. 如何实现网页上的气球提示