2.1 Ansible目录结构介绍

      Ansible是开源工具,这个开发过程或二次开发均遵循GPL协议,所以所有源码均可见。作为一款日常工作所需的核心软件,我们有必要知道期目录分布及各目录功能。通过如下命令可以获取Ansible所有文件存放目录:

#rpm -ql ansible



该命令输出内容较多,大致分为如下几类:

  • 配置文件目录/etc/ansible/
  • 执行文件目录/usr/bin
  • Lib库依赖目录/usr/lib/pythonX.X/site-packages/ansible/
  • Help文档目录/usr/share/doc/ansible-X.X.X/
  • Man文档目录/usr/share/man/man1

整体的目录概要可参考下图所示的Ansible目录树结构

ansible获取解压后的文件目录 ansible目录结构_配置文件

ansible获取解压后的文件目录 ansible目录结构_Ansible_02

    其中,如下目录运维常要配置,需熟练掌握。

    1)配置文件目录/etc/ansible,主要功能为:Inventory主机信息配置、Ansible工具功能配置等。所有Ansible的配置均存放在该目录下,运维日常的所有配置类操作也均基于此目录进行。

    2)执行文件目录/usr/bin,主要功能为:Ansible系列命令默认存放目录。Ansible所有的可执行文件均存放在该目录下。

    在/usr/lib/pythonXXX/site-packages/下,该目录是系统当前默认的Python路径,因为Ansible是基于Python编写的,所以Ansible的所有lib库文件和模块文件也均存放于该目录下。

2.2 Ansible配置文件解析

    Inventory用于定义Ansible的主机列表配置,Ansible的自身配置文件只有一个,即ansible.cfg,Ansible安装好后它默认存放于/etc/ansible目录下。ansible.cfg配置文件可以存在于多个地方,Ansible读取配置文件的顺序依次是当前命令执行目录-->用户家目录下的.ansible.cfg-->/etc/ansible.cfg,先找到那个就使用哪个的配置。其ansible.cfg配置的所有内容均可在命令行通过参数的形式传递或定义在Playbooks中。

    配置文件ansible.cfg约有350多行语句,大多数为注释默认配置项。该文件遵循INI格式,分为如下几类配置。

    (1)[defaults]

    该类配置下定义常规的连接类配置,如inventory、library、remote_tmp、local_tmp、forks、poll_interval、sudo_user、ask_sudo_pass、ask_pass、transport、remote_port等。

ansible获取解压后的文件目录 ansible目录结构_Ansible_03

ansible获取解压后的文件目录 ansible目录结构_配置文件_04

         (2)[privilege_escalation]

         处于安全角度考虑,部分公司不希望直接以root的高级管理员权限直接部署应用,往往会开放普通用户权限并给予sudo的权限,该部分配置主要针对sudo用户提权的配置。

ansible获取解压后的文件目录 ansible目录结构_ansible获取解压后的文件目录_05

        (3)[paramiko_connection]

        定义paramiko_connection配置,该部分功能不常用,了解即可。

ansible获取解压后的文件目录 ansible目录结构_Ansible_06

         (4)[ssh_connection]

         Ansible默认使用SSH协议连接对端主机,该部署是主要是SSH连接的一些配置,但配置项较少,多数默认即可。

ansible获取解压后的文件目录 ansible目录结构_ansible获取解压后的文件目录_07

         (5)[accelerate]

         Ansible连接加速相关配置。因为有部分使用者不满意Ansible的执行速度,所以Ansible在连接和执行速度方面也在不断地进行优化,该配置项在提升Ansible连接速度时会涉及,多数保持默认即可。

ansible获取解压后的文件目录 ansible目录结构_Ansible_08

        (6)[selinux]

        关于selinux的相关配置几乎不会涉及,保持默认配置即可。

ansible获取解压后的文件目录 ansible目录结构_API_09

        (7)[colors]

        Ansible对于输出结果的颜色也进行了详尽的定义且可配置,该选项对日常功能应用影响不大,几乎不用修改,保持默认即可。

