Ansible权威指南
上QQ阅读APP看书,第一时间看更新

第2章
Ansible基础元素介绍

第1章介绍了Ansible的功能作用、通信发展史、基础的安装部署及处理Ansible安装问题所需的Python多环境管理工具Pyenv和Virutalenv。在前期基本工作准备妥当的基础上,本章进一步深入学习Ansible的基础元素,会相继接触Ansible目录结构简介、Ansible系列命令、Ansible Inventory配置规范、Ansible模式匹配规则等,其中部分内容,诸如Inventory、Ansible-playbook等在后续涉及章节会更深入介绍。本章主要是为大家呈现Ansible及系列命令的基础入门介绍,所介绍的内容相互之间没有紧密关系,可选择性地阅读感兴趣章节。

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/

整体的目录概要可参考如图2-1所示的Ansible目录树结构。

图2-1 Ansible目录树结构

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

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

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

在/usr/lib/pythonXXX/site-packages/下,该目录是系统当前默认的Python路径,因为Ansible是基于Python编写的,所以Ansible的所有lib库文件和模块文件也均存放于该目录下。希望了解Ansible源码的话可至该目录下查看其工作原理,当然也可至GitHubGitHub:GitHub是一个通过Git进行版本控制的软件源代码托管服务,由GitHub公司(曾称Logical Awesome)的开发者Chris Wanstrath、PJ Hyett和Tom Preston-Werner使用Ruby on Rails编写而成。 上下载历史或最新AnsibleAnsible GitHub地址:https://github.com/ansible/ansible。 版本。

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等。

    [defaults]
    # inventory = /etc/ansible/hosts         # 定义Inventory
    # library = /usr/share/my_modules/       # 自定义lib库存放目录
    # remote_tmp = $HOME/.ansible/tmp        # 临时文件远程主机存放目录
    # local_tmp = $HOME/.ansible/tmp         # 临时文件本地存放目录
    # forks = 5                                  # 默认开启的并发数
    # poll_interval = 15                        # 默认轮询时间间隔
    # sudo_user  = root                         # 默认sudo用户
    # ask_sudo_pass = True                     # 是否需要sudo密码
    # ask_pass  = True                          # 是否需要密码
    # roles_path = /etc/ansible/roles        # 默认下载的Roles存放的目录
    # host_key_checking = False               # 首次连接是否需要检查key认证,建议设为False
    # timeout = 10                               # 默认超时时间
    # timeout = 10                               # 如没有指定用户,默认使用的远程连接用户
    # log_path = /var/log/ansible.log        # 执行日志存放目录
    # module_name = command                    # 默认执行的模块
    # action_plugins = /usr/share/ansible/plugins/action # action插件的存放目录
    # callback_plugins = /usr/share/ansible/plugins/callback # callback插件的存放目录
    # connection_plugins = /usr/share/ansible/plugins/connection  # connection插件的
                                                                      # 存放目录
    # lookup_plugins = /usr/share/ansible/plugins/lookup   # lookup插件的存放目录
    # vars_plugins = /usr/share/ansible/plugins/vars        # vars插件的存放目录
    # filter_plugins = /usr/share/ansible/plugins/filter   # filter插件的存放目录
    # test_plugins = /usr/share/ansible/plugins/test        # test插件的存放目录
    # strategy_plugins = /usr/share/ansible/plugins/strategy# strategy插件的存放目录
    # fact_caching = memory                                     # getfact缓存的主机信息存放方式
    # retry_files_enabled = False
    # retry_files_save_path = ~/.ansible-retry               # 错误重启文件存放目录
    …

上述是日常可能用到的配置,这些多数保持默认即可。

(2)[privilege_escalation]

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

    [privilege_escalation]
    # become=True              # 是否sudo
    # become_method=sudo      # sudo方式
    # become_user=root        # sudo后变为root用户
    # become_ask_pass=False   # sudo后是否验证密码

(3)[paramiko_connection]

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

    [paramiko_connection]     # 该配置不常用到
    # record_host_keys=False # 不记录新主机的key以提升效率
    # pty=False                 # 禁用sudo功能

