Ansible Ad-Hoc命令集,ansiblead-hoc


3.1 Ad-Hoc使用场景

          所谓Ad-Hoc,简而言之是"临时命令",英文中作为形容词有"特别的,临时"的含义。Ad-Hoc只是官方对Ansible命令的一种称谓。

          从功能上讲,Ad-Hoc是相对于Ansible-playbook而言的,Ansible提供两种完成任务方式:一种是Ad-Hoc命令集,即ansible,另一种就是Ansible-playbook了,即命令Ansible-playbook。前者更注重于解决一些简单的或者平时工作中临时遇到的任务,相当于Linux系统命令行下的Shell命令,后者更适合与解决复杂或需固化下来的任务,相当于Linux系统的Shell Scripts。

          情景1:

          节假日将至,我们需要关闭所有不必要的服务器,并对所有服务器进行节前健康检查。

          情景2:

          临时更新Apache&Nginx的配置文件,且需同时将其分发至所有需更新该配置的Web服务器

          2. 需要使用ansible-playbook的场景

          情景1:

          新购置的服务器安装完系统后需做一系列固化的初始化工作,诸如:定制防火墙策略、添加NTP时间同步配置、添加EPEL源等。

          情景2:

          业务侧每周定期对生产环境发布更新程序代码。

3.2 Ad-Hoc命令集介绍

3.2.1 Ad-Hoc命令集用法简介

      Ad-Hoc命令集由/usr/bin/ansible实现,其命令用法如下:

ansible <host-pattern> [options]

可用选项如下。

  • -v,--verbose:输出更详细的执行过程信息,-vvv可得到执行过程所有信息。
  • -i PATH,--inventory=PATH:指定inventory信息,默认/etc/absible/hosts。
  • -f NUM,--forks=NUM:并发线程数,默认5个线程。
  • --private-key=PRIVATE_KEY_FILE:指定密钥文件。
  • -m NAME,--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:列出符合条件的主机列表,不执行任何命令。

ansiblemaster:192.168.230.100

ansibleslave1 :192.168.230.240

ansibleslave2 :  192.168.230.247


首先配置三台主机的hosts的文件:


配置ansible的host分组


      情景1:检查proxy组所有主机是否存活。

      执行命令:

     

ansible proxy -f 5 -m ping


     其中ansibleslave1,ansibleslave2是指命令执行的主机,SUCCESS表示命令执行成功,">>{}"表示详细返回结果如下。""change":false""表示没有对主机做变更,""ping":"pong""表示执行了ping命令返回结果为pong。

        情景2:返回proxy组所有主机的hostname,并打印最详细的执行过程到标准输出。

        执行命令:

ansible proxy -s -m command -a 'hostname' -vvv


执行结果诠释:




       情景3:列出proxy组所有主机列表。


       情景4:对10.21.40.61服务器以root执行sleep 20,设置最大连接超时时长为2s,且设置为后台运行模式,执行过程每2s输出依次进度,如5s还未执行完则终止该任务。

      

//time命令可省,为方便观察结果,这里使用time命令查看执行时长
time ansible 10.21.40.61 -B 5 -P 2 -T 2 -m command -a 'sleep 20' -u root

执行结果诠释:




3.2.2 通过Ad-Hoc查看系统设置

情景1:批量查看proxy组所有主机的磁盘容量(使用command模块)。

执行命令:


执行结果诠释:

以ansibleslave2的返回为例,SUCCESS表示命令执行成功,rc=0表示ResultCode=0,即命令返回结果,返回码为0,表示命令执行成功,>>后面跟的内容相当于在本地执行df -lh后的结果返回。

情景2:批量查看远程主机内存使用情况(shell模块)



3.2.3 通过Ad-Hoc研究Ansible的并发特性


返回结果分析如下:

1)同样的命令多次执行,但每次的输出结果都不一定一样。

2)输出结果不是按照/etc/ansible/hosts中[proxy]定义的主机顺序输出。

3)结果输出基本上遵循每次输出3条记录(线程池始终保持3个线程,所以每次输出小于等于3都是正常的)。

      Ansible使用multiprocessing管理多线程。

3.2.4 通过Ad-Hoc研究Ansible的模块使用

模块链接:http://docs.ansible.com/ansible/modules_by_category.html

ansible-doc [options] [module...]

可用选项如下。

  • --version:显示工具版本号
  • -h,--help:显示该help说明
  • -M MODULE_PATH,--module-path=MODULE_PATH:指定Ansible模块的默认加载目录。
  • -l,--list:列出所有可用的模块。
  • -s,--snippet:只显示playbook说明的代码段。
  • -v:显示工具版本号。