ansible获取解压后的文件目录 ansible目录结构_API_10

       上面尽可能全地介绍了运维工作中可能需要修改的配置选项,除了在关闭首次连接提示(host_key_checking=False)或提速调整([accelerate]区域块配置调整)时可能会稍作调整,其中绝大多数选项默认即可,Ansible安装好后无需任何改动即可使用。

2.3 Ansible命令用法详解

         Ansible命令执行方式有Ad-Hoc、Ansible-playbook两种方式。Ad-Hoc主要用于临时命令的执行,Ansible-playbook可以理解为Ad-Hoc的集合,通过一定的规则编排在一起。

         Ansible的通信默认基于SSH,因此我们需要对主机先进行认证。Ansible认证方式有密码认证和公私钥两种方式,其实完全等同于SSH的认证。Ansible默认使用公私钥认证方式,究其原因无非是出于安全的考虑,密码不用明文存放。以本机为例,执行如下命令即可添加本机认证信息。

//ssh-keygen是Linux下认证密钥生成、管理和转换工具
ssh-keygen -N "" -b 4096 -t rsa -C "stanley@magedu.com" -f /root/.ssh/stanley.rsa
//为本机添加密钥认证
ssh-copy-id -i /root/.ssh/stanley.rsa root@localhost


ansible获取解压后的文件目录 ansible目录结构_Ansible_11



输入正确的密码信息后结果认证,随后在当前命令行输入如下命令尝试免密码登录:

ansible获取解压后的文件目录 ansible目录结构_配置文件_12


        如不提示输入密码即可直接登录则表示密钥验证成功。

        Ansible的命令使用格式如下:

  

ansible <host-pattern> [options]



       <host-pattern>是Inventory中定义的主机或主机组,可以为Ip、hostname、Inventory中的group组名、具有"."或"*"或":"等特殊字符的匹配型字符串,<>表示该选项是必须项,不可忽略。

       [options]是Ansible的参数选项,[]表示该选项中的参数任选其一。

       Ansible命令可用选项非常多,这里列举如下会用到的选项,详细选项可参考man文档。

  • -m NAME,--module-name=NAME:指定执行使用的模块
  • -u USERNAME,--user=USERNAME:指定远程主机以USERNAME运行命令。
  • -s,--sudo:相当于Linux系统下的sudo命令
  • -U SUDO_USERNAME,--sudo-user=SUDO_USERNAME:使用sudo,相当于Linux下的sudo命令。

具体示例如下:

//以bruce用户执行ping存活检测
ansible all -m ping -u bruce
//以bruce sudo至root执行ping存活检测
ansible all -m ping -u bruce --sudo
//以bruce sudo至batman用户执行ping存活检测
ansible all -m ping -u bruce --sudo --sudo-user batman



但在新版本中Ansible的sudo命令废弃,改为--become或-b,如上命令需改为如下:

//以bruce sudo至root执行ping存活检测
ansible all -m ping -u bruce -b
//以bruce sudo至batman用户执行ping存活检测
ansible all -m ping -u bruce -b --become-user batman



      Ansible-playbook的命令使用格式如下:

      ansible-playbook playbook.yml

      ansible-playbook命令后跟事先编辑好的playbook.yml文件即可。Ansible-playbook新增的功能参数如下:

ansible获取解压后的文件目录 ansible目录结构_配置文件_13

2.4 Ansible系列命令用法详解与使用场景介绍

  • ansible
  • ansiblee-galaxy
  • ansible-pull
  • ansible-doc
  • Ansible-playbook
  • ansible-vault
  • ansible-console

2.4.1 ansible

    ansible命令主要在如下场景使用:

  • 非固化需求
  • 临时一次性操作
  • 二次开发接口调用

     那么什么是非固化需求和临时一次性操作呢?简单来讲,比如工作中我临时想查看web1服务器组是否存活,或我临时复制本地的/etc/fstab到web服务器组的/tmp目录下做测试,例如这些没有规律的、临时需要做的任务,我们称之为非固化需求、临时一次性操作。具体的命令使用如下:

//检查服务器存活
ansible web1 -m ping
//复制本地文件到远程
ansible web1 -m copy -a "src=/etc/fstab owner=root group=root mode=644 backup=yes"



      Ansible的返回结果都非常友好,一般会用3种颜色来表示执行结果:红色、绿色、橘黄色。其中红色表示执行过程有异常,一般会终止剩余所有的任务;绿色和橘黄色表示执行过程没有异常,所有任务均正常执行,但橘黄色表示命令执行结束后目标有状态的变化。


