Ansible是一个部署一群远程主机的工具;Ansible通过SSH协议实现远程节点和管理节点之间的通信。理论上说,只要管理员通过ssh登录到一台远程主机上能做的操作,Ansible都可以做到。Ansible是python开发的,故依赖一些python库和组件,如:paramiko,PyYaml和jinja三个关键组件;
ansible是自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
用途:批量的去完成日常运维的工作
日常linux运维工作:
1.安装软件
2.启动服务
3.运行脚本
4.修改配置
5.升级软件
6.备份复制文件
等
ansible就是让什么主机使用什么工具做什么事情 --》自动化运维工具,批量部署,批量操作运维,目的是提升效率和降低人力成本
1.host inventory 主机清单 --》可以控制的其他的电脑的名单
2.playbook 剧本(配置文件) --》让主机清单里的主机去批量完成的任务 --》脚本
3.module 模块 实现一个个功能的程序
4.plugins 插件 :依附于ansible的一个小软件,实现某个小功能。
写明控制的机器的信息,例如ip地址、ssh端口号、域名、用户名和密码
[webservers]
192.168.0.190
192.168.0.191
[dbservers]
192.168.0.192:22 ansible_ssh_user='cali'
[nfs]
192.168.0.139:2233 ansible_ssh_user='root' ansible_ssh_pass='123456'
指定用户名和密码的配置,需要连接一次,获取对方服务器的公钥到know_hosts文件
在后面介绍
后面介绍
定义客户机--》你需要去控制的客户机,可以对客户机进行分类:web组、db组、redis组、flask组、django组等
hosts 里面定义主机清单
[root@server ansible]# vim /etc/ansible/hosts
[scweb]
192.168.223.205
HOST-PATTERN #匹配主机模式,如all表示所有主机
-m MOD_NAME #模块名 如:ping
-a MOD_ARGS #模块执行的参数
-f FORKS #生成几个子进行程执行
-C #(不执行,模拟跑)
-u Username #某主机的用户名
-c CONNection #连接方式(default smart)
完整示例:
[root@ansible ~]# ansible all -m shell -a "ifconfig|grep enp0s3"
172.16.3.152 | SUCCESS | rc=0 >>
enp0s3: flags=4163 mtu 1500
172.16.3.216 | SUCCESS | rc=0 >>
enp0s3: flags=4163 mtu 1500
执行的返回结果里不同的颜色:
绿色:曾经使用,命令执行的 效果,之前执行过,已经有了
黄色:没有使用,命令执行有效果
红色:失败
ansible模块比较多,可以通过ansible-doc --help 显示帮助信息
ansible doc -l 获取所有当前版本下的可用模块及简要信息
ansible-doc -s 模块名 获取指定模块帮助信息说明``
使用方式:
准备2台服务器
server: 192.168.223.206
client: 192.168.223.205
1.先在server和client之间建立单向信任关系,server端产生密钥对,上传公钥到client
[root@server ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
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:8/oghA3DLKP6/1FiJm77Z312AfEzhSNhcTS3uj9e95k root@server
The key's randomart image is:
+---[RSA 2048]----+
| +++..|
| o .o.ooo|
| o = + + |
| . o = . = |
|. o * S o o |
|. . = o o o |
|. o o ... . .o|
| . . . ooo. o o.*|
| ..oooo...o ..Eo|
+----[SHA256]-----+
[root@server ~]# cd /root/.ssh/
[root@server .ssh]# ls
authorized_keys boot hosts id_rsa id_rsa_2048-de.pub id_rsa_2048-feng.pub id_rsa.pub known_hosts
[root@server .ssh]# ll
总用量 28
-rw------- 1 root root 1153 5月 14 16:47 authorized_keys
dr-xr-xr-x 4 root root 246 5月 14 15:13 boot
-rw-r--r-- 1 root root 158 5月 14 15:12 hosts
-rw------- 1 root root 1675 5月 21 11:34 id_rsa
-rw-r--r-- 1 root root 380 5月 14 16:44 id_rsa_2048-de.pub
-rw-r--r-- 1 root root 380 5月 14 16:38 id_rsa_2048-feng.pub
-rw-r--r-- 1 root root 393 5月 21 11:34 id_rsa.pub
-rw-r--r-- 1 root root 361 5月 14 16:20 known_hosts
上传公钥
[root@server .ssh]# ssh-copy-id -i id_rsa.pub [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
测试是否免密通道建立成功
[root@server .ssh]# ssh '[email protected]'
Last login: Sun May 21 11:31:37 2023 from 192.168.223.1
[root@web1 ~]#
2.安装ansible,在管理节点上
[root@ansible .ssh]# yum install epel-release -y
[root@ansible .ssh]# yum install ansible -y
[root@server ~]# cd /etc/ansible/
[root@server ansible]# ls
ansible.cfg hosts roles
ansible.cfg 是ansible的配置文件
hosts 里面定义主机清单
[root@server ansible]# vim hosts
[scweb]
192.168.223.205
[root@server ansible]# ansible scweb -m shell -a "ip add" 在scweb组的主机上执行ip add 命令
192.168.223.205 | CHANGED | rc=0 >>
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:27:30:f9 brd ff:ff:ff:ff:ff:ff
inet 192.168.223.205/24 brd 192.168.223.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe27:30f9/64 scope link
valid_lft forever preferred_lft forever
[root@server ansible]#
在所有主机上执行 yum install epel-release命令
[root@server ansible]# ansible all -m yum -a "name=epel-release state=installed"
在所有主机上执行 yum istall htop命令
[root@server ansible]# ansible all -m yum -a "name=htop state=installed"
在scweb组的主机上执行nohup bash /tmp/while.sh & 命令
[root@server test]# ansible scweb -m shell -a "nohup bash /tmp/while.sh &"
在所有主机上新建/hehaotian 目录
[root@server test]# ansible all -m file -a "path=/hehaotian state=directory"
在所有主机上新建/hehaotian/sc.txt空文件
[root@server test]# ansible all -m file -a "path=/hehaotian/sc.txt state=touch"
在所有主机上创建链接文件/hehaotian/sc.txt.link 指向 /hehaotian/sc.txt
[root@server test]# ansible all -m file -a "src=/hehaotian/sc.txt path=/hehaotian/sc.txt.link state=link"
从本地copy文件分发到目录主机路径
参数说明:
src= 源文件路径
dest= 目标路径
注意src= 路径后面带/ 表示带里面的所有内容复制到目标目录下,不带/是目录递归复制过去
content= 自行填充的文件内容
owner 属主
group 属组
mode权限
ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
ansible all -m copy -a "content='hi there\n' dest=/tmp/hi.txt"
到node1上查看
[root@node1 tmp]# ll
-rw------- 1 root root 465 2月 9 14:59 fstab.ansible
-rw-r--r-- 1 root root 9 2月 9 14:58 hi.txt
从远程主机拉取文件到本地
[root@ansible ~]# ansible all -m fetch -a "src=/tmp/hi.txt dest=/tmp"
172.16.3.152 | SUCCESS => {
"changed": true,
"checksum": "279d9035886d4c0427549863c4c2101e4a63e041",
"dest": "/tmp/172.16.3.152/tmp/hi.txt",
"md5sum": "12f6bb1941df66b8f138a446d4e8670c",
"remote_checksum": "279d9035886d4c0427549863c4c2101e4a63e041",
"remote_md5sum": null
}
.......省略
说明:fetch使用很简单,src和dest,dest只要指定一个接收目录,默认会在后面加上远程主机及src的路径
在远程主机上执行命令,属于裸执行,非键值对显示;不进行shell解析;
[root@ansible ~]# ansible all -m command -a "ifconfig"
172.16.3.152 | SUCCESS | rc=0 >>
enp0s3: flags=4163 mtu 1500
inet 172.16.3.152 netmask 255.255.255.0 broadcast 172.16.3.255
.....省略.....
172.16.3.216 | SUCCESS | rc=0 >>
enp0s3: flags=4163 mtu 1500
inet 172.16.3.216 netmask 255.255.255.0 broadcast 172.16.3.255
.....省略.....
[root@ansible ~]# ansible all -m command -a "ifconfig|grep lo"
172.16.3.152 | FAILED | rc=2 >>
[Errno 2] 没有那个文件或目录
172.16.3.216 | FAILED | rc=2 >>
[Errno 2] 没有那个文件或目录
这就是因为command模块不是shell解析属于裸执行导致的
为了能达成以上类似shell中的解析,ansible有一个shell模块;
由于commnad只能执行裸命令(即系统环境中有支持的命令),至于管道之类的功能不支持,
shell模块可以做到
[root@ansible ~]# ansible all -m shell -a "ifconfig|grep lo"
172.16.3.152 | SUCCESS | rc=0 >>
lo: flags=73 mtu 65536
loop txqueuelen 0 (Local Loopback)
172.16.3.216 | SUCCESS | rc=0 >>
lo: flags=73 mtu 65536
loop txqueuelen 0 (Local Loopback)
设置文件属性(创建文件)
常用参数:
path目标路径
state directory为目录,link为软件链接
group 目录属组
owner 属主
等,其他参数通过ansible-doc -s file 获取
示例1:创建目录
[root@ansible ~]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"
172.16.3.152 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/var/tmp/hello.dir",
"size": 6,
"state": "directory",
"uid": 0
}
172.16.3.216 | SUCCESS => {
"changed": true,
.....省略.....
示例2:创建软件链接
[root@ansible ~]# ansible all -m file -a "src=/tmp/hi.txt path=/var/tmp/hi.link state=link"
172.16.3.152 | SUCCESS => {
"changed": true,
"dest": "/var/tmp/hi.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 11,
"src": "/tmp/hi.txt",
"state": "link",
"uid": 0
}
172.16.3.216 | SUCCESS => {
"changed": true,
.....省略.....
通过cron模块对目标主机生成计划任务
常用参数:
除了分(minute)时(hour)日(day)月(month)周(week)外
name: 本次计划任务的名称
state: present 生成(默认) |absent 删除 (基于name)
ansible all -m cron -a "minute=0 hour=8-18 month=5 weekday=1-5 job='bash /root/iptables.sh' name=runiptables2"
示例:对各主机添加每隔3分钟从time.windows.com同步时间
[root@ansible ~]# ansible all -m cron -a "minute=*/3 job='/usr/sbin/update time.windows.com &>/dev/null' name=update_time"
172.16.3.152 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"update_time"
]
}
172.16.3.216 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"update_time"
]
}
#到node1上查看
[root@node1 tmp]# crontab -l
#Ansible: update_time
*/3 * * * * /usr/sbin/update time.windows.com &>/dev/null
示例2:删除计划任务
[root@ansible ~]# ansible all -m cron -a "name=update_time state=absent"
172.16.3.152 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
172.16.3.216 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
#node1上查看
[root@node1 tmp]# crontab -l
会发现已经被删除了
创建计划任务
[root@server test]# ansible all -m cron -a "minute=30 hour=2 job='bash /tmp/backup.sh' name=backup_passwd state=present"
[root@web1 hehaotian]# crontab -l
#Ansible: backup_passwd
30 2 * * * bash /tmp/backup.sh
取消计划任务
[root@web1 hehaotian]# ansible all -m cron -a "name=backup_passwd state=absent"
扩展 supervisor
Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。
看服务是否运行?
1.看进程
2.看端口
3.直接访问
如何知道服务做了哪些事情?
1.看日志
crond 服务:去检查计划任务的最短时间间隔 1分钟
如何让某个事情每隔1秒钟去做一次呢?
1.编写一个脚本watch.sh,死循环 一直运行,每隔一秒钟去执行
while
sleep 1
2.监控软件监控脚本watch.sh -->监控软件 supervisor
[root@master lianxi]# cat watch.sh
#!/bin/bash
#while :
while true
do
sleep 1
mkdir -p /test
touch /test/$RANDOM-SC.txt
done
故名思义就是yum安装软件包的模块;
常用参数说明:
enablerepo,disablerepo表示启用与禁用某repo库
name 安装包名
state (present' or
installed', latest')表示安装, (
absent' or `removed') 表示删除
示例:通过安装epel扩展源并安装nginx
[root@ansible ~]# ansible all -m yum -a "name=epel-release state=installed"
[root@ansible ~]# ansible all -m yum -a "name=nginx state=installed"
服务管理模块
常用参数:
name:服务名
state:服务状态
enabled: 是否开机启动 true|false
runlevel: 启动级别 (systemed方式忽略)
[root@ansible ~]# ansible all -m service -a "name=nginx state=started enabled=true"
到node1上查看
[root@node1 tmp]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since 五 2018-02-09 15:54:29 CST; 1min 49s ago
Main PID: 10462 (nginx)
CGroup: /system.slice/nginx.service
├─10462 nginx: master process /usr/sbin/nginx
└─10463 nginx: worker process
......省略......
把本地的脚本传到远端执行;前提是到远端可以执行,不要把Linux下的脚本同步到windows下执行;
直接上示例:
[root@ansible ~]# cat test.sh
#!/bin/bash
echo "ansible script test!" > /tmp/ansible.txt
[root@ansible ~]# ansible all -m script -a "/root/test.sh"
172.16.3.152 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.3.152 closed.\r\n",
"stdout": "",
"stdout_lines": []
}
172.16.3.216 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.3.216 closed.\r\n",
"stdout": "",
"stdout_lines": []
}
到node1上查看
[root@node1 tmp]# ls
ansible.txt fstab.ansible hi.txt
[root@node1 tmp]# cat ansible.txt
ansible script test!
script模块这个功能可以做很多事,就看你怎么用了~
以上是常用模块,至于其他模块的使用可通过官方模块列表获得~
playbook是Ansible的配置,部署和编排的语言。他们可以描述你所希望的远程系统强制执行的政策,或者在一般的IT流程的一组步骤;形象点的说就是:如果ansible的各模块(能实现各种功能)是车间里的各工具;playbook就是指导手册,目标远程主机就是库存和原料对象.
playbook是基于YAML语言格式配置,关于YAML
更多playbook官方说明参考
hosts : playbook配置文件作用的主机
tasks: 任务列表
variables: 变量
templates:包含模板语法的文本文件 jinja2是一种模板语言
handlers 和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags 标签,指定某条任务执行,用于选择运行playbook中的部分代码。
roles :用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文件、tasks以及handlers等;做一个事情就相当于演一个角色,需要准备一个对应的文件夹和yaml文件,适合于大的项目,部署安装修改的内容非常多;可以完成更加复杂的任务,需要多个任务同时或者按照顺序去执行,需要很多的源文件和多个playbook的yaml文件,需要定义自定义的变量,来完成这件复杂的事情(比较大的项目)
playbook
使用yaml
语法格式,后缀可以是yaml
,也可以是yml
。
playbook
文件中,可以连续三个连子号(---
)区分多个play
。还有选择性的连续三个点好(...
)用来表示play
的结尾,也可省略。playbook
的内容,一般都会写上描述该playbook
的功能。tab
混用。YAML
文件内容和Linux
系统大小写判断方式保持一致,是区分大小写的,k/v
的值均需大小写敏感k/v
的值可同行写也可以换行写。同行使用:分隔。v
可以是个字符串,也可以是一个列表name: task
示例:
# 创建playbook文件
[root@ansible ~]# cat playbook01.yml
--- #固定格式
- hosts: 192.168.1.31 #定义需要执行主机
remote_user: root #远程用户
vars: #定义变量
http_port: 8088 #变量
tasks: #定义一个任务的开始
- name: create new file #定义任务的名称
file: name=/tmp/playtest.txt state=touch #调用模块,具体要做的事情
- name: create new user
user: name=test02 system=yes shell=/sbin/nologin
- name: install package
yum: name=httpd
- name: config httpd
template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: #定义执行一个动作(action)让handlers来引用执行,与handlers配合使用
- restart apache #notify要执行的动作,这里必须与handlers中的name定义内容一致
- name: copy index.html
copy: src=/var/www/html/index.html dest=/var/www/html/index.html
- name: start httpd
service: name=httpd state=started
handlers: #处理器:更加tasks中notify定义的action触发执行相应的处理动作
- name: restart apache #要与notify定义的内容相同
service: name=httpd state=restarted #触发要执行的动作
#测试页面准备
[root@ansible ~]# echo "playbook test file
" >>/var/www/html/index.html
#配置文件准备
[root@ansible ~]# cat httpd.conf |grep ^Listen
Listen {{ http_port }}
#执行playbook, 第一次执行可以加-C选项,检查写的playbook是否ok
[root@ansible ~]# ansible-playbook playbook01.yml
PLAY [192.168.1.31] *********************************************************************************************
TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.1.31]
TASK [create new file] ******************************************************************************************
changed: [192.168.1.31]
TASK [create new user] ******************************************************************************************
changed: [192.168.1.31]
TASK [install package] ******************************************************************************************
changed: [192.168.1.31]
TASK [config httpd] *********************************************************************************************
changed: [192.168.1.31]
TASK [copy index.html] ******************************************************************************************
changed: [192.168.1.31]
TASK [start httpd] **********************************************************************************************
changed: [192.168.1.31]
PLAY RECAP ******************************************************************************************************
192.168.1.31 : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# 验证上面playbook执行的结果
[root@ansible ~]# ansible 192.168.1.31 -m shell -a 'ls /tmp/playtest.txt && id test02'
192.168.1.31 | CHANGED | rc=0 >>
/tmp/playtest.txt
uid=990(test02) gid=985(test02) 组=985(test02)
[root@ansible ~]# curl 192.168.1.31:8088
playbook test file
ansible-playbook --check 只检测可能会发生的改变,但不真执行操作
ansible-playbook --list-hosts 列出运行任务的主机
ansible-playbook --syntax-check playbook.yaml 语法检测
ansible-playbook -t TAGS_NAME playbook.yaml 只执行TAGS_NAME任务
ansible-playbook playbook.yaml 运行
很多时候当我们某一个配置发生改变,我们需要重启服务,(比如httpd配置文件文件发生改变了)这时候就可以用到handlers
和notify
了;
(当发生改动时)notify actions
会在playbook
的每一个task结束时被触发,而且即使有多个不同task通知改动的发生,notify actions
知会被触发一次;比如多个resources
指出因为一个配置文件被改动,所以apache
需要重启,但是重新启动的操作知会被执行一次。
[root@ansible ~]# cat httpd.yml
#用于安装httpd并配置启动
---
- hosts: 192.168.1.31
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=installed
- name: config httpd
template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
#这里只要对httpd.conf配置文件作出了修改,修改后需要重启生效,在tasks中定义了restart httpd这个action,然后在handlers中引用上面tasks中定义的notify。
#在家目录下创建playbooks
[root@ansible ~]# mkidr playbooks
[root@ansible ~]# cd playbooks
[root@ansible playbooks]# cat redis_first.yaml
- hosts: all
remote_user: root
tasks:
- name: install redis
yum: name=redis state=latest
- name: start redis
service: name=redis state=started
语法检测:
[root@ansible playbooks]# ansible-playbook --syntax-check redis_first.yaml
playbook: redis_first.yaml
说明语法没有 问题
将要执行的主机:
[root@ansible playbooks]# ansible-playbook --list-hosts redis_first.yaml
playbook: redis_first.yaml
play #1 (all): all TAGS: []
pattern: [u'all']
hosts (2):
172.16.3.216
172.16.3.152
执行
[root@ansible playbooks]# ansible-playbook redis_first.yaml
PLAY [all] *****************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************
ok: [172.16.3.216]
ok: [172.16.3.152]
TASK [install redis] *******************************************************************************************************
changed: [172.16.3.216]
changed: [172.16.3.152]
TASK [start redis] *********************************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP *****************************************************************************************************************
172.16.3.152 : ok=3 changed=2 unreachable=0 failed=0
172.16.3.216 : ok=3 changed=2 unreachable=0 failed=0
说明:
自上而下列出了三个任务,分别是[Gathering Facts] , [install redis], [start redis],其中各主机上成功为ok=3,有两项任务执行结果是changed
不可达 和失败的任务均为0;
由于上面的操作是直接安装redis服务并启动,并没有配置文件,这还不能往生产环境中使用,生产环境中的redis肯定有不同的配置项,因此需要在安装时提供配置文件
首先复制一个redis.conf到本地并进行修改
[root@ansible ~]# ansible 172.16.3.152 -m fetch -a "src=/etc/redis.conf dest=./"
[root@ansible ~]# mv /root/172.16.3.152/etc/redis.conf /root/playbooks/redis.conf
修改bind 0.0.0.0
cat redis_second.yaml
- hosts: all #所有远程主机
remote_user: root #以远程主机上root用户执行
tasks: #任务
- name: install redis #任务之安装
yum: name=redis state=latest #动作调用yum模块安装
- name: copy config file #任务之复制同步配置文件到远程目标主机
copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis #动作copy模块执行
notify: restart redis #触发的动作
tags: configfile #任务标记名configfile
- name: start redis #任务之启动redis
service: name=redis state=started #动作调用sevice模块
handlers: #特定情况下,接收到其他任务的通知时被触发
- name: restart redis
service: name=redis state=restarted
再次测试并执行
[root@ansible playbooks]# ansible-playbook redis_second.yaml
PLAY [all] ****************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
TASK [install redis] ******************************************************************************************************
ok: [172.16.3.216]
ok: [172.16.3.152]
TASK [copy config file] ***************************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
TASK [start redis] ********************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
RUNNING HANDLER [restart redis] *******************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP ****************************************************************************************************************
172.16.3.152 : ok=5 changed=2 unreachable=0 failed=0
172.16.3.216 : ok=5 changed=2 unreachable=0 failed=0
可以发现只是加了一个配置文件,所有的任务都执行了,可否只应用新添加的任务?当然可以
这里就要通过
ansible-playbook -t TAGS_NAME 来执行了
可以把redis.conf中添加一个登录密码再执行测试下:
[root@ansible playbooks]# ansible-playbook -t configfile redis_second.yaml
PLAY [all] ****************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************
ok: [172.16.3.152]
ok: [172.16.3.216]
TASK [copy config file] ***************************************************************************************************
changed: [172.16.3.216]
changed: [172.16.3.152]
RUNNING HANDLER [restart redis] *******************************************************************************************
changed: [172.16.3.152]
changed: [172.16.3.216]
PLAY RECAP ****************************************************************************************************************
172.16.3.152 : ok=3 changed=2 unreachable=0 failed=0
172.16.3.216 : ok=3 changed=2 unreachable=0 failed=0
以上执行结果就没有 了安装与启动的步骤~只有更新和重启!
参考: https://www.cnblogs.com/yanjieli/p/10969299.html
参考: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html
示例:
[root@server playbook]# cat redis4.yaml
- hosts: scweb
remote_user: root
vars:
- scredis: /playbook/redis.conf.j2 #定义变量
- redis_port: 63790
tasks:
- name: copy config file
copy: src={{ scredis }} dest=/etc/redis.conf owner=redis
notify: restart redis
tags: configfile
handlers:
- name: restart redis
service: name=redis state=restarted
[root@server playbook]# cp redis.conf redis.conf.j2 获得模板文件
[root@server playbook]# vim redis.conf.j2
bind {{ ansible_facts["ens33"]["ipv4"]["address"] }} #不同的机器上获取的ip地址不一样,从而达到差异化
port {{ redis_port }} #使用自定义的变量
[root@server playbook]# cat redis.conf.j2 |egrep -v "^#|^$"
bind {{ ansible_facts["ens33"]["ipv4"]["address"] }}
protected-mode yes
port {{ redis_port }}
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
[root@server playbook]# cat redis4.yaml
- hosts: scweb
remote_user: root
vars:
- scredis: /playbook/redis.conf.j2
- redis_port: 63790
tasks:
- name: template use
template: src={{ scredis }} dest=/etc/redis.conf owner=redis
notify: restart redis
tags: configfile
handlers:
- name: restart redis
service: name=redis state=restarted
[root@server playbook]# ansible-playbook redis4.yaml
PLAY [scweb] ************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************
ok: [192.168.223.205]
ok: [192.168.223.206]
TASK [template use] *****************************************************************************************************
changed: [192.168.223.205]
changed: [192.168.223.206]
RUNNING HANDLER [restart redis] *****************************************************************************************
changed: [192.168.223.205]
changed: [192.168.223.206]
PLAY RECAP **************************************************************************************************************
192.168.223.205 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.223.206 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@server playbook]#
[root@server playbook]# netstat -anputl|grep redis
tcp 0 0 192.168.223.206:63790 0.0.0.0:* LISTEN 48216/redis-server