情景1:显示所有可用模块。


情景2:以yum模块为例,我们希望获取yum模块的HELP说明。


【示例1】安装redhat-lsb并查看服务器系统版本号。

步骤1:安装redhat-lsb。


其中:

  • "changed":主机是否有变更,true为有;false为没有(第1次运行或事先没有安装,返回值一般是true,否则为false)。
  • "msg":安装过程信息。
  • "rc":0,resultcode:结果状态码,非0返回码往往是红色并且错误的返回,非常明显。

步骤2:查看系统版本号。


部分执行结果诠释:

  • ansibleslave1:表示命令执行的对象。
  • success:表示命令执行的返回状态为成功状态
  • rc=0:表示命令执行的状态码为0。
  • >>:该符号后返回的所有内容为执行lsb_release -a命令返回的信息。
  • LSB Version:表示该系统的内核版本信息。
  • Distributor ID:表示发行厂商。
  • Description:表示版本简要信息。
  • Release:表示该系统的发行版本号。
  • Codename:表示发行版代号。

【示例2】为所有服务器安装ntp服务,并设置为开机启动。

步骤1:安装ntp服务。


步骤2:启动ntp服务,并设置为开机启动。


3.3 Ad-Hoc组管理和特定主机变更

3.3.1 Ad-Hoc组定义

       Ad-Hoc的组功能定义在Inventory文件中,默认路径是/etc/ansible/hosts,书写格式遵循INI风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口来表明。

      如下为inventory文件实例,包括了组定义即冒号加端口号功能的使用。

ntp.magedu.com

[webservers]
www1.magedu.com:2222
www2.magedu.com

[dbservers]
db1.magedu.com
db2.magedu.com
db3.magedu.com
       如果远程主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机,如下案例为大家展示改写法。

[webservers]
www[01:50].magedu.com
[databases]
db-[a:f].magedu.com

      本次架构规划了前端Proxy,Web Servers和后面DB一套完整应用,图中共定义了Proxy、App、NoSQL和DB这4个组。



应用分布如下。

  • [proxy]组:Nginx;
  • [app]组:Nginx+PHP+Django;
  • [nosql]组:Redis;
  • [db]组:Mariadb。

3.3.2 Ad-Hoc配置管理:配置Proxy与Web Servers实践

(1)Ad-Hoc配置管理Proxy(即Nginx)


wget http://mirror.switch.ch/ftp/pool/4/mirror/scientificlinux/6.5/x86_64/updates/fastbugs/python-devel-2.6.6-52.el6.x86_64.rpm
wget http://mirror.switch.ch/ftp/pool/4/mirror/scientificlinux/6.5/x86_64/updates/fastbugs/python-libs-2.6.6-52.el6.x86_64.rpm
wget http://mirror.switch.ch/ftp/pool/4/mirror/scientificlinux/6.5/x86_64/updates/fastbugs/python-2.6.6-52.el6.x86_64.rpm
卸载原来的,python包
rpm -ivh python-devel-2.6.6-52.el6.x86_64.rpm python-libs-2.6.6-52.el6.x86_64.rpm python-2.6.6-52.el6.x86_64.rpm


解决:


部分结果诠释:

"changed":true,  //表示本次命令对执行的目标有变更,如再执行一次则为false,表示执行的目标没有变更,这里的false和true不代表该命令执行成功或失败,只是表示执行目标是否被变更
"rc":0, //resultcode的简写,表示命令的执行结果状态返回,非0均为异常,命令执行失败
"results":  //执行结果信息返回

     Ansible的YUM模块同样支持指定某版本安装,其name参数指定具体版本地址(网络或本地均可)。YUM模块也支持从网络或本地安装。

     如果从网络安装,执行命令:

ansilbe proxy -m yum -a "name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present"

    如果从本地安装,执行命令:

ansible proxy -m yum -a "name=/usr/local/src/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present"

(2)Ad-Hoc配置管理Web Servers

    Web Servers需同时部署Nginx、PHP和Django,其中Nginx、PHP依然通过YUM模块实现,Django推荐使用PIP或easy_install方式。

1)Nginx、PHP安装命令如下:



ansible app -m yum -a "name=php state=present"

2)Django安装命令如下:

步骤1:安装MySQL-python和python-setuptools依赖包。

ansible app -m yum -a "name=MySQL-python state=present"
ansible app -m yum -a "name=python-setuptools state=present"

步骤2:安装Django

升级python2.6.6到python2.7.13(点击打开链接)

ansible app -m pip -a "name=django==1.9 state=present"

步骤3:检查Django安装是否正常,执行命令如下:


3.3.3 Ad-Hoc配置后端:配置NoSQL与Database Servers实践

安装Redis:


安装MariaDB:

步骤1:添加yum源,vim编辑/etc/yum.repos.d/mariadb.repo添加内容如下。

[mariadb]
name=MariaDB
baseurl=http://yum.mariadb.org/10.1/centos6-x86
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

步骤2:安装MariaDB-server


执行如下命令:

 yum remove mysql-libs

步骤2:安装MariaDB-server,

步骤3:安装MariaDB-client,


步骤4:开启防火墙3306访问权限。


3.3.4 Ad-Hoc特定主机变更

Ansible有多种方式实现针对特定主机做变更。

1)--limit:通过--limit参数限定主机做变更。

情景:在App组中启动192.168.37.15的NTP服务。

ansible app -m command -a "service ntpd status" --limit "192.168.230.237"

2)指定IP:通过指定具体IP限定主机做变更。

情景:查看192.168.230.237的NTP服务

ansible 192.168.230.237 -m command -a "service ntpd status"

3)用":"做分隔符,指定多台机器做变更。

启动192.168.230.237和192.168.230.238的ntp服务

ansible "192.168.230.237:192.168.230.238" -m command -a "service ntpd status"

4)通过"*"泛匹配,更灵活的针对多台主机做变更。

ansible 192.168.230.* -m command -a "service ntpd status"

3.4 Ad-Hoc用户与组管理

Ansible系统用户模块有如下两个:

  • Linux系统用户管理:user。
  • Windows系统用户管理:win_user。

3.4.1 Linux用户管理




场景1:新增用户。

需求描述:新增用户dba,使用BASH Shell,附加组为admins,dbagroup,家目录为/home/dba/。

该场景中我们可以掌握如下技能点。

1)groups设定:groups=用户组1,用户组2.....

2)增量添加属组:append=yes

3)表明属组状态为新建:state=present


场景2:修改用户属组。

需求描述:修改DBA附加组为dbagroups(即删除admins组权限)。

该场景中我们可以掌握如下技能点。

全量变更属组信息:append=no


场景3:修改用户属性。

需求描述:设置dba用户的过期时间为2016/6/1 18:00:00(UNIXTIME:1464775200)。

该场景中我们可以掌握如下技能点。

1)设置用户登录过期时间:expire=1464775200

2)UNIX时间转换:2016/6/1 18:00:00需转换为UNIXTIME格式

ansible db -m user -a "name=dba expires=1464775200"

场景4:删除用户。

需求描述:删除用户DBA,并删除其家目录和邮件列表。

该场景中我们可以掌握如下技能点:

1)表明属组状态为删除:state=absent

2)设定remove=yes:remove=yes

删除成功


场景5:变更用户密码

需求描述:设置系统用户tom的密码为redhat123.

方式一:使用命令mkpasswd生成密码。

查找安装包名称:yum whatprovides */mkpasswd,


yum install expect

Debian Ubuntu执行命令:sudo apt-get install whois


方式2:使用Python的passlib、getpass库生成密码。

pip install passlib
python 3.x系列版本使用如下命令(sha512加密算法)
python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.encrypt(getpass.getpass()))"
普通加密算法。
python -c 'import crypt; print(crypt.crypt("redhat123","dba"))'
Python2.x(sha512加密算法)
python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"
普通加密算法
python -c 'import crypt; print(crypt.crypt("redhat123","dba"))'



3.4.2 Windows用户管理

场景:新增用户stanley,密码为magedu@123,属组为Administrators。

ansible windows -m win_user -a "name=stanley passwd=magedu@123 group=Administrators"



  • account_disabled-----禁用用户登录;
  • account_locked-------解锁用户
  • groups---------用户所属组
  • name---------用户名
  • password_expired----------下次登录修改密码。
  • user_cannot_change_password---------用户是否可修改密码

3.4.3 应用层用户管理

情景:新增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'
在db服务器上测试登录
mysql -ustanley -pmagedu@bj
执行命令:
show grants for 'stanley'@'localhost';验证权限是否正确。

其实如上命令存在很大的安全隐患,因为MySQL的登录信息完全暴露在命令台。Ansible建议的使用方式如下。

1)在远程主机的~/.my.cnf文件中配置root的登录信息,配置信息如下:

[client]
user=root
password=magedu

2)命令行执行命令如下:

ansible db -m mysql_user -a 'name=stanley password=magedu@bj priv=zabbix.*:ALL state=present'

此方式密码将不再暴露在控制台,在一定程度上提高了服务安全性。






















相关内容

    暂无相关文章