ansible入门指南 - inventory主机清单

inventory

inventory描述了被管理的机器清单, 这些机器通过何中方式连接. inventory文件的描述越详细, 执行ansible的时候需要指定的参数就越少. 例如在inventory文件中指定了ssh的连接用户, 那么在执行ansible命令的时候就可以不需要用 -u参数指定用户

inventory支持 iniyaml 两种格式, 快速入门中我们使用的是 ini 格式, 下面使用 yaml格式测试

举个例子, 如下就是一个合法的 yaml格式的inventory文件

prod:
  hosts:
    tomcat1:
      ansible_host: 127.0.0.1
    tomcat2:
      ansible_host: localhost

uat:
  hosts:
    tomcat:
      ansible_host: 192.168.68.123

该inventory文件中, 定义了两个组, 分别为prod和uat,组名是大小写敏感的, 对应生产和uat环境, 生产环境两台主机, uat环境一台主机, tomcat1, tomcat2 是主机名, 如果没有指定ansible_host变量, 就会用使用主机名连接. 把改文件保存为inventory.yaml, 继续接下来的学习

ansible-inventory -i inventory.yaml --list
# 输出所有节点信息
{
    "_meta": {
        "hostvars": {
            "tomcat": {
                "ansible_host": "192.168.68.123"
            },
            "tomcat1": {
                "ansible_host": "127.0.0.1",
                "discovered_interpreter_python": {
                    "__ansible_unsafe": "/usr/bin/python3"
                }
            },
            "tomcat2": {
                "ansible_host": "localhost",
                "discovered_interpreter_python": {
                    "__ansible_unsafe": "/usr/bin/python3"
                }
            }
        }
    },
    "all": {
        "children": [
            "ungrouped",
            "prod",
            "uat"
        ]
    },
    "prod": {
        "hosts": [
            "tomcat1",
            "tomcat2"
        ]
    },
    "uat": {
        "hosts": [
            "tomcat"
        ]
    }
}

使用ansible检查uat环境的主机是否能连通

ansible -i inventory.yaml -m ping uat
# 如果能正常连通, 输出结果应当和下面类似
tomcat | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

此处使用 -m 参数指定使用的模块. ansible执行命令有两种方式, Ad-Hocplaybook , Ad-Hoc 是在命令行执行的一次性命令,例如此处我们用 ping模块检查主机是否在线, Ad-Hoc 命令方便快捷, 但是不可重用. playbook 就表示执行一系列的比较长的指令, 比如针对需要配置 LAMP环境的需求, 这里使用playbook执行完后, 可以拿到其他机器上接着用

-i inventory.yaml 指定inventory文件, 可以 -i 参数可以指定单个主机而不通过inventory文件, ansible -i 127.0.0.1, -m ping 127.0.0.1 也可以直接运行, -i 127.0.0.1 后面的 , 不能漏了.

inventory中的元组/子组(metagroup)

使用元组可以更好地在一个inventory文件中管理多个逻辑分组, 此处使用官网的例子, 下面的inventory中, leafsspines 共同属于 network 分组, network 组和 webservers 组属于 datacenter 分组. 使用 children 关键字管理哪个组属于哪个元组

leafs:
  hosts:
    leaf01:
      ansible_host: 192.0.2.100
    leaf02:
      ansible_host: 192.0.2.110

spines:
  hosts:
    spine01:
      ansible_host: 192.0.2.120
    spine02:
      ansible_host: 192.0.2.130

network:
  children:
    leafs:
    spines:

webservers:
  hosts:
    webserver01:
      ansible_host: 192.0.2.140
    webserver02:
      ansible_host: 192.0.2.150

datacenter:
  children:
    network:
    webservers:

inventory中的变量

inventory的变量可以指定使用什么用户登录被控机器, 使用什么用户执行sudo命令等

prod:
  hosts:
    tomcat1:
      ansible_host: 127.0.0.1
    tomcat2:
      ansible_host: localhost

uat:
  hosts:
    tomcat:
      ansible_host: 192.168.68.123
      ansible_ssh_user: root

此处在上面的inventory文件中添加了 ansible_ssh_user , 然后重新执行 ansible -i inventory.yaml uat -m ping

tomcat | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: root@192.168.68.123: Permission denied (publickey,password).",
    "unreachable": true
}

从结果可以看到ansible尝试使用root用户登录主机, 但是登录失败了, 因为没有添加免密登录

变量也可以加到组的下面, 对组中的所有用户生效

uat:
  hosts:
    tomcat:
      ansible_host: 192.168.68.123
  vars:
    ansible_ssh_user: root

如果主机存在于多个组中, 但是在不同组中变量的值有冲突, 按照以下优先级(越下面优先级越高), 并且父组的变量会被子组继承

  • all group (because it is the ‘parent’ of all other groups)
  • parent group
  • child group
  • host

如果在相同的级别中的变量, 可以使用 ansible_group_priority 设置变量优先级, 如果没有设置, 优先级就是1, 数字越大优先级越高

a_group:
  vars:
    testvar: a
    ansible_group_priority: 10
b_group:
  vars:
    testvar: b

在上面这个例子中, testvar的值会设为a, 因为优先级10更高一些

ansible的内置变量参考 https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#connecting-to-hosts-behavioral-inventory-parameters

运行时指定多个inventory

ansible 执行时可以指定多个inventory文件, 参考如下的方式

# 使用多个inventory文件
ansible -i inventory1.yaml -i inventory2.yaml all -m ping

# 指定inventory的目录, 目录下可以放多个inventory文件
ansible -i inventory/ all -m ping

如果inventory文件夹下有多个文件, 且inventory之间存在依赖关系, 例如hosts.yaml中定义了多个组的机器, groups.yaml中定义了组与组的包含, 如果先加载groups.yaml, 那么ansible会可能运行失败, 因为groups.yaml中定义的子组ansible没找到.

ansible 根据文件名称的ASCII码按顺序加载inventory, 可以通过修改文件名来引导加载顺序, 例如 01-hosts.yaml, 02-groups.yaml, 这样01-hosts.yaml就会先于02-groups.yaml加载

动态的inventory

如果需要管理的机器由于业务的变化经常变动, 那么就会需要动态inventory来管理机器. 动态的inventory可以从外部数据源动态获取运行中的机器

有两种方式获取动态的inventory: inventory plugininventory scripts

inventory plugin 官网提供了几个示例 cobbler, openstack

使用语法指定运行的主机或组

可以用如下的语法限制运行脚本的主机, 在ansible命令中和playbook中都适用. 适用 --limit 参数限制执行的目标

ansible all -m [module] -a "[module options]" --limit 'group1'
描述 语法 慕楠
所有主机 all (or *)
单个主机 host1
多个主机 host1:host2 (or host1,host2)
一个组 webservers
多个组 webservers:dbservers webservers组 + dbservers组中的机器
排除组 webservers:!atlanta 在webservers组中但是不在atlanta组中的机器
组的交集 webservers:&staging 在webservers组中并且在staging组中的机器

语法只能匹配inventory中的主机名或者组名, 不能匹配地址

当ansible的配置文件中启用了 RETRY_FILE_ENABLED , ansible-playbook 运行结束后就会创建一个 .retry 文件, 我们可以重新运行playbook并指定retry文件, 避免在运行成功的机器上重新运行脚本

ansible-playbook site.yml -i inventory --limit@site.retry
posted @ 2023-08-18 16:04  Chinor  阅读(137)  评论(0编辑  收藏  举报