2.4.2 ansible-galaxy

      ansible-galaxy的功能可以简单地理解为GitHub或PIP的功能通过ansible-galaxy命令,我们可以根据下载量和关注量等信息,查找和安装优秀的Roles。Roles是Ansible非常重要的一项功能。在ansible-galaxy上,我们可以上传和下载Roles,这里也是优秀Roles的聚集地,下载地址为https://galaxy.ansible.com

      ansible-galaxy命令使用格式如下:

ansible-galaxy [init|info|install|list|remove] [--help] [options] ...



      ansible-galaxy命令分三大部分:

      (1)[init|info|install|remove]

  • init:初始化本地的Roles配置,以备上传Roles至galaxy。
  • info:列表指定Role的详细信息
  • install:下载并安装galaxy指定的Roles到本地
  • list:列出本地已下载的Roles
  • remove:删除本地已下载的Roles

          Ansible2.0版本中,针对ansible-galaxy增加了login、import、delete、setup等功能,但这些功能需基于login在galaxy认证成功后方可执行,主要为了方便对galaxy上已有Roles的配置工作。

       (2)help用法显示[--help]

       针对第一部分的inti、info等功能,其后跟--help可单独显示该项用法。例如:

ansible-galaxy init --help



         执行后会返回ansible-galaxy init选项的用法说明。

Usage: ansible-galaxy init [options] role_name

Options:
  --container-enabled   Initialize the skeleton role with default contents for
                        a Container Enabled role.
  -f, --force           Force overwriting an existing role
  -h, --help            show this help message and exit
  -c, --ignore-certs    Ignore SSL certificate validation errors.
  --init-path=INIT_PATH
                        The path in which the skeleton role will be created.
                        The default is the current working directory.
  --offline             Don't query the galaxy API when creating roles
  --role-skeleton=ROLE_SKELETON
                        The path to a role skeleton that the new role should
                        be based upon.
  -s API_SERVER, --server=API_SERVER
                        The API server destination
  -v, --verbose         verbose mode (-vvv for more, -vvvv to enable
                        connection debugging)
  --version             show program's version number and exit

 See 'ansible-galaxy <command> --help' for more information on a specific
command.



       (3)参数项[options]


       该部分结合第一部分的参数完成ansible-galaxy完整的功能用法,如:

       ansible-galaxy inti [options] role_name 即ansible-galaxy init后 跟[-f|-h|-c|-p|--offline|-s SERVER|-v|--version]参数,后跟role-name成为一条完整的命令。

        具体可参考如下:

//下载用户hectcastro的Nginx这个Role到本地并忽略错误(默认存放在/etc/ansible/roles/)
ansible-galaxy --ignore-errors install azavea.git


ansible获取解压后的文件目录 ansible目录结构_配置文件_14



    因为ansible-galaxy是对https://galaxy.ansible.com网站的上传、下载、配置类工作,如有类似如下报错,请确保该网站可正常访问。

the API server (galaxy.ansible.com) is not responding,please try again later.

2.4.3 ansible-pull

       该指令的使用涉及Ansible的另一种工作模式:pull模式(Ansible默认使用push模式)。这和通常使用的push模式工作机理刚好相反,其适用与以下场景:1.你有数量巨大的机器需要配置,即使使用高并发线程依旧要花费很多时间;2你要在刚启动的、没有网络连接的主机上运行ansible。

       ansible-pull命令使用格式如下:

      

ansible-pull [options] [playbook.yml]



      通过ansible-pull结合git和crontab一并实现,其原理如下:通过crontab定期拉取指定的Git版本到本地,并以指定模式自动运行预先制定好的指令。

      具体实例参考如下:

*/20 * * * * root /usr/local/bin/ansible-pull -o -C 2.1.0 -d /srv/www/kong-gw/ -i /etc/ansible/hosts -U git://git.kingifa.com/kong-gw-ansiblepull >> /var/log/ansible-pull.log 2>&1



