OpenStack系列(二十二) Ansible自动化应用
1 | 作者:李晓辉 |
Ansible自动化概述
Ansible 是个开源工具,特别厉害,好多 IT 任务都能搞定,比如部署基础设施、配置管理,还有给云平台搞各种配置任务。
Ansible 能帮你超快地把多层云应用搭起来。你可以用它创建计算、存储和网络组件,还能在实例上安装软件包,搞负载均衡,处理网络安全,这些在混合云环境里很常见的任务都能搞定。
有些任务是所有服务器都得执行的,比如安全加固或者基础系统配置。还有一些任务只有在特定条件下才会运行。Ansible Playbooks 就是用来安排这些多层部署和跨平台工作流的,而且它是用人类能读懂的格式写的,很容易复用。
OpenStack 模块
Ansible 现在可以很方便地操作 OpenStack,而且有很多模块可以直接跟 OpenStack 的服务交互,不管是管理员还是普通用户都能用。
认证方式
首先,Ansible 是通过一个叫 os-client-config
的东西来完成认证的。它可以从很多地方获取认证信息,比如环境变量、配置文件,或者直接在 playbook 里定义。这些方式都很灵活,你可以根据自己的需求选择。
环境变量:如果你已经设置了像
OS_AUTH
这样的环境变量,Ansible 会直接用它们,不用在模块里再写一遍。配置文件:比如
/etc/ansible/openstack.yaml
或者~/.config/openstack/clouds.yaml
,这些文件里也可以放认证信息。Playbook:你可以在 playbook 里直接定义认证信息,甚至可以用
ansible-vault
加密,这样更安全。模块参数:如果某个任务需要以不同的用户身份运行,还可以在模块的
auth
参数里单独定义。
模块命名
还有一个很关键的点,就是现在新的 OpenStack 模块都以 os_
开头了,比如 os_server
用来创建实例,os_network
用来创建网络。老的模块没有这个前缀,现在正在逐渐被废弃。而且现在模块的名字更贴近用户熟悉的组件名,而不是服务名(比如 nova
),这样更容易理解。
信息收集模块
还有一些带 _info
后缀的模块,比如 os_network_info
,它们可以用来从服务或组件中收集信息。你可以用过滤器和条件语句来优化搜索结果。
查看模块
如果你想看看都有哪些模块可以用,可以直接用命令 ansible-doc --list | grep ^os_
,或者去 Ansible 官方文档 查看详细列表。
运⾏ OpenStack 模块
首先,运行 Ansible 命令的时候,你需要一个目标主机,而且这个主机需要有 SSH 密钥访问权限。在课堂环境里,我们一般用本地主机(localhost
)作为目标,然后用 OpenStack 用户凭证进行认证。
比如,你可以先加载用户凭证文件(比如 developer1-finance-rc
),然后运行一个简单的 Ansible 命令来创建一个密钥对:
1 | (overcloud) [stack@director ~]$ ansible -m os_keypair -a 'name=key state=present \ |
创建实例
创建实例的时候,需要定义一些关键参数,比如 flavor
、image
和 network
,这些参数是必须的,不然实例没法正确创建。Ansible 的模块默认值可能和 OpenStack 命令行工具的默认值不一样,所以有时候可能会出现一些意外行为。
比如,auto_ip
参数默认是开启的,它会自动给实例分配一个浮动 IP 地址。如果你的内部网络连接了多个外部网络,Ansible 会随机选择一个来分配浮动 IP,除非你指定了 floating_ip_pools
。比如:
1 | (overcloud) [stack@director ~]$ ansible -m os_server \ |
如果 auto_ip
是开启的,但没有连接外部网络,命令就会失败,因为没法分配浮动 IP。这种情况下,你可以手动指定一个浮动 IP 地址,比如:
等待资源就绪
有些模块里有一个 wait 参数,比如 os_image 模块。如果你设置了 wait=yes,Ansible 会等待资源进入 ACTIVE 状态,这样它就可以被使用或者与其他资源交互了。还可以用 timeout 参数来设置等待的时间限制。比如:
1 | (overcloud) [stack@director ~]$ ansible -m os_image \ |
创建和删除资源
如果你想创建一个资源,直接运行命令就行,默认情况下 state=present
,不需要显式指定。如果资源已经存在,命令会返回 SUCCESS
,但 changed
会是 false
。
如果你想删除一个资源,就把 state
设置为 absent
,然后提供资源的名字或者 ID。比如,如果你想把一个叫 database1
的服务器从负载均衡池 database_pool
中移除,可以用:
1 | (overcloud) [stack@director ~]$ ansible -m os_member \ |
负载均衡模块
os_loadbalancer
模块比较特殊,因为它可以一次性声明多个子资源,比如浮动 IP、监听器、池和成员。这个模块用起来很强大,但需要注意参数的配置。
创建负载均衡器的时候,可以直接分配一个浮动 IP,而且这个浮动 IP 是在创建负载均衡器的时候一起生成的,不需要提前创建。这比 os_server
模块方便多了,因为 os_server
创建实例的时候,浮动 IP 必须提前存在。
比如,你可以这样创建一个负载均衡器,并且直接分配一个浮动 IP:
1 | (overcloud) [stack@director ~]$ ansible -m os_loadbalancer \ |
运行之后,OpenStack 会自动分配一个内部 VIP 地址(比如 192.168.1.100
),并且绑定一个浮动 IP 地址(比如 172.25.250.181
)。你可以用 OpenStack 命令行工具查看负载均衡器和浮动 IP 的详细信息:
1 | (overcloud) [stack@director ~]$ openstack loadbalancer show \ |
删除负载均衡器的时候,浮动 IP 默认不会被删除。如果你想同时删除浮动 IP,需要设置 delete_public_ip=yes
,比如:
1 | (overcloud) [stack@director ~]$ ansible -m os_loadbalancer \ |
使用 Playbook 自动化操作
如果你需要操作多个资源,或者想自动化一系列操作,用 Playbook 是最好的选择。Ansible 的 Playbook 非常强大,可以用来定义复杂的任务序列,而且支持各种模块、参数、条件判断,几乎可以完成任何应用生命周期的操作。
SSH 密钥访问
在 Playbook 中,你需要确保目标主机有 SSH 密钥访问权限。你可以通过变量来定义 SSH 密钥的位置。这些变量可以定义在 Playbook 中、inventory 文件中、角色中,或者直接在命令行中指定。你甚至可以在 Playbook 运行过程中动态创建变量,或者通过注册返回值来使用变量。
比如,你可以这样定义一个 inventory 文件,指定主机的 SSH 密钥位置:
1 | [production] |
这样,当你运行 Playbook 的时候,Ansible 会自动使用指定的 SSH 密钥去连接目标主机。
Ansible 中带有 _info
后缀的 OpenStack 模块可以用来查询和获取资源信息,这些信息可以保存下来,或者在后续任务中使用。比如 os_flavor_info
、os_networks_info
和 os_server_info
等模块。
参数和缩进
Ansible 的参数(比如
with_items
和register
)和模块定义的缩进级别是一样的。模块参数(比如
wait
和state
)需要在模块定义内部进一步缩进。
过滤结果
有些模块可以通过资源属性值来过滤结果。不同模块的过滤方式可能有所不同。比如:
os_flavor_info
:可以直接在参数中应用条件。比如:ram: ">=1024"
:筛选内存大于 1024 MB 的 flavor。ram: "MIN"
:筛选内存最小的 flavor。vcpus: "2"
:筛选 vCPU 数量为 2 的 flavor。
示例 1:查询带有临时存储的 Flavor
以下是一个查询带有临时存储的 Flavor 的示例。认证信息直接在模块级别定义,优先级高于其他地方定义的认证信息:
1 | - name: "Look for flavors that comply with the conditions" |
示例 2:查询特定租户的活动子网
以下是一个查询特定租户的活动子网的示例:
1 | - name: "Gather active networks from tenant" |
示例 3:查询匹配特定条件的实例
以下是一个查询实例名称中包含 web 并且状态为 active 的实例的示例:
1 | - name: "Query and filter instance information" |
Ansible 提供了很多原生过滤器,可以用来操作数据,比如:
将 JSON 数据转换为 YAML 格式。
从 URL 中提取主机名。
获取字符串的 SHA1 哈希值。
对整数进行加法或乘法运算。
你可以根据需要使用这些过滤器来操作数据,让输出结果更符合你的需求。