一篇教你学会Ansible
前言
Ansible首次发布于2012年,是一款基于Python开发的自动化运维工具,核心是通过ssh将命令发送执行,它可以帮助管理员在多服务器上进行配置管理和部署。它的工作形式依托模块实现,自己没有批量部署的能力。真正具备批量部署的是ansible所运行的模块,ansible只是提供一种框架。
优点
- 学习、配置及部署简单,学习速度快
- 用户量庞大,经得起实际的是考验,自然,文档也会很多,降低学习难度
- 模块繁多,可完成运维工程中绝大多数任务
- 轻量级:无客户端程序,更新时,只需机器上进行一次更新
- 定制化模块,更好的适配项目进度,加速工作效率
- 多系统应用,不单单linux工作管理,还可以用在windo、交换机等
- 配置文件中内置幂等性、并发度控制等功能,有效减少批量部署工作量
- 集合了多种运维工具(puppet、cfengine、chef、func、fabric)优势的新兴高效运维工具
结构组成
- 链接插件connection plugins:负责和被监控端实现通讯;
- host inventory:主机(待执行任务)列表文件
- 模块:执行模块、管理模块、附属属性模块
- 插件完成记录日志邮件等功能
- playbook:剧本编排,实现多任务顺序执行
一、环境配置
# 配置ssh免密授权完成机器互通,形式公私钥
- 假设从A(主)→→→连通→→→B(从)
# 服务器A上执行,假设B服务器的账户名、IP为userB、hostB
ssh-keygen -t rsa
ssh-copy-id userB@hostB
二、装包
当前主机A的linux版本是ubuntu
apt-get install ansible
# 查看安装的版本
ansible --version
三、配置主机清单inventory信息
- ansible默认读取的配置文件为/etc/ansible/hosts,语法类型类INI形式
[servers] # 定义ansible组
ansible_node1 ansible_host=121.47.45.83 # 配置从机域名及地址,此处变量为主机变量
[servers:vars] # 组变量
ansible_ssh_user=zhangs # ansible servers组机器被ssh时使用的账户
ansible_ssh_pass=zhangs@123 # ansible servers组机器被ssh时使用的密码
# 非root账户,提升至root需sudo,下面的参数就是提升权限所用,单词become换成sudo是一样的效果,可能版本升级,兼容原版本形式
ansible_become_pass=zhangs@123test_node 192.168.200.131 ansible_ssh_user=root ansible_ssh_pass='123456' # 配置域名+IP+user+pwd
# 定义组嵌套,可以实现组变量共享
[link:children]
servers
[link:vars] # 组变量
server_name=www.example.com
四、基础模块的应用
ping | yum | copy | fetch | file | template | user | group |
---|---|---|---|---|---|---|---|
service | raw | command | shell | script | cron | get_url | synchronize |
其它模块 | 附属属性 |
4.1、ping模块
- 测试对从节点机器的连接是否可用
ansible all -m ping # 对主机清单内的所有主机进行ping测试
ansible ansible_node1 -m ping # 对主机ansible_node1进行ping测试
4.2、yum模块
- 实现centos主机内的包安装
# 主机test_node安装pandas
ansible test_node -m yum -a 'name=pandas state=present' # 可以不加state参数,默认值present
# 卸载pandas包
ansible test_node -m yum -a 'name=pandas state=absent'
参数名 | 是否必须 | 默认值 | 选项值 | 参数说明 |
---|---|---|---|---|
conf_file | no | 设定远程yum执行时所依赖的yum配置文件 | ||
disable_gpg_check | no | no | yes/no | 在安装包前检查包,只会影响state参数为present或者latest的时候 |
list | no | 只能由ansible调用,不支持playbook | ||
name | yes | 安装的包名,也能如此使用name=python=2.7安装python2.7 | ||
state | no | present | present/latest/absent | 用于描述安装包最终状态,present/latest用于安装包,absent用于remove安装包 |
update_cache | no | no | yes/no | 用于安装包前执行更新list,只会影响state参数为present/latest的时候 |
4.3、copy 模块
- 复制(主机文件复制至从机)
# 拷贝字符至目的地
ansible ansible_node1 -m copy -a 'content="Hello World\n" dest=/home/zhangs/1.txt'
# 拷贝文件至目的地,并配置文件属性
ansible ansible_node1 -m copy -a 'src=monitor dest=/home/zhangs/monitor owner=root group=root mode=0644'
参数名 | 是否必须 | 默认值 | 选项 | 说明 |
---|---|---|---|---|
src | no | 用于定位ansible执行的机器上的文件,须要绝对路径。若是拷贝的是文件夹,那么文件夹会总体拷贝,若是结尾是”/”,那么只有文件夹内的东西被考过去。一切的感受很像rsync | ||
content | no | 用来替代src,用于将指定文件的内容,拷贝到远程文件内 | ||
dest | yes | 用于定位远程节点上的文件,须要绝对路径。若是src指向的是文件夹,这个参数也必须是指向文件夹 | ||
backup | no | no | yes/no | 备份远程节点上的原始文件,在拷贝以前。若是发生什么意外,原始文件还能使用 |
directory_mode | no | 这个参数只能用于拷贝文件夹时候,这个设定后,文件夹内新建的文件会被拷贝。而老旧的不会被拷贝 | ||
follow | no | no | yes/no | 当拷贝的文件夹内有link存在的时候,那么拷贝过去的也会有link |
force | no | yes | yes/no | 默认为yes,会覆盖远程的内容不同的文件(可能文件名同样)。若是是no,就不会拷贝文件,若是远程有这个文件 |
group | no | 设定一个群组拥有拷贝到远程节点的文件权限 | ||
mode | no | 等同于chmod,参数能够为“u+rwx or u=rw,g=r,o=r” | ||
owner | no | 设定一个用户拥有拷贝到远程节点的文件权限 |
4.4、fetch模块
- 复制(从机文件复制至主机),与copy模块作用相反
# 拉取从机文件到本机
ansible ansible_node1 -m fetch -a "src=/home/zhangs/123/1.txt dest=/usr/src"
参数 | 必填 | 默认值 | 选项 | 说明 |
---|---|---|---|---|
dest | yes | 用来存放文件的目录,例如存放目录为backup,源文件名称为/etc/profile在主机pythonserver中,那么保存为/backup/pythonserver/etc/profile | ||
fail_on_missing | no | no | yes/no | 当源文件不存在的时候,标识为失败 |
flat | no | 是否允许覆盖默认行为从hostname/path到/file的,若是dest以/结尾,它将使用源文件的基础名称 | ||
src | yes | 在远程拉取的文件,而且必须是一个file,不能是目录 | ||
validate_checksum | no | yes | yes/no | 当文件fetch以后进行md5检查 |
4.5、file模块
- 文件目录的创建修改删除及属性变更,包含多个模块功能,如copy,assemble和template
# 创建指定目录文件并设定用户及用户组权限
ansible ansible_node1 -m file -a "path=/home/zhangs/2.txt owner=zhangs group=zhangs mode=0644"
# 建立软链接
ansible ansible_node1 -m file -a "src=/home/zhangs dest=/home/zhangs_link owner=zhangs state=link"
参数 | 必填 | 默认 | 选项 | 说明 |
---|---|---|---|---|
follow | no | no | yes/no | 这个标识说明这是系统连接文件,若是存在,应该遵循 |
force | no | no | yes/no | 强制建立连接在两种状况下:源文件不存在(过会会存在);目标存在可是是文件(建立连接文件替代) |
group | no | 文件所属用户组 | ||
mode | no | 文件所属权限 | ||
owner | no | 文件所属用户 | ||
path | yes | 要控制文件的路径 | ||
recurse | no | no | yes/no | 当文件为目录时,是否进行递归设置权限 |
src | no | 文件连接路径,只有状态为link的时候,才会设置,能够是绝对相对不存在的路径 | ||
state | no | file | file/directory/link/touch/absent | 若是是目录不存在,那么会建立目录;若是是文件不存在,那么会建立文件;若是是link,那么软连接会被建立或者修改;若是是absent,那么目录下的全部文件都会被删除,若是是touch,会建立不存在的目录和文件 |
4.6、template模块
- 生成一个模板,将主机文件传输从机(类似与copy模块)
ansible all -m template -a 'src=files/CentOS-Base.repo dest=/etc/yum.repos.d/CentOS-Base.repo owner=root group=root mode=0644'
4.7、user模块
- 实现账户管理
# 创建账户
ansible ansible_node1 -m user -a 'name=lis uid=666 system=yes create_home=no shell=/sbin/nologin state=present'
# 查看账户
id lis
# 修改账户
ansible ansible_node1 -m user -a 'name=lis uid=888'
# 删除账户
ansible ansible_node1 -m user -a 'name=lis state=absent remove=yes'
参数名 | 是否必须 | 默认值 | 选项 | 参数说明 |
---|---|---|---|---|
home | 指定用户的家目录,须要与createhome配合使 | |||
groups | 指定用户的属组 | |||
uid | 指定用的uid | |||
password | 指定用户的密码 | |||
name | 指定用户名 | |||
createhome | 是否建立家目录 yes | |||
system | 是否为系统用户 | |||
remove | 当state=absent时,remove=yes则表示连同家目录一块儿删除,等价于userdel -r | |||
state | 是建立仍是删除 | |||
shell | 指定用户的shell环境 |
4.8、group模块
- 实现组管理
# 创建组
ansible ansible_node1 -m group -a 'name=testG gid=666 state=present'
# 查看组
grep testG /etc/group
# 删除组
ansible ansible_node1 -m group -a 'name=testG gid=666 state=absent'
4.9、service模块
- 对linux机器内服务进行管理
# 启动nginx服务
ansible ansible_node1 -m service -a 'name=nginx state=started'
# 查看nginx服务状态
ansible ansible_node1 -m shell -a 'systemctl is-active nginx'
# 查看nginx服务是否开启自启
ansible ansible_node1 -m shell -a 'systemctl is-enabled nginx'
# 设置nginx服务开机自启动
ansible ansible_node1 -m service -a 'name=nginx enabled=yes state=restarted'
# 停止nginx服务
ansible ansible_node1 -m service -a 'name=nginx state=stopped'
参数名 | 是否必须 | 默认值 | 选项 | 参数说明 |
---|---|---|---|---|
enabled | no | yes/no | 启动os后启动对应service的选项。使用service模块的时候,enabled和state至少要有一个被定义 | |
name | yes | 须要进行操做的service名字 | ||
state | no | stared/stoped/restarted/reloaded | service最终操做后的状态 |
4.10、raw模块
- 实现linux执行命令,其支持管道符与重定向
- 老版本python,需要用到raw,又或者是客户端是路由器,因为没有安装python模块,那就需要使用raw模块
- 建议使用shell和command模块
# 重定向写入数据
ansible ansible_node1 -m raw -a 'echo "hello world" > /home/zhangs/test.txt'
# 管道符应用
ansible ansible_node1 -m raw -a 'cat /home/zhangs/test.txt|grep -Eo hello'
# 匹配正则文件
ansible ansible_node1 -m raw -a 'ls -lrth /home/zhangs/te*'
# 查看从机host信息
ansible ansible_node1 -m raw -a 'hostname|tree'
4.11、command模块(系统默认)
- 实现linux执行命令,命令执行在ssh进程中,使用shell命令执行的会失败
- 不支持管道符和重定向,包含"><&|"都会报错
- 不能解析系统变量
# 查看日期
ansible ansible_node1 -m command -a 'date'
ansible ansible_node1 -a 'date' # 因默认故省略
# 关机
ansible ansible_node1 -a '/sbin/shutdown -t now'
# 创建文件
ansible ansible_node1 -a 'touch /home/zhangs/demo.txt warn=false'
# 执行sh脚本,目录/usr/src/file不存在执行,否则跳过
ansible ansible_node1 -a '/usr/bin/scp_file.sh ag1 ag2 creates=/usr/src/file'
# 查看目录
ansible ansible_node1 -a 'ls /home/zhangs'
ansible ansible_node1 -a 'tree /home/zhangs'
4.12、shell模块
- 实现linux执行命令,调用的是/bin/sh指令(意味着/bin/sh这个文件必须存在),基本涵盖所有命令
- 支持管道和重定向
- 不支持交互式命令,如vim top等
# 创建目录
ansible ansible_node1 -m shell -a "mkdir /home/zhangs/test"
ansible检测到语法使用某模块,而不是shell时,会报[WARNING], 可通过ansible.cfg中配置command_warnings=False或命令后面追加warn=false进行屏蔽
# 创建目录
ansible ansible_node1 -m shell -a "mkdir /home/zhangs/test1 warn=false"
# 查看nginx的进程信息
ansible ansible_node1 -m shell -a 'ps -ef|grep nginx'
# 输出到文件
ansible ansible_node1 -m shell -a 'echo "Hello World">>2.txt'
# 查看文件
ansible ansible_node1 -m shell -a 'cat /home/zhangs/2.txt'
# 执行shell脚本
ansible ansible_node1 -m shell -a '/bin/bash /scripts/test.sh'
# cd目录编译并安装
ansible ansible_node1 -m shell -a "./configure && make && make install" chdir=/xxx/yyy/
# 查看HOSTNAME内置变量值
ansible ansible_node1 -m shell -a 'echo ${HOSTNAME}'
4.13、script模块
- 实现linux执行命令,从机上执行主机上的脚本(不仅限于sh类型脚本,其它类型须指明解释器)
# 执行主机sh脚本并将结果输出到从机文件
ansible ansible_node1 -m script -a "/home/zhuz/mk.sh & > /tmp/log"
# 查看从机结果
ansible ansible_node1 -m shell -a 'cat /tmp/log'
4.14、cron模块
- cron模块用于管理计划任务
ansible ansible_node1 -m cron -a 'name="a job for reboot" special_time=reboot job="/some/job.sh"'ansible ansible_node1 -m cron -a 'name="yum autoupdate" weekday="2" minute=0 hour=12 user="rootansible ansible_node1 -m cron -a 'backup="True" name="test" minute="0" hour="5,2" job="ls -alh > /dev/null"'ansilbe ansible_node1 -m cron -a 'cron_file=ansible_yum-autoupdate state=absent'
参数名 | 是否必须 | 默认值 | 选项 | 参数说明 |
---|---|---|---|---|
backup | 对远程主机上的原任务计划内容修改以前作备份 | |||
cron_file | 若是指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划 | |||
day | 日(1-31,,/2,……) | |||
hour | 小时(0-23,,/2,……) | |||
minute | 分钟(0-59,,/2,……) | |||
month | 月(1-12,,/2,……) | |||
weekday | 周(0-7,*,……) | |||
job | 要执行的任务,依赖于state=present | |||
name | 该任务的描述 | |||
special_time | 指定何时执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly | |||
state | 确认该任务计划是建立仍是删除 | |||
user | 以哪一个用户的身份执行 |
4.15、get_url模块
- 用于从http、ftp、https服务器上下载文件(相似于wget)
# 从web拉取文件到从机
ansible ansible_node1 -m get_url -a 'url= http://10.1.1.11/favicon.ico dest=/home/zhangs'
参数名 | 是否必须 | 默认值 | 选项 | 参数说明 |
---|---|---|---|---|
sha256sum | 下载完成后进行sha256 check | |||
timeout | 下载超时时间,默认10s | |||
url | 下载的URL | |||
url_password、url_username | 主要用于须要用户名密码进行验证的状况 | |||
use_proxy | 是否使用代理,代理需事先在环境变动中定义 |
4.16、synchronize模块
- 使用rsync同步文件
# 将主机file目录推送到从机的/home/zhangs目录下
ansible ansible_node1 -m synchronize -a 'src=file dest=/home/zhangs/ compress=yes' # --exclude=.Git忽略同步.git结尾的文件
#
参数名 | 是否必须 | 默认值 | 选项 | 参数说明 |
---|---|---|---|---|
archive | 归档,至关于同时开启recursive(递归)、links、perms、times、owner、group、-D选项都为yes ,默认该项为开启 | |||
checksum | 跳过检测sum值,默认关闭 | |||
compress | 是否开启压缩,默认开启 | |||
copy_links | 复制连接文件,默认为no ,注意后面还有一个links参数 | |||
delete | 同步后保持主从文件一致,以发送方的文件作为参考,默认no | |||
dest | 目录路径 | |||
dest_port | dest_port:默认目录主机上的端口 ,默认是22,走的ssh协议 | |||
dirs | 传速目录不进行递归,默认为no,即进行目录递归 | |||
rsync_opts | rsync参数部分 | |||
set_remote_user | 主要用于/etc/ansible/hosts中定义或默认使用的用户与rsync使用的用户不一样的状况 | |||
mode | push或pull 模块,push模式的话,通常用于从本机向远程主机上传文件,pull 模式用于从远程主机上取文件,默认push |
4.17、其它模块
- mount模块:配置挂载点
- unarchive模块:解压文件模块
- apt模块:ubuntu包安装
- lineinfile模块:实现文件内容正则替换==Ctrl+R
- systemd模块:服务管理模块
- docker_image模块:docker镜像处理
- docker_container模块:docker容器处理
- docker_compose模块: docker服务编排管理
- vault模块:加密,防止pwd明文存储到文件,可用此加密存储
4.18、附属属性
- chdir=/xxx指定路径
ansible test_node1 -m shell -a 'touch a.txt chdir=/root/test'
- creates=1.txt判断指定文件是否存在,如果不存在,就执行命令,如果存在,命令将不再运行
ansible test_node1 -m shell -a 'touch 1.txt chdir=/root/test creates=1.txt'
- removes=1.txt判断指定文件是否存在,如果存在,执行后面的操作
ansible test_node1 -m shell -a 'rm -f /root/test/1.txt removes=/root/test/1.txt'
五、核心模块的应用
如《第四章》不难看出,命令的执行时独立的,有没有将多个命令编排在一起的呢?
playbook可以定义为一些列任务的配置集合。也称为剧本,每一个playbook都包含一系列的任务,每个任务在Ansible中称为play。Playbook的写法采用缩排的方式呈现,结构通过缩进来表示,连续的项目通过减号 “-”来表示。一个name仅代表一个play,每个play下只能跟一个命令(如command),当存在多个命令时只会执行最后一个命令
5.1、playbook基本demo
- yaml文件遵循2个空格缩进,编辑ansible_demo.yml
- name: Ansible Project Demo # 剧本名,我觉得叫项目名更合适,随意起hosts: ansible_node1 # 被控端域名或IP,在inventory中需要声明tasks:- name: touch myfile # 任务的名称,随意起- file: path=/home/zhangs/demo.txt state=touch mode=0755 # 利用file模块实现创建文件
小节拓展
如果不用file文件去创建文件,还有别的方式吗?command,但那需要两次command命令才能实现相同的功能,如下
- name: Ansible Project Demo # 剧本名,我觉得叫项目名更合适,随意起hosts: ansible_node1 # 被控端域名或IP,在inventory中需要声明tasks:- name: create myfilecommand: touch /home/zhangs/demo.txt- name: change the modcommand: chmod 755 /home/zhangs/demo.txt
- 选用合适的模块会事半功倍
5.2、校验配置yml文件合法性
ansible-playbook -i inventory --syntax-check ansible_demo.yml
如果ansible配置文件位置,选择的是系统默认,那么inventory=/etc/ansible/hosts,否则填写自定义位置
5.3、任务执行
ansible-playbook -i /etc/ansible/hosts ansible_demo.yml
①配置文件路径如果是默认,可不加参数-i
②如果想看过程输出,可以追加参数-verbose
③支持ansible从机正则匹配规则,如果从机数量过多,可用--list-host
来查询匹配到的主机汇总
5.4、提权become
- name: Ansible Project Demo # 剧本名,我觉得叫项目名更合适,随意起hosts: ansible_node1 # 被控端域名或IP,在inventory中需要声明tasks:- name: create myfilecommand: touch /home/zhangs/demo.txt- name: change the modcommand: chmod 755 /home/zhangs/demo.txt- name: latest httpd version installedbecome: yes # 安装包需要提权以便系统目录文件的写入,sudo升权密码已在Inventory标注yum:name: httpdstate: latest
- 其它提权形式
- ansible的become就是提权的意思。ansible.cfg中become通常设置为false,具体的task操作中再指定become: true。这样可以确保使用最小权限进行操作,以防误操作
- 提权操作时ssh登陆帐号还是非root帐号(该帐号有sudo权限),特别注意become_user不能写原ssh登陆的非root用户,一定要写root,或者不写默认为root。这样才能执行成功
- 如果主机清单hosts中没有指定become的密码,那么执行ansible-playbook install.yml加-K参数,手动输入ssh用户的sudo密码(不是root密码)
- ssh登陆时可以使用密码,也可以使用基于密钥的登陆(免密)。但是执行特权命令时必须要提权,即执行命令时加入-K参数,输入ssh用户的提权密码
5.5、debug调试
5.6、playbook辅助参数
# 自定义参数引用时,可以用关键字vars。在剧本级别中定义变量时,与hosts同级;在任务级别中定义,与tasks或command同级皆可
vars:custom_item: custom_value # 引用形式双大括号为{{custom_item}},如在inventory文件中有过声明,可直接引用# 自定义yml文件引用,可以用关键字include,与task同级
include: other.yml # 主要用于不同项目间的批量任务处理,每个项目都有自己专属的yaml文件# with_item应用,引用形式为{{item}},实现多个包的安装,多变量信息读取执行,与command、file等模块同级
with_items:-'docker-ce'-'nginx'-'git'# cd目录执行及指定解释器,与command、file等模块同级
args:chdir: /xxx/yyyexecutable: /bin/bash# 返回命令(shell、command等)执行的结果, 与command、file等模块同级
register: result# 根据命令执行结果决定任务执行情况,与command、file等模块同级
when: result|success # 如果上面的result为success,则该任务执行
5.7、Handler
章节《5.1》中为playbook剧本任务的一种最常见形式task,下面我们需要了解另一种形式,也就是handler,有没有想到厨师这个职业,是的!就是炒菜,意味着只有买了原料之后才能炒菜,假设买每一种菜都当作一个任务,所有任务完成之后才能执行最终要做的炒菜任务。。。话不多说,为什么要有这么个东西?再举个简单例子"老师准备上课,但是她的课本进度适中,她考虑加快进度迎头赶上,进入教室例行学生的考验,哈哈,叫到了张三、李四、王五、赵六,回答的一塌糊涂,老师很生气,于是将课程加快这个想法放弃,发放试卷加深学生对课本知识的汲取,以防学生们考得太差。。真难啊,老师心想,走出了教室,不久下课铃响了。。。"在老师考校几个学生都分别当作一个任务,当所有任务失败后,讲课的任务被迫放弃,反言之,只有所有任务成功才能继续学习新内容
。我想你大概理解了这段话的意思!所有任务完成→→最终任务
- 执行单个handler任务样例
- name: Ansible Project Demo # 剧本名,我觉得叫项目名更合适,随意起hosts: ansible_node1 # 被控端域名或IP,在inventory中需要声明tasks:- name: create myfilecommand: touch /home/zhangs/demo.txt- name: change the modcommand: chmod 755 /home/zhangs/demo.txtnotify: rm myfile # 任务完成执行handler任务handlers:- name: rm myfilecommand: rm /home/zhangs/demo.txt
上面的例子只是执行了一个handler,有没有方法执行多个handler?这就需要一个另一个关键字listen,你可以将之理解成组名
- 执行多个handler任务样例
- name: Ansible Project Demo # 剧本名,我觉得叫项目名更合适,随意起hosts: ansible_node1 # 被控端域名或IP,在inventory中需要声明tasks:- name: create myfilecommand: touch /home/zhangs/demo.txt- name: change the modcommand: chmod 755 /home/zhangs/demo.txtnotify: handler group # 任务完成执行handler任务组handlers:- name: rm myfilelisten: handler groupcommand: rm /home/zhangs/demo.txt- name: create myfile againlisten: handler groupcommand: touch /home/zhangs/demo.txt
在playbook中,只要有task执行失败,则playbook终止,即使是与handler关联的task在失败的task之前运行成功了,handler也不会被执行,那么如何保证多任务执行时handler任务不会受其它任务影响?关键字force_handlers派上用场
- 任务互不干扰
- name: Ansible Project Demo # 剧本名,我觉得叫项目名更合适,随意起hosts: ansible_node1 # 被控端域名或IP,在inventory中需要声明force_handlers: yes # 保证任务成功执行的handler任务也可以被执行tasks:- name: create myfilecommand: touch /home/zhangs/demo.txt- name: change the modcommand: chmod 755 /home/zhangs/demo.txtnotify: handler group # 任务完成执行handler任务组- name: a task which fails because the package doesn't exist # 创建一个必定失败的项目验证任务间互不干扰yum:name: notapkgstate: latesthandlers:- name: rm myfilelisten: handler groupcommand: rm /home/zhangs/demo.txt- name: create myfile againlisten: handler groupcommand: touch /home/zhangs/demo.txt
##如果与handler关联的task还未执行,在其前的task已经失败,整个play终止,则handler未被触发,也不会执行。
在《5.7 Handler》介绍中,有得到剧本任务执行顺序:所有任务完成→→最终任务,那么有没有方式不等到所有任务完成就去执行最终任务?关键字meta可以实现
- 立即执行handler任务
- name: Ansible Project Demo # 剧本名,我觉得叫项目名更合适,随意起hosts: ansible_node1 # 被控端域名或IP,在inventory中需要声明force_handlers: yes # 保证任务成功执行的handler任务也可以被执行tasks:- name: create myfilecommand: touch /home/zhangs/demo.txt- name: change the modcommand: chmod 755 /home/zhangs/demo.txtnotify: handler group # 任务完成执行handler任务组- meta: flush_handlers # change the mod这个任务一经完成(无关所有任务完不完成),立即执行handler任务- name: a task which fails because the package doesn't exist # 创建一个必定失败的项目验证任务间互不干扰yum:name: notapkgstate: latesthandlers:- name: rm myfilelisten: handler groupcommand: rm /home/zhangs/demo.txt- name: create myfile againlisten: handler groupcommand: touch /home/zhangs/demo.txt
5.8、最终版
需要什么取什么,可能不一定满足需要哈,仅供参考!!
- name: play to setup web serverhosts: alltasks:# 任务一:安装httpd包- name: latest httpd version installedyum:name: httpdstate: latest# 任务二:复制文件 - name: correct index.html is presentcopy: src: files/index.htmldest: /var/www/html/index.html# 任务三: 开启httpd服务并配置开机自启 - name: start httpd serviceservice:name: httpdstate: startedenabled: true# 任务四: 文件内容替换- name: 'change sshd_config'lineinfile:dest: /etc/ssh/sshd_configregexp: "{{ item.regexp }}"line: "{{ item.line }}"state: presentwith_items:#- regexp: "^#PermitRootLogin yes"# line: "PermitRootLogin no"# Both methods have the same effect- { regexp: "PermitRootLogin yes",line: "PermitRootLogin no" }# 任务五: 安装Docker- name: Install Dockerapt:name: docker.iostate: present# 任务六: 启动Docker服务并设置开机自启- name: start docker servicesystemd: centos7开启服务,添加到启动项name: dockerstate: startedenabled: true# 任务七: 拉取nginx镜像- name: Pull Docker imagedocker_image:name: nginxstate: present# 任务八: 启动由nginx镜像生成的服务- name: Run Docker containerdocker_container:name: mynginximage: nginxstate: startedports:- "80:80"volumes:- "/var/www/html:/usr/share/nginx/html"# 任务九: docker配置文件文件变更,触发docker服务重启- name: provide docker-ce configfiletemplate:src: daemon.json.j2 提供配置文件dest: /etc/docker/daemon.jsonnotify: restart docker 配置文件修改了触发通知机制,提醒handler# 任务十: 关停项目,清除遗留,开启项目- name: project restartbecome: yesshell: /home/zhangs/miniconda3/envs/web_server/bin/supervisorctl -c server.conf stop all && lsof -i:4057|awk 'NR>1 {print $2}'|xargs -i kill {}|/home/zhangs/miniconda3/envs/web_server/bin/supervisorctl -c server.conf reloadargs:chdir:/home/zhangs/web_server
六、引申
- 其它相关资料
七、结束!
相关文章:

一篇教你学会Ansible
前言 Ansible首次发布于2012年,是一款基于Python开发的自动化运维工具,核心是通过ssh将命令发送执行,它可以帮助管理员在多服务器上进行配置管理和部署。它的工作形式依托模块实现,自己没有批量部署的能力。真正具备批量部署的是…...

Mysql第四篇---数据库索引优化与查询优化
文章目录 数据库索引优化与查询优化索引失效案例数据准备1. 全值匹配2 最佳左前缀法则(联合索引)主键插入顺序4 计算、函数导致索引失效5 类型转换(自动或手动)导致索引失效6 范围条件右边的列索引失效7 不等于(!或者<>)索引失效8 is null可以使用索引, is not null无法使…...

SpringBoot手动获取实例
1.首先创建一个接口里面是关于建库建表的方法 public interface MetaMapper {//三个核心建表方法void createExchangeTable();void createQueueTable();void createBingdingTable(); } 2.启动类中定义一个ConfigurableApplicationContext 类型的变量context接收SpringApplica…...

栈(Stack)的概念+MyStack的实现+栈的应用
文章目录 栈(Stack)一、 栈的概念1.栈的方法2.源码分析 二、MyStack的实现1.MyStack的成员变量2.push方法3.isEmpty方法和pop方法4.peek方法 三、栈的应用1.将递归转化为循环1.调用递归打印2.通过栈逆序打印链表 栈(Stack) 一、 栈…...

C语言进阶第九课 --------动态内存管理
作者前言 🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 🎂 作者介绍: 🎂🎂 🎂 🎉🎉🎉…...

嵌入式 Tomcat 调校
SpringBoot 嵌入了 Web 容器如 Tomcat/Jetty/Undertow,——这是怎么做到的?我们以 Tomcat 为例子,尝试调用嵌入式 Tomcat。 调用嵌入式 Tomcat,如果按照默认去启动,一个 main 函数就可以了。 简单的例子 下面是启动…...

初始化固定长度的数组
完全解析Array.apply(null,「length: 1000」) 创建固定长度数组,并且初始化值。直接可以使用map、forEach、reduce等有遍历性质的方法。 如果直接使用Array(81),map里面的循环不会执行。 //方法一 Array.apply(null, { length: 20 })//方法二 Array(81)…...

实现基于 Jenkins 的多服务器打包方案
实现基于 Jenkins 的多服务器打包方案 在实际项目中,我们经常会遇到需要将一个应用程序或服务部署到不同的服务器上的需求。而使用 Jenkins 可以很方便地自动化这个过程。 设置参数 首先,我们需要设置一些参数,以便在构建过程中指定要部署…...

探索现代IT岗位:职业机遇的海洋
目录 1 引言2 传统软件开发3 数据分析与人工智能4 网络与系统管理5 信息安全6 新兴技术领域 1 引言 随着现代科技的迅猛发展,信息技术(IT)行业已经成为了全球经济的关键引擎,改变了我们的生活方式、商业模式和社会互动方式。IT行…...

np.linspace精确度
前言 今天发现一个大坑,如果是序列是小数的话,不要用np.linspace,而要用np.arrange指定等差序列。比如入下图中a和b是一样的意思,但是b是有较大误差的。 anp.arange(0,4,0.4) bnp.linspace(0,4,10) print("a",a) prin…...

GD32_定时器输入捕获波形频率
GD32_定时器输入捕获波形频率(多通道轮询) 之前项目上用到一个使用定时器捕获输入采集风扇波形频率得到风扇转速的模块,作为笔记简单记录以下当时的逻辑结构和遇到的问题,有需要参考源码、有疑问或需要提供帮助的可以留言告知 。…...

单窗口单IP适合炉石传说游戏么?
游戏道具制作在炉石传说中是一个很有挑战的任务,但与此同时,它也是一个充满机遇的领域。在这篇文章中,我们将向您展示如何在炉石传说游戏中使用动态包机、多窗口IP工具和动态IP进行游戏道具制作。 作者与主题的关系:作为一名热爱炉…...

win11安装docekr、docker-compose
1.docker安装 下载地址:Install Docker Desktop on Windows | Docker Docs 出问题别慌,看清楚提示信息,cmd更新wsl,什么是wsl,百度好好理解一下哦 2.docker-compose安装 还是去官方看看怎么说的,然后跟着处…...

Postman的简单使用
Postman简介 官网 Postman是Google公司开发的一款功能强大的网页调试与发送HTTP请求,并能运行测试用例的Chrome插件 使用Postman进行简单接口测试 新建测试 → 选择请求方式 → 请求URL,下面用百度作为例子: 参考文档 [1] Postman使用教程…...

信号继电器驱动芯片(led驱动芯片)
驱动继电器需要配合BAV99(防止反向脉冲)使用 具体应用参考开源项目 电阻箱 sbstnh/programmable_precision_resistor: A SCPI programmable precision resistor (github.com) 这个是芯片的输出电流设置 对应到上面的实际开源项目其设置电阻为1.5K&…...

IDEA配置HTML和Thymeleaf热部署开发
IDEA配置HTML和Thymeleaf热部署开发 1.项目配置2. IDEA配置3. 使用 需求:现在我们在开发不分离项目的时候(SpringBootThmeleaf)经常会改动了类或者静态html文件就需要重启一下服务器, 这样不仅时间开销很大,而且经常重…...

Nginx动静分离
为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。 在动静分离的tomcat的时候比较明显,因为tomcat解析静态很慢,其实这些原理的话都很好理解,简单来说&…...

Spring中AOP详解
目录 一、AOP的概念 二、AOP的底层实现原理 2.1 JDK的动态代理 2.1.1 invocationhandler接口 2.1.2 代理对象和原始类实现相同的接口 interfaces 2.1.3 类加载器ClassLoador 2.1.4 编码实现 2.2 Cglib动态代理 2.2.1 Cglib动态代理编码实现 三、AOP如何通过原始对象的id获取到代…...

Unity DOTS系列之Filter Baking Output与Prefab In Baking核心分析
最近DOTS发布了正式的版本, 我们来分享一下DOTS里面Baking核心机制,方便大家上手学习掌握Unity DOTS开发。今天给大家分享的Baking机制中的Filter Baking Output与Prefab In Baking。 对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础…...

Matlab读写操作
随机生成一个3*3矩阵,对矩阵进行按列升序排列 >> Arand(3,3); >> [B, ~] sort(A, 2); >> B B 0.4898 0.6797 0.70940.4456 0.6551 0.75470.1626 0.2760 0.6463在不同数值类型下显示π的值 1、默认数值类型 >> p_defa…...

Android 开发技巧:音乐播放器的后台处理【Service、Handler、MediaPlayer】
给定部分完成的MusicPlayer项目,实现其中未完成的service部分: 1、创建MusicService类,通过service组件实现后台播放音乐的功能; 2、在MainActivity中通过ServiceConnection连接MusicService,实现对音乐播放的控制&…...

使用Windows平台的Hyper-V虚拟机安装CentOS7的详细过程
Hyper-V虚拟机安装CentOS7 前言常见Linux系统CentOSUbuntuDebianKaliFedoraArch LinuxMintManjaroopenSUSE Hyper-V开启Hyper-V打开Hyper-V Hyper-V的使用新建虚拟机开始安装分区配置开始安装 修改yum源为阿里源 前言 作为一名开发者,就服务器而言,接触最…...

某马机房预约系统 C++项目(二) 完结
8.4、查看机房 8.4.1、添加机房信息 根据案例,我们还是先在computerRoom.txt中直接添加点数据 //几机房 机器数量 1 20 2 50 3 1008.4.2、机房类创建 同样我们在头文件下新建一个computerRoom.h文件 添加如下代码: #pragma once #include<i…...

npm 安装到指定文件夹
创建一个文件夹,用vscode或者cmd打开, 执行 npm install --prefix ./ 路径 包名, npm install --prefix ./ 包名 , 就会将包安装在当前文件夹, 例如: npm install --prefix ./ -g oppo-minigame…...

自建的离散傅里叶变换matlab程序实现及其与matlab自带函数比较举例
自建的离散傅里叶变换matlab程序实现及其与matlab自带函数比较举例 在matlab中有自带的离散傅里叶变换程序,即fft程序,但该程序是封装的,无法看到源码。为了比较清楚的了解matlab自带的实现过程,本文通过自建程序实现matlab程序&…...

Vue图片路径问题(动态引入)
vue项目中我们经常会遇到动态路径的图片无法显示的问题,以下是静态路径和动态路径的常见使用方法。 1.静态路径 在日常的开发中,图片的静态路径通过相对路径和绝对路径的方式引入。 相对路径:以.开头的,例如./、../之类的。就是…...

项目部署Linux步骤
1、最小化安装centos7-环境准备 安装epel-release 安装epel-release,因为有些rpm包在官方库中找不到。前提是保证可以联网 yum install -y epel-release 修改IP net-tools net-tool:工具包集合,包含ifconfig等命令 yum install -y net-…...

UG\NX二次开发 在资源栏(左侧面板)中添加按钮
文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 感谢粉丝订阅 感谢 apolloryd 订阅本专栏,非常感谢。 简介 UG\NX二次开发 在资源栏(左侧面板)中添加按钮,下面提供了帮助说明,在 UGOPEN 文件夹下有示例。 C++语言在UG二次…...

Proteus仿真--量程自动切换数字电压表(仿真+程序)
本文主要介绍基于51单片机的量程自动切换数字电压表Proteus仿真设计(完整仿真源文件及代码见文末链接) 简介 硬件电路主要分为单片机主控模块、AD转换模块、量程选择模块以及数码管显示模块 (1)单片机主控模块:单片…...

如何使用ArcGIS Pro制作一张地形图
01数据来源 本教程所使用的数据是从水经微图中下载的DEM数据,除了DEM数据,常见的GIS数据都可以从水经微图中下载,你可以通过关注“水经注GIS”,然后在后台回复“微图”即可获取软件下载地址,当然也可以直接在水经注…...