2.4.4 ansible-doc

   ansible-doc是Ansible模块文档说明,针对每个模块都有详细的用法说明及应用案例介绍,功能和Linux系统man命令类似。该命令使用方式如下:

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



    ansible-doc命令后跟[options]参数或[模块名],显示模块用法说明,具体实例如下:

//列出支持的模块
ansible-doc -l
//模块功能说明
ansible-doc ping



2.4.5 ansible-playbook

        ansible-playbook是日常应用中使用频率最高的命令,其工作机制是:通过读取预先编写好的playbook文件实现批量管理。要实现的功能与命令Ansible一样,可以理解为按一定条件组成的ansible任务集。

        ansible-playbook命令后跟YML格式的playbook文件,执行事先编排好的任务集,命令使用方式如下:

ansible-playbook playbook.yml



        具体示例如下:

//执行gw.yml这个playbook中定义的所有任务集
ansible-playbook gw.yml



2.4.6 ansible-vault

       ansible-vault主要用于配置文件加密,如编写的Playbook配置文件中包含敏感信息,不希望其他人随意查看,ansible-vault可加密/解密这个配置文件,具体使用方式如下:

Usage:ansible-vault [create|decrypt|edit|encrypt|rekey|view] [--help] [options] file_name



      具体示例如下。

      设定如下密码,加密a.yml文件

     

ansible-vault encrypt a.yml



      会有以下输入加密密码提示:

Vault password:
Confirm Vault password:
Encryption successful



      这时,再打开a.yml文件后会发现该文件乱码,只有通过如下命令解密后方可正常查看。

ansible-vault decrypt a.yml



      输入预设的密码后方可解密

Value password:
Decryption successful



        此时a.yml文件可正常查看。


2.4.7 ansible-console

ansible获取解压后的文件目录 ansible目录结构_配置文件_15

   图中的"root@all(4)[f:5]$"是提示符,该提示符表示"当前的使用用户@当前所在的Inventory中定义的组,默认是all分组(Inventory中all组所有主机的数量)[forks:线程数]$"。

   使用cd命令可切换至指定Hosts或分组,同时提示符的相应信息也会随之变动,如下图所示。

ansible获取解压后的文件目录 ansible目录结构_API_16

    cd至webs分组后,原来的root@all(4)[f:5]$也相应地变更为root@webs(3)[f:5],表示当前分组为webs分组,该分组所拥有的主机总数为3台。执行forks 2后,提示符再次变更为root@webs(3)[f:2]$,表示设置并发的线程数为2。

    所有的操作与Shell类似,而且支持Tab键补全,如启动httpd服务时,键入service后连续按两次Tab键后自动补全剩余的命令选项。ansible-console命令用法如下图所示。

ansible获取解压后的文件目录 ansible目录结构_ansible获取解压后的文件目录_17

     如需启动httpd服务,使用命令service name=httpd state=started,命令用法与Ad-Hoc一致,只是格式上的使用习惯不同而已。

ansible获取解压后的文件目录 ansible目录结构_API_18

        使用完毕如希望退出,Ctrl+D或Ctrl+C即可退出当前的虚拟终端。

2.5 Ansible Inventory配置及详解

        Inventory是Ansible管理主机信息的配置文件,相当于系统HOSTS文件的功能,默认存放在/etc/ansible/hosts。为方便批量管理主机,便捷使用其中的主机分组,Ansible通过Inventory来定义其主机和组,在使用时通过-i或--inventory-file指定读取,与Ansible命令结合使用时组合如下:

ansible -i /etc/ansible/hosts webs -m ping



        如果只有一个inventory时可不用指定路径,默认读取/etc/ansible/hosts。Inventory可以同时存在多个,而且支持动态生成,如AWS EC2、Cobbler等均支持。

2.5.1 定义主机和组

# Inventory可以直接为IP地址
192.168.37.149
# Inventory同样支持Hostname的方式,后跟冒号加数字表示端口号,默认22号端口
ntp.magedu.com:2222
nfs.mageud.com
# 中括号内的内容表示一个分组的开始,紧随其后的主机均属于该组成员,空行后的主机亦属于该组,即web2.magedu.com这台主机也属于[websevers]组
[websevers]
web1.magedu.com
web[10:20].magedu.com # [10:20]表示10-20z之间的所有数字(包括10和20),即表示web10.magedu.com,web11.magedu.com......web20.mageud.com的所有主机