(4)[ssh_connection]

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

    [ssh_connection]
    # pipelining = False      # 管道加速功能,需配合requiretty使用方可生效

(5)[accelerate]

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

    [accelerate]
    # accelerate_port = 5099                   # 加速连接端口
    # accelerate_timeout = 30                  # 命令执行超时时间,单位秒
    # accelerate_connect_timeout = 5.0       # 连接超时时间,单位秒
    # accelerate_daemon_timeout = 30         # 上一个活动连接的时间,单位分钟
    # accelerate_multi_key = yes

(6)[selinux]

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

    [selinux]
    # libvirt_lxc_noseclabel = yes
    # libvirt_lxc_noseclabel = yes

(7)[colors]

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

    [colors]
    # highlight = white
    # verbose = blue
    # warn = bright purple
    # error = red
    # debug = dark gray
    # deprecate = purple
    # skip = cyan
    # unreachable = red
    # ok = green
    # changed = yellow
    # diff_add = green
    # diff_remove = red
    # diff_lines = cyan

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

2.3 Ansible命令用法详解

Ansible命令行执行方式有Ad-Hoc、Ansible-playbook两种方式,Web化执行方式其官方提供了付费产品Tower(10台以内免费),个人的话可以基于其提供的API开发类似的Web化产品。关于命令行执行的两种方式Ad-Hoc和Ansible-playbooks、什么是Ad-Hoc及Ad-Hoc与Ansible-playbook的区别我们在第3章有详细介绍,这里不再赘述。需简要说明的是两者没有本质上的区别,Ad-Hoc主要用于临时命令的执行,Ansibel-playbook可以理解为Ad-Hoc的集合,通过一定的规则编排在一起。两者的操作也极其简便,且提供了如with_items、failed_when、changed_when、until、ignore_errors等丰富的逻辑条件和Dry-run的Check Mode。但在Chceck Mode下并不真正执行命令,即将执行的操作不会对端服务器产生任何影响,只模拟命令的执行过程是否能正常执行。

通过第1章的学习我们知道,Ansible的通信默认基于SSH,因此我们需要对主机先进行认证。Ansible认证方式有密码认证和公私钥认证两种方式,其实完全等同于SSH的认证,所以这里关于这两种认证方式不做过多介绍。Ansible默认使用(笔者也建议各位使用)公私钥认证方式,究其原因无非是出于安全的考虑,密码不用明文存放。以本机为例,执行如下命令即可添加本机认证信息。

    // 随机生成公私钥对,ssh-keygen是Linux下认证密钥生成、管理和转换工具,详细用法可参考其man文档
    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

输入的时候会有如下提示:

    Are you sure you want to continue connecting (yes/no)?

输入全小写的英文字母yes即可。

而后会有类似如下提示输入对应root用户的密码信息:

    root@localhost's password:

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

    ssh -i /root/.ssh/stanley.rsa root@localhost

如不提示输入密码即可直接登录则表示密钥验证成功。当然,这里只是为大家简要演示密钥认证的过程,实际应用中为方便起见,一般会使用非root用户生成默认文件名为id_rsa、id_rsa.pub的密钥对,在使用时通过sudo的方式获取权限。

Ansible的命令使用格式如下:

    ansible <host-pattern> [options]

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

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

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

❑-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略有不同,虽然参数选项与Ansible有很多相同的地方,但也新增了针对Ansible-playbook特有的参数。

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

    ansible-playbook playbook.yml

ansible-playbook命令后跟事先编辑好的playbook.yml文件即可。本节只简单介绍其用法,在第4、5、6章有大量内容介绍其写法、高级用法及优化方向。Ansible-playbook新增的功能参数如下:

❑--ask-vault-pass:加密playbook文件时提示输入密码。

❑-D, --diff:当更新的文件数及内容较少时,该选项可显示这些文件不同的地方,该选项结合-C用会有较好的效果。

