2.0 Ansible Ad-Hoc命令
概览
什么是 ad-hoc commands 呢 ? 下面这样就是
ansible all -a "free -h"
也就是在命令行直接执行Ansible命令,不是我装逼,这个没找到很好的翻译,官方文档和一些国外的书籍都这么称呼
在命令行直接运行Ansible命令,基本上只存在于测试环节,甚至有时候测试都不用,毕竟生产环境都是写playbook管理,否则有点什么操作大家都冲到机器上执行个Ansible远程命令,也没啥记录,时间久了其不乱成一坨,而写成playbook尤其是在配合git进行管理,则可以清楚的看到服务修改的来龙去脉
我们在查看官方文档,某个模块如何用的时候,官方文档给的示例基本也是playbook形式
为什么需要 ad-hoc commands 呢 ?
不过在一些特殊情况下,直接在命令行执行Ansible命令有一个优点,那就是快,比如新上线某个服务严重拖垮机器资源,此时根本来不及再去写什么完整的playbook,直接一行命令批量把这个服务先停掉再说
Ansible ad-hoc command适合新手学习、简单测试,能够帮助我们快速了解Ansible强大的功能,所有能够使用Ansible命令行直接实现的操作,都可以通过书写playbook实现
环境准备
和之前的环境一致
[root@192-168-31-106 ~]# cat /etc/ansible/hosts [allservers] 192.168.31.106 192.168.31.100 192.168.31.101 192.168.31.102 [webservers] 192.168.31.100 192.168.31.101 192.168.31.102
基础
ansible group-or-host [-m MODULE_NAME] [-a MODULE_ARGS]
查看帮助
ansible -h OR man ansible
上面我们查看内存的命令,如果写完整是这样
ansible all -m shell -a "free -h"
即默认的执行模块是shell命令
参数的顺序无关紧要,上面的命令写成这样也正确
ansible -m shell -a "free -h" all
输出详细信息
-v 输出详细信息 -vvv 输出更详细信息 -vvvv 调试(debug)模式
并发执行
Ansible默认是采用并发执行的方式,管理多台机器,反复执行下面的命令观察结果的顺序
ansible all -a "hostname"
可以看到每次的输出顺序是不通的,可以通过参数控制并发的个数
ansible all -a "hostname" -f 1 ansible all -a "hostname" --forks 10 #参数的长写法,同-f功能一致
Ansible默认是5个并发执行
拿到目标机器的全部环境信息
ansible 192.168.31.100 -m setup
这个命令会输出大量目标机器的详细信息,如操作系统、IP地址、内存、磁盘等,返回的是一个JSON格式数据,输出之详细我们甚至可以用这种方法在生产环境上收集机器的信息,当然过滤这些信息最好拿python之类的程序进行JSON格式化解析
注意我们这里的IP 192.168.31.100 ,是已经写在主机清单里的,如果填写一个主机清单里没有的IP地址,则会报错:
[root@192-168-31-106 ~]# ansible 192.168.31.120 -m setup [WARNING]: Could not match supplied host pattern, ignoring: 192.168.31.120 [WARNING]: No hosts matched, nothing to do
后面我们学习变量的时候,会讲到利用这些信息做些特定操作,如判断目标机器是CentOS6安装一个包,如果是CentOS7则安装另外一个包之类
command 与 shell
前面我们已经使用过这种方法,如查看远程机器的内存:
ansible all -m command -a "free -h" OR ansible all -a "free -h" ansible all -m shell -a "free -h"
使用
-m shell功能更为强大,如普通执行远程命令的方式不支持管道,但普通的命令执行方式因为其功能少,相对来说安全性好
https://docs.ansible.com/ansible/2.9/modules/shell_module.html https://docs.ansible.com/ansible/2.9/modules/command_module.html
幂等性
幂等性是指如果系统已经处于期望的状态,则对系统什么也不操作。
下面我们看下,使用Ansible的YUM模块给机器安装上nginx,借这个例子再重点看下Ansible的幂等性
ansible webservers -m ping ansible webservers -m yum -a "name=nginx state=present"
命令执行第2次,就可以看到全是绿色的,说明机器状态无变化
可不可以不实用YUM模块,就使用Shell命令呢,可以,如下
ansible webservers -m shell -a "yum install nginx -y"
我们可以看到,输出内容有蓝色警告内容,提醒我们建议使用YUM模块而不是Shell YUM命令,并且更关键的是后面3台机器的输出内容都是黄色的,表示机器状态已被修改,即便我们多次执行
ansible webservers -m shell -a "yum install nginx -y",输出内容依旧是黄色CHANGED的状态
可以看到要想让Ansible完美支持幂等性,需要尽可能不使用直接的Shell命令,而是多使用Ansible自带的模块,后面我们还会学习到Ansible其它模块
使用Ansible自带的模块而不是原生shell命令有2个好处:
- 方便维护,Ansible模块的语法统一,而shell脚本如果写的复杂,难以维护
- 支持幂等性(idempotency)
为什么非要强调幂等性的重要呢,比如说一个常见的场景,老板说让初始化一台新机器,安装nginx提供七层的负载均衡服务,团队之前已经写好了对应的playbook,理想情况下是直接一条Ansible命令完成初始化,但是谁也不能保证永远不报错,一旦有什么错误,或者新增什么新的需求,就需要这套Ansible服务支持反复执行,状态始终是预期的状态,换句话说我们希望写的playbook文件是一种对状态的描述,类似于"保持nginx出于安装并且启动的状态"而不是"安装nginx"
理想虽好,但是实际工作中想要保证Ansible剧本里完全没有直接运行shell命令的方式,全部使用的是Ansible自带的模块,难,非常难,但是我么至少要保证别挖大坑,避免第一次执行脚本正常,而多次执行某个脚本系统处于什么状态,已经完全不可预期的情况
类似的,我们用copy模块测试幂等性的效果
ansible all -m copy -a "src=/root/node_exporter-1.0.0.linux-amd64.tar.gz dest=/tmp" ansible all -m copy -a "src=/root/node_exporter-1.0.0.linux-amd64.tar.gz dest=/tmp" 上面的命令连续执行两次,可以发现第1次输出为黄色,表明系统已经做了修改,第2次输出为绿色表明无任何修改,具有一定的幂等性
限制针对某台机器执行
假设我们之前的主机清单是这样的
[root@192-168-31-106 ~]# cat /etc/ansible/hosts [webservers] 192.168.31.100 192.168.31.101
即已经有了2台webserver服务器,但现在的场景是,量太大,机器抗不住,需要初始化一台新的webserver机器加入集群,因此我们修改主机清单,增加一行IP,如下
[root@192-168-31-106 ~]# cat /etc/ansible/hosts [webservers] 192.168.31.100 192.168.31.101 192.168.31.102
此时我们进行相关部署操作的时候,希望限定在对102机器执行操作,其它不动,我们可以使用
--limit ${ip}参数
ansible webservers -m yum -a "name=nginx state=present" --limit "192.168.31.102"
管理系统users和groups
在shell命令中,我们使用
useradd、usermod、userdel来管理用户,使用
groupadd、groupdel、groupmod来管理组
在Ansible中分别使用
user和
group进行管理
管理组 group
ansible 192.168.31.100 -m group -a "name=test1 state=present" #增加test1组 ansible 192.168.31.100 -m group -a "name=test1 state=absent" #删除test1组 ansible 192.168.31.100 -m group -a "name=test1 state=present gid=2000" #指定组的gid
管理用户 user
ansible 192.168.31.100 -m user -a "name=test2 state=present" #增加用户 ansible 192.168.31.100 -m user -a "name=test2 state=absent" #删除用户 ansible 192.168.31.100 -m user -a "name=test3 password={{ '123456' | password_hash('sha512', 'mysecretsalt') }} state=present" #创建用户并指定密码
更多参数,参考官方文档
https://docs.ansible.com/ansible/2.9/modules/user_module.html https://docs.ansible.com/ansible/2.9/modules/group_module.html
管理包
上面我们已经看到,Ansible的yum模块来管理包,Ansible还有一个通用的包管理模块,可跨平台支持不同的操作系统
ansible 192.168.31.100 -m package -a "name=git state=present"
管理文件和目录
1 查看文件的状态信息
#该功能类似 stat ansible all -m stat -a "path=/etc/profile"
2 把本地文件或目录(在管理机器上)拷贝到远程机器上
#该功能类似 scp 、 rsync ansible 192.168.31.100 -m copy -a "src=/etc/hosts dest=/tmp/hosts"
其中
src可以是文件,可以是目录,如果是目录的话注意末尾是否有斜线,行为不同
- 有斜线,拷贝目录里的内容,不包括目录本身
- 无斜线,连同目录本身和目录里的内容一块拷贝
ansible 192.168.31.100 -m copy -a "src=/etc/sysconfig/network-scripts dest=/tmp" ansible 192.168.31.100 -m copy -a "src=/etc/sysconfig/network-scripts/ dest=/tmp"
rsync也有类似的逻辑,在实际使用的时候多加测试即可
与cp命令不同,类似 cp /etc/* 这种带星号的逻辑,不支持
3 把远程机器的文件拉到本地
#这种场景应用的比较少,我们演示一种情况,备份所有机器的/etc/hosts到管理机器上 ansible all -m fetch -a "src=/etc/hosts dest=/tmp/xtmp" #可以看到,还贴心的自动生成了IP文件夹以区分
4 创建目录和文件
#类似 touch mkdir ansible 192.168.31.100 -m file -a "path=/tmp/test10 mode=644 state=directory" #创建目录 ansible 192.168.31.100 -m file -a "path=/tmp/test6.txt mode=0644 state=touch" #创建文件
5 删除目录和文件
ansible 192.168.31.100 -m file -a "path=/tmp/test10 state=absent"
更多文件操作的细节功能,参考官方文档
https://docs.ansible.com/ansible/2.9/modules/file_module.html https://docs.ansible.com/ansible/2.9/modules/copy_module.html
管理定时任务
话不多说,我们直接看个简单的效果
ansible 192.168.31.100 -m cron -a "name='cron_test' minute='*/2' job='date >> /tmp/tmp.txt' state='present'" ansible 192.168.31.100 -m cron -a "name='cron_test' minute='*/2' job='date >> /tmp/tmp.txt' state='absent'"
参考链接
https://docs.ansible.com/ansible/2.9/modules/cron_module.html
提升权限
执行Ansible的用户默认就是当前使用的用户,如果管理机器上用root执行,到目标机器上也是root用户,可以通过参数更改使用的用户
ansible all -a "whoami" -u nginx
SSH免密码配置是针对用户的,如果我们用其它的用户去执行Ansible命令,那么这个用户也需要配置免密
如果这个普通用户,配置了sudo免密切到root,则可以加上参数
-b OR --become,这样需要提权才能执行的操作才能正常执行
ansible all -a "whoami" -u nginx -b
可能遇到的报错
1 No h 8000 osts matched
遇到此类报错,一般都是主机清单没有配置正确,如果确认已经配置正确,还可以通过设定环境变量的方式指定主机清单文件,如
ANSIBLE_INVENTORY=/etc/ansible/hosts ansible all -a "hostname"
上面的命令直接执行,明确告诉Ansible的路径,也可以把相关环境变量写到脚本里,或者
/etc/profile
2 The authenticity of host '192.168.31.100' can't be established
类似这种报错是因为,默认SSH远程有一个输入yes确认的过程,我们可以随便用一个远程命令测试下,把yes输入上,或者使用如下的环境变量
ANSIBLE_HOST_KEY_CHECKING=False ansible all -a "hostname"
总结
本篇文章,我们主要是围绕着Ansible Ad-Hoc命令,以一些重点模块为例,展开讲一些Ansible的主要功能,主要的目的是让大家对Ansible能够干啥有个直观的认识,另外还简要探讨了幂等性这个重要的概念,有了这些基本的认识,为我们紧接着学习playbook打下良好的基础
- Ansible Ad-Hoc命令
- Ansible Ad-Hoc 常用命令
- ASP.NET 2.0中执行数据库操作命令之二
- 重新注册.net2.0、4.0命令
- Vue2.0 之 自带浏览器里无法打开(兼容IE处理) - 解决方案 命令
- ansible 自动化运维工具——ansible Ad-Hoc 使用
- C# ping命令实现:利用c#2.0新增的Ping类
- 在IIS上重新注册.NET Framework 2.0的命令和参数详解
- Hadoop 2.0命令手册
- kali2.0 2017国内源添加+系统信息相关命令+中文输入法安装
- Xamarin中使用EF Core 2.0应该如何使用数据迁移命令生成迁移文件
- 解决ASP 2.0中GridView控件的删除、插入、编辑命令操作客户端确认问题的另一方法
- SP2010和Windows PowerShell 2.0--PowerShell脚本方法和创建自定义命令
- 在ASP.NET 2.0中操作数据之七十:配置数据库连接和命令等级设置
- ASP.NET 2.0中执行数据库操作命令之一
- U-boot用tftp命令直接烧写到NandFlash V2.0
- Ansible Ad-Hoc与常用模块
- Hadoop-2.0命令手册
- Windows PowerShell 2.0 开发之命令别名 (1)
- 【Ansible 文档】【译文】Ad-Hoc 命令介绍