web2.magedu.com[dbservers]
db-a.magedu.com
db-[b:f].magedu.com # [b:f]表示b到f之间的所有数字(包括b和f)



2.5.2 定义主机变量

[webservers]
web1.magedu.com http_port=808 maxRequestPerChild=801 # 自定义http_port的端口号为808,配置maxRequestPerChild为801



2.5.3 定义组变量

[groupservers]
web1.magedu.com
web2.magedu.com

[groupservers:vars]
ntp_server=ntp.magedu.com # 定义groupservers组中所有主机ntp_server值为ntp.magedu.com
nfs_server=nfs.magedu.com # 定义groupservers组中的所有主机nfs_server值为nfs.magedu.com



2.5.4 定义组嵌套及组变量

[apache]
httpd1.magedu.com
httpd2.magedu.com

[nginx]
ngx1.magedu.com
ngx2.magedu.com

[webservers:children]
apache
nginx

[webservers:vars]
ntp_server=ntp.magedu.com



2.5.5 多重变量定义

     变量除了可以在Inventory中一并定义,也可以独立于Inventory文件之外单独存储到YAML格式的配置文件中,这些文件通常以.yml、.yaml、.json为后缀或者无后缀。

变量通常从如下4个位置检索:

  • Inventory配置文件(默认/etc/ansible/hosts)
  • Playbook中vars定义的区域
  • Roles中vars目录下的文件
  • Roles同级目录group_vars和hosts_vars目录下的文件

         假如foosball主机同属于raleigh和webservers组,那么其变量在如下文件中设置均有效:

/etc/ansible/group_vars/raleigh
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball



2.5.6 其他Inventory参数列表

     除了支持如上的功能外,ansible基于ssh连接Inventory中指定的远程主机时,还内置了很多其他参数,用于指定其交互方式,如下列举了部分重要参数:

ansible_ssh_host:指定连接主机
ansible_ssh_sort,指定ssh连接端口,默认22
ansible_ssh_user:指定ssh连接用户
ansible_ssh_pass,指定ssh连接密码
ansible_sudo_pass:指定ssh连接时sudo密码
ansible_ssh_private_key_file:指定特有私钥文件



2.6 Ansible与正则

用法:

ansible <pattern_goes_here> -m <module_name> -a <arguments>



如下示例针对webservers进行正则匹配:

//重启webservers组所有主机的httpd服务
ansible webservers -m service -a "name=httpd state=restarted"



(1)all(全量)匹配

匹配所有主机,all或*号功能相同。如检测所有主机存活情况。

ansible all -m ping
ansible "*" -m ping



检查192.168.1.0/24网段所有主机存活情况

ansible 192.168.1.* -m ping



(2)逻辑或(or)匹配

ansible "web1:web2" -m ping



(3)逻辑非(!)匹配

//所有在webservers组但不在phoenix组的主机
webservers:!phoenix



(4)逻辑与(&)匹配

//webservers组和staging组中同时存在的主机
webservers:&staging



(5)多条件组合

//webservers和dbservers两个组中的所有主机在staging组中存在且在phoenix组中不存在的主机
webservers:dbservers:&staging:!phoenix



(6)模糊匹配

//所有以.magedu.com结尾的主机均符合
*.magedu.com
//one开头.com结尾的所有主机和dbservers组中的所有主机
one*.com:dbservers



(7)域切割

[webservers]
cobweb
webbing
weber

webservers[0]   # == cobweb
webservers[-1]  # == weber
webservers[0:1]  # == webservers[0],webservers[1],即 cobweb,webbing



(8)正则匹配

ansible同样完整支持正则匹配功能,"~"开始表示正则匹配

~(web|db).*\.example\.com



检测beta.example.com、web.example.com、green.example.com、beta.example.org、web.example.org、green.example.org的存活,使用如下匹配模式:

ansible "~(beta|web|green)\.example\.(com|org)" -m ping



检测Inventory中所有以192.168.开头的服务器存活信息:

ansible ~192\.168\.[0-9]\{\2}.[0-9]\{2,} -m ping