❑-e EXTRA_VARS, --extra-vars=EXTRA_VARS:在Playbook中引入外部变量。

❑--flush-cache:将fact清除到的远程主机缓存。

❑--force-handlers:强制运行handlers的任务,即使在任务失败的情况下。

❑-i INVENTORY:指定要读取的Inventory文件。

❑--list-tags:列出所有可用的tags。

❑--list-tasks:列出所有即将被执行的任务。

❑--skip-tags=SKIP_TAGS:跳过指定的tags任务。

❑--start-at-task=START_AT_TASK:从第几条任务开始执行。

❑--step:逐步执行Playbook定义的任务,并经人工确认后继续执行下一步任务。

❑--syntax-check:检查Playbook中的语法书写。

❑-t TAGS, --tags=TAGS:指定执行该tags的任务。

在日常工作中,大家经常会遇到批量添加认证的问题,而逐条添加认证方式,如机械地对每台主机都一条条添加认证,那是一件非常麻烦的事,也违反了我们期望的自动化方式。具体的批量添加认证方式请参考第9章。如前面所介绍,Ansible不仅有ansible、ansible-playbook命令,还有ansible-galaxy、ansible-pull、ansible-doc、ansible-vault、ansible-console(2.0版本新增)命令,掌握Ansible的基础用法后,我们将更深一步学习Ansible系列命令。

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

如何获取Ansible的系列命令呢?在终端键入ansible后连续按两次Tab键,会补全所有以ansible字母开头的命令,这些命令均是Ansible系列命令。本节我们来逐一介绍Ansible的系列命令使用。

❑ansible

❑ansible-galaxy

❑ansible-pull

❑ansible-doc

❑ansible-playbook

❑ansible-vault

❑ansible-console

2.4.1 ansible

命令ansible是日常工作中使用率非常高的命令之一,man中是如此定义其功能的:run a command somewhere else,可见其灵活性。ansible命令主要在如下场景使用:

❑非固化需求

❑临时一次性操作

❑二次开发接口调用

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

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

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

图2-2 Ansible执行结果错误的结果返回

图2-3 Ansible执行结果正确的结果返回

不仅ansible命令的执行结果如此设置,Ansible系列命令均如此设置,所以判断Ansible系列命令的执行结果是否正常是一件非常容易的事情,只要看颜色即可。

2.4.2 ansible-galaxy

这里的galaxy和三星手机没有任何关系。ansible-galaxy的功能可以简单地理解为GitHub或PIP的功能,通过ansible-galaxy命令,我们可以根据下载量和关注量等信息,查找和安装优秀的Roles。Roles是Ansible非常重要的一项功能,关于Roles的详细功能会在第6章介绍。在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|list|remove]

init:初始化本地的Roles配置,以备上传Roles至galaxy。

❑info:列表指定Role的详细信息。

❑install:下载并安装galaxy指定的Roles到本地。

❑list:列出本地已下载的Roles。

❑remove:删除本地已下载的Roles。

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

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

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

    ansible-galaxy init --help

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

    Usage: ansible-galaxy init [options] role_name
    Options:
        -f, --force              Force overwriting an existing role
        -h, --help               show this help message and exit
        -c, --ignore-certs     Ignore SSL certificate validation errors.
        -p INIT_PATH, --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
        -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

其他选项与help用法一样。

(3)参数项[options]

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

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

具体可参考如下:

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

因为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模式工作机理刚好相反,其适用于以下场景:①你有数量巨大的机器需要配置,即使使用高并发线程依旧要花费很多时间;②你要在刚启动的、没有网络连接的主机上运行Anisble。

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/king-gw/
    -i /etc/ansible/hosts -U git:// git.kingifa.com/king-gw-ansiblepull >> /var/log/
    ansible-pull.log 2>&1

ansible-pull通常在配置大批量机器的场景下会使用,灵活性稍有欠缺,但效率几乎可以无限提升,对运维人员的技术水平和前瞻性规划有较高要求。

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

