基础

主机清单,inventory,是存放被管理机器的IP或域名的地方,清单里的IP地址可以分组,如前端机器一组,后端机器一组,默认这个配置文件在/etc/ansible/hosts,如下是一个实例

# cat /etc/ansible/hosts
[webservers]
foo.example.com
bar.example.com
192.168.31.10

[dbservers]
one.example.com
two.example.com
three.example.com

组名称遵循一般的变量命名规则,不能以数字开头,特殊符号只能用下划线

在playbook中使用

# cat main1.yml
---
- hosts: dbservers
  gather_facts: yes

  tasks:

    - name: test1
      debug:
        msg: "just for a test"


ansible-playbook main1.yml #这种执行方式就是去默认主机清单里找,即 /etc/ansible/hosts

ansible-playbook main1.yml -i hosts #这种执行方式主机清单就是当前目录的hosts文件,路径也可以用绝对路径,hosts文件名称不固定

执行playbook时,加上 -v 参数,会输出主机清单路径

在命令行中(Ad-Hoc)使用

ansible webservers -m ping

默认的组名称 default groups

有两个组名称比较特殊,是自带的,默认就有的,allungrouped,顾名思义一个all分组代表全部机器,ungrouped代表不属于任何一个分组的机器,如下一份主机清单示例

# cat /etc/ansible/hosts
192.168.31.10 #属于 ungrouped 和 all 分组
192.168.31.11 #属于 ungrouped 和 all 分组

[webservers]
foo.example.com #属于 webservers 和 all 分组
bar.example.com #属于 webservers 和 all 分组

[dbservers]
one.example.com   #属于 dbservers 和 all 分组
two.example.com   #属于 dbservers 和 all 分组
three.example.com #属于 dbservers 和 all 分组

因此我们常使用的Ansible检查机器连通性的命令,或者playbook的分组名称,指定为all,即表示全部机器都应用该playbook

allungrouped属于保留分组名字,不能自己写到主机清单的分组名称中去

常见的机器分组方式

大致有三种

  1. 按照服务(业务、角色)分,如 web、mysql、php、dns
  2. 按照地理位置(机房)分,如 north、sourth、beijing、shenzhen
  3. 按照时间阶段分,即生产prod、预生产stag、测试test

机器分组的嵌套

一台机器,可能同属于多个分组,如某台机器是web,在北方,生产环境,那么这台机器会出现在三个分组中

之前我们介绍的主机清单都是配置文件(INI)那种格式,而Ansible还支持YAML格式书写主机清单,对于具有嵌套关系的主机清单,使用YAML格式书写更清楚,如下示例

all:
  hosts:
    192.168.21.100:
  children:
    webservers:
      hosts:
        192.168.31.101:
        192.168.31.102:
        192.168.31.103:
    dbservers:
      hosts:
        192.168.41.101:
        192.168.41.102:
        192.168.41.103:
    east:
      hosts:
        192.168.41.101:
        192.168.41.102:
        192.168.41.103:
    west:
      hosts:
        192.168.31.101:
        192.168.31.102:
        192.168.31.103:
    prod:
      hosts:
        192.168.31.101:
        192.168.31.102:
        192.168.31.103:
    test:
      hosts:
        192.168.41.103:
    centos:
      children:
        webservers:    
    ubuntu:
      children:
        dbservers:

批量选择一群机器

批量选择www01 ~ www50机器

[webservers]
www[01:50].example.com

批量选择dba ~ dbf机器

[databases]
db-[a:f].example.com

这种情况类似正则匹配,一般很少用,比如要下线某个机器,这样的写法就比较麻烦了

其它可以使用的匹配语法,如下表所示

Description Pattern(s) Targets
All hosts all (or *) 匹配全部机器
One host host1 匹配单个机器
Multiple hosts host1,host2 匹配多个机器 逗号分隔
One group webservers 匹配一个机器分组
Multiple groups webservers:dbservers 匹配多个机器分组 冒号分割
Intersection of groups webservers:&staging 匹配同时在webservers和staging分组里的机器

在主机清单里定义变量

参考3.1 Playbooks 高级一里的相关内容

控制SSH的连接变量(connection variables)

这一类变量专门用来控制目标机器的SSH连接参数,比如加入目标机器SSH端口不是监听在默认的22端口,就需要改动这里

变量 含义
ansible_connection 远程通信方式,smart、ssh、paramiko,默认是smart表示自动,该值一般不需要动,paramiko是一个python操作ssh的包
ansible_host 一般用不上,除非给出的域名无法解析(如果这样直接用IP地址就好)
ansible_port 指定ssh端口,默认22
ansible_user 指定ssh连接的用户,默认是当前用户
ansible_password 指定ssh连接的密码(如果没有做免密登录的话)
ansible_python_interpreter 指定目标机器的python路径,默认去找/usr/bin/python,如果这个地没有,或者这个地的python版本太低,则需要修改

使用示例

#cat /etc/ansible/hosts
some_host         ansible_port=2222   ansible_user=manager
192.168.31.100    ansible_user=root   ansible_password=123456
freebsd_host      ansible_python_interpreter=/usr/local/bin/python

可以看到这些变量都是以ansible开头的,官方文档里似乎没提能不能被覆盖,不过我们自己最好不要定义ansible开头的变量 使用账号密码直接控制机器,需要手动进行一次登录,以记住该key

参考资料

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html
https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html
https://docs.ansible.com/ansible/latest/user_guide/connection_details.html