[转] 第二章 Ansible Ad-Hoc介绍
2.1 Ad-Hoc使用场景
所谓Ad-Hoc, 简而言之是 “临时命令",英文中作为形容词有 “特别的, 临时的含义。Ad-Hoc只是官方对Ansible命令的一种称谓, 大家按各自习惯称呼即可。一般称之为临时操作 ” 或Ansible命令 。
从功能上讲, Ad-Hoc是相对Ansible-playbook而言的, Ansible提供两种完成任务方式:一 种是Ad-Hoc命令集, 即命令Ansible, 另外一 种就是Ansible-playbook了, 即命令 ansible-playbook。前者更注重千解决一些简单或者平时工作中临时遇到的任务, 相当于Linux系统命令行下的Shell命令, 后者更适合千解决复杂或需固化下来的任务, 相当千Linux系统的Shell Scripts。通常,深入Ansible是从接触Ansible-playbook开始的, 灵活运用Ansible-playbook才能更好地体会到Ansible的强大所在。
具体来讲, 什么样的场景下需要用到Ad-Hoc, 什么样的情况下需要使用Ansible-playbook呢?
2.1.1 需要使用Ad-Hoc的场景
情景1:节假日将至, 我们需要关闭所有不必要的服务器, 并对所有服务器进行节前健康检查。
情景2:临时更新Apache &Nginx的配置文件,且需同时将其分发至所有需更新该配置的Web服务器。
2.1.2 需要使用Ansible-playbook的场景
情景1:新购置的服务器安装完系统后需做一系列固化的初始化工作,诸如:定制防火墙策略、添加NTP时间同步配置、添加EPEL源等。
情景2:业务侧每周定期对生产环境发布更新程序代码。
其实两者之间关系用急行军(Ad-Hoc)和远征军(Ansible-playbook)来形容可能更容易理解。急行军需轻装上阵,注重灵活机动;远征军需稳扎稳打,注重长远规划。正如我们上面所讲,Ad-Hoc更注重千解决一些简单或者平时工作中临时遇到的任务,Ansible-playbook更适合于解决复杂的或需固化下来的任务。
2.2 Ad-Hoc命令集介绍
2.2.1 Ad-Hoc命令集用法简介
Ad-Hoc命令集由/usr/bin/ansible实现,其命令用法如下:
ansible <host-pattern> [options]
可以用选项如下:
-v,--verbose:输出更详细的执行过程信息,-vvv可得到执行过程所有信息。
-i,PATH,--inventory(清单)=PATH:指定inventory(清单)信息,默认/etc/ansible/hosts
-f NUM,--forks=NUM:并发线程数,默认5个线程。
--private-key=PRIVATE_KEY_FILE:指定密钥文件。
-m NMAE,--module-name=NAME:指定执行使用的模块。
-M DIRECTORY,--module-path=DIRECTORY:指定模块存放路径,默认/usr/share/ansible,也可以通过ANSIBLE_LIBRARY设定默认路径。
-a ‘ARGUMENTS’,--args=‘ARGUMENTS’:模块参数。
-k,--ask-pass SSH:认证密码
-K,--ask-sudo-pass sudo:用户的密码(--sudo时使用)。
-o,--one-line:标准输出至一行。
-s,--sudo:相当于Linux系统下的sudo命令。
-t DIRECTORY,--tree=DIRECTORY:输出信息至DIRECTORY目录下,结果文件以远程主机命名。
-T SECONDS,--timeout=SECONDS:指定连接远程主机的最大超时,单位是秒。
-B NUM,--background=NUM:后台执行命令,超NUM秒后中止正在执行的任务。
-P NUM,--poll=NUM:定期返回后台任务进度。
-u USERNAME,--user=USERNAME:指定远程主机以USERNAME运行命令。
-U SUDO_USERNAME,--sudo-user=SUDO_USERNAME:使用sudo,相当于LInux下的sudo命令。
-c CONNECTION,--connection=CONNECTION:指定连接方式,可用选项paramiko(SSH)、ssh、local,local方式常用于crontab和kickstarts。
-l SUBSET,--limit=SUBSET:指定运行主机。
-l ~REGEX,--limit=~REGEX:指定运行主机(正则)。
--list-hosts:列出符合条件的主机列表,不执行任何命令。
情景 1: 检查 proxy 组所有主机是否存活。
执行命令:
ansible proxy -f 5 -m ping
执行结果:
其中 192.168.37.159 是指命令执行的主机, Success 表示命令执行成功, ">> {} 表示详细返回结果如下。 ”“changed": false" 表示没有对主机做变更, ”“ping": "pong"" 表示执行了 ping 命令返回结果为 pong。
情景 2: 列出 Web 组所有主机列表。
执行命令:
ansible web --list
执行结果:
Ansible命令执行流程图
2.2.2 通过Ad-Hoc查看系统设置
通过 df、free 命令查看系统设置,但是是通过 Ad-Hoc 实现的,如下演示。
情景 1: 批量查看 apps 组所有主机的磁盘容量(使用 command 模块)。
执行命令:
ansible apps -a "df -lh"
返回结果如下:
情景 2: 批量查看远程主机内存使用情况 (shell 模块)。
执行命令:
ansible apps -m shell -a "free -m"
返回结果如下:
2.2.3 通过Ad-Hoc研究Ansible的并发特性
Ansible和Ansible-playbook 默认会 fork 5 个线程并发执行命令, 但在实际工作中, 如果主机数量众多,Ansible 并发 5 个线程是远不能满足企业所需的, 所以本节介绍 Ansible 的并发特性。 通过如下测试来更深入地了解 Ansible 的并发工作模式。
执行命令:
ansible apps -m ping -f 3
返回结果如下:
-
同样的命令多次执行, 但每次的输出结果都不一定一样
-
输出结果不是按照/etc/ansible/hosts 中 [apps] 定义的主机顺序输出。
-
结果输出基本上遵循每次输出 3条记录(线程池始终保持 3个线程, 所以这里如果每次输出小于等于3都是正常的)。
通过上面的实验可以对 Ansible 的并发性有了概念性的了解。 回到前面的问题,企业实际应用中, 如主机数量很多,我们需调大线程数, 该如何操作呢?这里 Ansible 为我们提供了便捷的选项,-f 指定线程数, 如-f 1 表示并发启动一个线程, -f 10 则表示同时启动 10 个线程并发执行命令。其实查看源码可知,Ansible 使用multiprocessing 管理多线程。
单台主机的性能始终有限, 大家根据自己机器实际的硬件配置做调整, 建议并发数配置的 CPU 核数偶数倍就好。 如 4Cores 8GB 的服务器, 建议最多并发 20 个线程。
2.2.4 通过Ad-Hoc研究Ansible的模块使用
Ansible 也提供了类似千 man 功能的 help 说明工具 ansible-doc, 直接按回车键或输入-h显示功能用法。
命令用法:
ansible -doc [options] [module... ]
可用选项如下:
--version: 显示工具版本号。
-h, --help:显示该 help 说明。
-M MODULE _pATH, --module-path=MODULE _pATH: 指定 Ansible模块的默认加载目录。
-I, --list: 列出所有可用模块。
-s, --snippet: 只显示 playbook 说明的代码段。
-v:等同于—version , 显示工具版本号。
情景1:显示所有可用模块。
执行命令:
ansible-do c -1
返回结果如下:
情景2:获取yum 模块的HELP 说明。
执行命令:
ansible-doc yum
返回结果如下:
2.2.5 Ansible模块练习
情景1:安装redhat-lsb 并查看服务器系统版本号。
1)安装redhat-lsb。
ansible apps -m yum -a 'name=redhat-lsb state=present'
2)查看系统版本号
ansible apps -m command -a'lsb_release -a'
情景2:为所有服务器安装ntp服务, 并设置为开机启动。
1)安装ntp服务。
ansible apps -s -m yum -a "name=ntp state=present"
2)启动ntp服务, 并设置为开机启动。
ansible apps -m service -a "name=ntpd state=Started enabled=yes"
2.3 Ad-Hoc组管理和特定主机变更
2.3.1 Ad-Hoc组定义
Ad-Hoc 的组功能定义在 Inventory 文件中,默认路径是 /etc/ansible/hosts, 书写格式遵循 INI 风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;
此外,若目标主机使用了非默认的 SSH 端口,还可以在主机名称之后使用冒号加端口号来标明。下面通过实际案例来了解 Inventory 文件的书写规则。
如下为 Inventory 文件示例,包括了组定义及冒号加端口号功能的使用。
ntp.magedu.com
[webservers]
wwwl.magedu.com:2222
www2.magedu.com
[dbservers]
dbl.magedu.com
db2.magedu.com
db3.magedu.com
如果远程主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机,如下案例为大家展示该写法。
[webservers]
www[01:50].magedu.com
[databases]
db-[a:f].magedu.com
2.3.2 Ad-Hoc配置管理:配置Proxy与Web Servers实践
1) Nginx、PHP 安装命令如下:
ansible app -m yum -a "name=nginx state=present"
ansible app -m yum -a "name=php state=present"
2) Django 安装命令如下:
安装 MySQL-python 和 python-setuptools 依赖包
ansible app -m yum -a "name=MySQL-python state=present"
ansible app -m yum -a "name=python-setuptools state=present"
安装 Django
ansible app -m pip -a "name=django state=present"
检查 Django 安装是否正常, 执行命令如下:
ansible app -m command -a "python -c 'import django; print django.get_version ()'"
2.3.3 Ad-Hoc配置后端:配置NoSQL与Database Servers实践
1)安装MariaDB-server
ansibledb -m yum -a "name=MariaDB-server state=present"
2)安装MariaDB-client
ansibledb -m yum -a "name=MariaDB-client state=present"
3)开启防火墙 3306访问权限
ansible db -m command -a "iptables -A INPUT -s 192.168.37.0/24 -p tcp -rn tcp --dport 3306 -j ACCEPT"
2.3.4 Ad-Hoc特定主机变更
1) --limit :通过-limit 参数限定主机做变更。
情景:在App组中启动 192.168.37.15 的 NTP 服务。
命令用法:
ansible app -m command -a "systemctl status ntpd" --limit ” 192.168.37.158"
2 ) 指定 IP: 通过指定具体 IP 限定主机做变更。
情景:启动 192.168.37.158 的NTP 服务。
执行命令:
ansible 192.168.37.158 -m command -a "systemctl status ntpd"
3) 作分隔符, 指定多台机器做变更。
情景:启动 192.168.37.158和192.168.37.161的NTP 服务。
执行命令:
ansible "192.168.37.158:192.168.37.161" -m command -a "systemctl status ntpd"
2.4 Ad-Hoc用户与组管理
用户权限管理是运维日常最重要的管理工作之一,如生产环境禁用开发和测试人员登录变更,但测试环境的用户权限仍需耗费精力维护,这项工作大公司也存在(将测试环境交给测试或开发管理并不是每个公司都能做到的,但未来是趋势)。
所以掌握Ad-Hoc用户与组管理很有用,如笔者现在的公司每次大版本更新后都会大量修改所有服务器密码。每次需要修改数十台服务器环境密码,若手动单台登录修改可是一项不小的工作, 并且手动方式难免会出错误。
Ansible系统用户模块有如下两个:
-
Linux系统用户管理:user
-
Windows系统用户管理:win_user
2.4.1 Linux用户管理
User模块功能诸多,各功能作用几乎完全覆盖平时工作常规及非常规场景。模块所有属性如表所示
情景1:新增用户
需求描述: 新增用户dba, 使用BASH Shell, 附加组为admins, dbagroup, 家目录为/home/dba/
执行命令:
ansibledb -m user -a "name=dba shell=/bin/bash groups=admins,dbagroup append=yes home=/home/dba/ state=present"
情景2:修改用户属组
需求描述:修改DBA附件组为dbagroups (即删除 admins 组权限)
执行命令:
ansibledb -m user -a "name=dba groups=dbagroup append=no"
情景3:修改用户属性
需求描述:设置 dba 用户的过期时间为 2016/6/1 18:00:00 (UNIXTIME: 1464775200)。
执行命令:
ansibledb -m user -a "name=dba expires=1464775200"
情景4:删除用户
需求描述:删除用户DBA, 并删除其家目录和邮件列表。
执行命令:
ansibledb -m user -a "name=dba state=absent remove=yes"
情景5:变更用户密码
需求描述:设置系统用户 tom 的密码为 redhat123。
执行命令:
ansibledb -m user -a "name=tom shell=/bin/bash password=redhat123 update password=always"
2.4.2 Windows用户管理
Ansible 同样支持 Windows 系统。但考虑 Windows 不开源的特殊性及服务器市场的占有率,使得 Ansible 与 Windows 的结合使用时总是会出问题,但其实类似问题其他工具也同样存在,这是 Windows 特性使然。
情景:新增用户 stanley, 密码为 magedu@l 23, 属组为 Administrators。
ansible wind ows -m win_user -a "name=stanley passwd=magedu@l23 group=Administrators"
2.4.3 应用层用户管理
Ansible 支持商业系统或产品类应用, 系统如 AWS 的 1AM, MAC 的 osx; 软件如 Apache CloudStack、Jabberd、 Open Stack、MongoDB、MySQL、PostgreSQL、RabbitMQ、Vertica等
情景:新增 MySQL 用户 stanley, 设置登录密码为 magedu@bj, 对zabbix* 表有ALL 权限。
ansible db -m mysql_user -a'login_host=localhost login_password=magedu login_ user=root name=stanley password=magedu@bj priv=zabbix.*:ALL state=present'