Playbook具有编写简单、可定制性高、灵活方便,以及可固化日常所有操作的特点,运维人员应熟练掌握。

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

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

    Vault password:
    Decryption successful

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

到此,我们对Ansible的用法及系列命令已经有了概念性的了解和掌握,接下来我们进一步了解Ansible Inventory文件的配置管理。

2.4.7 ansible-console

ansible-console是Ansible为用户提供的一款交互式工具,用户可以在ansible-console虚拟出来的终端上像Shell一样使用Ansible内置的各种命令,这为习惯于使用Shell交互方式的用户提供了良好的使用体验。ansible-console主要是针对1.X版本中ansible-shell工具而研发的,目前官网还没有对ansible-console进行详细的用法说明,最新版本的Ansible软件包也没有对应的man文档说明。经笔者实测,ansible-console命令的使用格式如下。

在终端键入ansible-console命令后,会进入如图2-4所示的类似Shell一样的交互式终端环境。

图2-4 ansible-console命令用法1

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

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

图2-5 ansible-console命令用法2

如图2-5中的Ansible-console命令用法2所示,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命令用法3如图2-6所示。

图2-6 ansible-console命令用法3

如需启动httpd服务,使用命令service name=httpd state=started,命令用法与Ad-Hoc一致,只是格式上的使用习惯不同而已。如想获取service模块更详细的用法,输入help service命令即可。ansible-console命令用法4如图2-7所示。

图2-7 ansible-console命令用法4

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

ansible-console命令在实际工作中用于Ad-Hoc和Ansible-playbooks之间的场景,常用于集中一批临时操作或命令,使用Ad-Hoc要键入很多次但整体操作的复杂度又不至于使用Playbooks时,这时ansible-console是最佳选择。

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等均支持,本节我们来学习Inventory的使用规则。

2.5.1 定义主机和组

Inventory配置文件遵循INI文件风格,中括号中的字符为组名。其支持将同一个主机同时归并到多个不同的组中,分组的功能为IT人员维护主机列表提供了非常大的便利。此外,若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明,以行为单位分隔配置,详细信息可参考以下代码中的注释。

    #“# ”开头的行表示该行为注释行,即当时行的配置不生效
    # Inventory可以直接为IP地址
    192.168.37.149
    # Inventory同样支持Hostname的方式,后跟冒号加数字表示端口号,默认22号端口
    ntp.magedu.com:2222
    nfs.magedu.com
    #  中括号内的内容表示一个分组的开始,紧随其后的主机均属于该组成员,空行后的主机亦属于该组,即
    web2.magedu.com这台主机也属于[websevers]组
    [websevers]
    web1.magedu.com
    web[10:20].magedu.com # [10:20]表示10~20之间的所有数字(包括10和20),即表示web10.
    magedu.com、web11.magedu.com……web20.magedu.com的所有主机
    web2.magedu.com[dbservers]
    db-a.magedu.com
    db-[b:f].magedu.com  #  [b:f]表示b到f之间的所有数字(包括b和f),即表示db-b.magedu.
    com、db-e.magedu.com……db-f.magedu.com的所有主机

2.5.2 定义主机变量

在日常工作中,通常会遇到非标准化的需求配置,如考虑到安全性问题,业务人员通常将企业内部的Web服务80端口修改为其他端口号,而该功能可以直接通过修改Inventory配置来实现,在定义主机时为其添加主机变量,以便在Playbook中使用针对某一主机的个性化要求。

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

Ansible其实支持多种方式修改或自定义变量,Inventory是其中的一种修改方式,在第6章中我们会详细介绍。不管哪种修改方式,大家一定要有自己的修改规范,以便于区别管理已有配置。

2.5.3 定义组变量

Ansible支持定义组变量,主要针对大量机器的变量定义需求,赋予指定组内所有主机在Playbook中可用的变量,等同于逐一给该组下的所有主机赋予同一变量。定义组变量的参考案例如下:

    [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 定义组嵌套及组变量

Inventory中,组还可以包含其他的组(嵌套),并且也可以向组中的主机指定变量。不过,这些变量只能在Ansible-playbook中使用,而Ansible不支持。组与组之间可以相互调用,并且可以向组中的主机指定变量。

参考示例如下:

    [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

Ansible以简单为其核心理念,上述实现在业务日常使用中并不常见,大家了解其用法即可。

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  #  can  optionally  end  in  '.yml',  '.yaml',  or
    '.json'
    /etc/ansible/group_vars/webservers
    /etc/ansible/host_vars/foosball

对于变量的读取,Ansible遵循如上优先级顺序,因此大家设置变量时尽量沿用同一种方式,以方便维护人员管理。

2.5.6 其他Inventory参数列表

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

    ansible_ssh_host:指定连接主机ansible_ssh_port,指定SSH连接端口,默认22
    ansible_ssh_user:指定SSH连接用户ansible_ssh_pass,指定SSH连接密码ansible_sudo_
    pass:指定SSH连接时sudo密码
    ansible_ssh_private_key_file:指定特有私钥文件
    …

其他内置参数还有数十个,这些参数均可以直接写在命令行或Playbook文件中,以覆盖配置文件中的定义。更多参数请参考官网内置变量参考网址:https://docs.ansible.com/ansible/intro_inventory.html# list-of-behavioral-inventory-parameters。

2.6 Ansible与正则

正则表达式(Patterns)是各类高级语言的必定支持的方法之一,Ansible也不例外。其Patterns功能等同于正则表达式,语法使用也和正则类同,这大大便利了运维的使用。其对于Ansible的灵活性有着极大贡献,该功能同样支持Ansible-playbook。其用法也非常简单。

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

该功能主要针对Inventory的主机列表使用,我们通过一些案例可以更好地了解其功能及用法。在如下示例中主要针对webservers进行正则匹配:

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

(1)All(全量)匹配

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

    // all和*功能相同,但*号需引起来
    ansible all -m ping
    ansible "*" -m ping

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

    ansible 192.168.1.* -m ping

(2)逻辑或(or)匹配

如我们希望同时对多台主机或多个组同时执行,相互之间用“:”(冒号)分隔即可。

    web1:web2

使用方式如下:

    ansible "web1:web2" -m ping

(3)逻辑非(! )匹配

逻辑非用感叹号(! )表示,主要针对多重条件的匹配规则,使用方式如下:

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

(4)逻辑与(&)匹配

和逻辑非一样,逻辑与也主要针对多重条件的匹配规则,只是逻辑上的判断不同。逻辑与使用&表示,请看如下示例:

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

(5)多条件组合

Ansible同样支持多条件的复杂组合,该情况企业应用不多,这里做简单举例说明。

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

(6)模糊匹配

*通配符在Ansible表示0个或多个任意字符,主要应用于一些模糊规则匹配,在平时的使用中应用频率非常高,请参考如下示例:

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

(7)域切割

Ansible底层基于Python,因此也支持域切割。Python字符串域切割的示例如下:

    str = '12345678'
    print str[0:1]

通过[0:1]即可获取数值1。该功能在Ansible中也支持,以如下Inventory内容为例:

    [webservers]
    cobweb
    webbing
    weber

通过截取数组下标可以获得对应变量值。

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

(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

关于Ansible的正则功能到此结束,相信大家在浏览的过程中对其灵活程度也会有所感触,在对Ansible的实际应用过程中也会不断地加深对其理解。

2.7 本章小结

本章着重为大家介绍了Ansible目录结构功能及Ansible命令使用方式。在对Ansible的使用有概念性的了解后,又介绍Ansible系列命令的功能作用,通过简单的案例加深对各命令功能的理解。Inventory是Ansible的核心功能点之一,本章用了约一半内容讲解了Inventory的入门、书写规范、使用技巧及其与正则的结合使用。正则作为运维必备技能与Ansible的结合也使得Ansible愈显灵活,功能也愈显强大,请务必熟练掌握。下章我们将为大家介绍Ansible Ad-Hoc命令集的进阶使用。