在我之前的文章中,我讨论了如何使用 Ansible 补丁系统和安装应用程序。在本文中,我将向您展示如何使用 Ansible 做其他事情,这将使您作为系统管理员的生活更轻松。首先,我想分享我为什么选择 Ansible。
我开始使用 Ansible 是因为它简化了系统补丁的打法。我可以随意运行一些临时命令,还可以运行别人编写的一些 Playbook。但是我并没有深入了解,因为我运行的 Playbook 使用了大量的 lineinfile 模块,而且说实话,我的 regex
技术并不存在。由于我管理层的指示和说明,我的能力也受到限制:“你只能运行这个 Playbook,这就是你所能做的全部。”
离开那份工作后,我开始在一个大部分基础设施都在云中的团队工作。在适应了团队并了解一切如何运作之后,我开始尝试寻找更多自动化的方法。我们花费两到三个月的时间来大规模部署虚拟机——手动完成所有工作,包括每个虚拟机的生命周期,从供应到退役。我们的工作经常落后于计划,因为我们花费大量时间进行维护。当有人休假时,其他人不得不接管,但对他们所做的工作知之甚少。
深入了解 Ansible
分享关于如何解决问题的想法是我们在 IT 和开源领域可以做的最好的事情之一,所以我通过在 Ansible 中提交问题和在 其他人创建的角色中提问来寻求帮助。
阅读文档(包括以下主题)是开始学习 Ansible 的最佳方式。
如果您正在尝试弄清楚可以使用 Ansible 做什么,请花一些时间思考您每天进行的活动,那些花费大量时间并且最好花在其他事情上的活动。以下是一些例子
- 管理系统中的帐户:创建用户,将他们添加到正确的组,并添加 SSH 密钥…… 当我们需要构建大量系统时,这些事情过去常常花费我几天的时间。即使使用 shell 脚本,这个过程也非常耗时。
- 维护所需软件包的列表:这可能是您安全态势的一部分,并包括您的应用程序所需的软件包。
- 安装应用程序:您可以使用当前的文档,并通过找到正确的 模块 将应用程序安装转换为任务。
- 配置系统和应用程序:您可能想要通过添加一两行来更改不同环境(例如,生产环境与开发环境)的
/etc/ssh/sshd_config
,或者您可能希望您管理的每个系统中的文件看起来都一样。 - 在云中配置 VM:当您需要为您的应用程序启动一些类似的虚拟机并且您厌倦了使用 UI 时,这非常有用。
现在让我们看看如何使用 Ansible 自动化一些重复性任务。
管理用户
如果您需要创建大量用户和组的列表,并将用户分散在不同的组中,则可以使用 循环。让我们从创建组开始
- name: create user groups
group:
name: "{{ item }}"
loop:
- postgresql
- nginx-test
- admin
- dbadmin
- hadoop
您可以使用特定的参数创建用户,如下所示
- name: all users in the department
user:
name: "{{ item.name }}"
group: "{{ item.group }}"
groups: "{{ item.groups }}"
uid: "{{ item.uid }}"
state: "{{ item.state }}"
loop:
- { name: 'admin1', group: 'admin', groups: 'nginx', uid: '1234', state: 'present' }
- { name: 'dbadmin1', group: 'dbadmin', groups: 'postgres', uid: '4321', state: 'present' }
- { name: 'user1', group: 'hadoop', groups: 'wheel', uid: '1067', state: 'present' }
- { name: 'jose', group: 'admin', groups: 'wheel', uid: '9000', state: 'absent' }
查看用户 jose
,您可能会意识到 state: 'absent'
删除了此用户帐户,并且您可能想知道为什么您在删除他时需要包含所有其他参数。这是因为这是一个很好的地方,可以保存重要更改的文档,以用于审计或安全合规性。通过将角色以 Git 作为您的真实来源存储在 Git 中,如果您以后需要回答有关更改原因的问题,您可以返回并查看 Git 中的旧版本。
要为某些用户部署 SSH 密钥,您可以使用与上一个示例中相同类型的循环。
- name: copy admin1 and dbadmin ssh keys
authorized_key:
user: "{{ item.user }}"
key: "{{ item.key }}"
state: "{{ item.state }}"
comment: "{{ item.comment }}"
loop:
- { user: 'admin1', key: "{{ lookup('file', '/data/test_temp_key.pub'), state: 'present', comment: 'admin1 key' }
- { user: 'dbadmin', key: "{{ lookup('file', '/data/vm_temp_key.pub'), state: 'absent', comment: 'dbadmin key' }
在这里,我们指定了 user
,如何使用 lookup
查找密钥,state
,以及描述密钥目的的 comment
。
安装软件包
软件包安装可能因您使用的打包系统而异。您可以使用 Ansible facts 来确定要使用的模块。Ansible 确实提供了一个名为 package 的通用模块,该模块使用 ansible_pkg_mgr
并为系统调用适当的软件包管理器。例如,如果您使用的是 Fedora,则 package 模块将调用 DNF 软件包管理器。
如果您正在进行简单的软件包安装,则 package 模块将起作用。如果您正在进行更复杂的工作,则必须使用适用于您系统的正确模块。例如,如果您想忽略 GPG 密钥并安装基于 RHEL 的系统上的所有安全软件包,则需要使用 yum 模块。根据您的 打包模块,您将有不同的选项,但它们通常比 Ansible 的通用 package 模块提供更多的参数。
这是一个使用 package 模块的示例
- name: install a package
package:
name: nginx
state: installed
以下示例使用 yum 模块来安装 NGINX,禁用 repo 中的 gpg_check
,忽略存储库的证书,并跳过可能出现的任何损坏的软件包。
- name: install a package
yum:
name: nginx
state: installed
disable_gpg_check: yes
validate_certs: no
skip_broken: yes
这是一个使用 Apt 的示例。Apt 模块告诉 Ansible 卸载 NGINX 并且不更新缓存
- name: install a package
apt:
name: nginx
state: absent
update_cache: no
在安装软件包时可以使用 loop
,但是如果您传递列表,则会单独处理它们
- name:
- nginx
- postgresql-server
- ansible
- httpd
注意:请确保您知道您正在使用的软件包管理器中您想要的软件包的正确名称。有些名称会根据软件包管理器而改变。
启动服务
与软件包非常相似,Ansible 有不同的模块来启动服务。就像我们之前的示例一样,我们使用 package 模块来执行软件包的常规安装,service 模块对服务执行类似的工作,包括 systemd 和 Upstart。(查看模块的文档以获取完整列表。)这是一个例子
- name: start nginx
service:
name: nginx
state: started
如果您只是启动和停止应用程序并且不需要任何更复杂的东西,则可以使用 Ansible 的 service 模块。但是,就像 yum 模块一样,如果您需要更多选项,则需要使用 systemd 模块。例如,如果您修改 systemd 文件,则需要执行 daemon-reload
,service 模块将不适用于此;您将不得不使用 systemd 模块。
- name: reload postgresql for new configuration and reload daemon
systemd:
name: postgresql
state: reload
daemon-reload: yes
这是一个很好的起点,但它可能会变得很麻烦,因为该服务总是会重新加载/重新启动。这是一个使用 handler 的好地方。
如果您使用最佳实践并使用 ansible-galaxy init "role name"
创建了您的角色,那么您应该拥有完整的 目录结构。您可以将上面的代码包含在 handlers/main.yml
中,并在您使用应用程序进行更改时调用它。例如
handlers/main.yml
- name: reload postgresql for new configuration and reload daemon
systemd:
name: postgresql
state: reload
daemon-reload: yes
这是调用 handler 的任务
- name: configure postgresql
template:
src: postgresql.service.j2
dest: /usr/lib/systemd/system/postgresql.service
notify: reload postgresql for new configuration and reload daemon
它通过更改 systemd 文件来配置 PostgreSQL,但不是在任务中定义重新启动(像以前一样),而是调用 handler 在运行结束时执行重新启动。这是配置应用程序并使其保持幂等性的好方法,因为 handler 仅在任务更改时运行 - 而不是在配置中间运行。
上一个示例使用了 template 模块和 Jinja2 文件。使用 Ansible 配置应用程序最棒的事情之一是使用模板。您可以使用您需要的完整配置来配置整个文件,例如 postgresql.service
。但是,您可以不更改每一行,而是使用变量并在其他地方定义选项。这将允许您随时更改任何变量并使其更加通用。例如
[database]
DB_TYPE = "{{ gitea_db }}"
HOST = "{{ ansible_fqdn}}:3306"
NAME = gitea
USER = gitea
PASSWD = "{{ gitea_db_passwd }}"
SSL_MODE = disable
PATH = "{{ gitea_db_dir }}/gitea.db
这会在 Gitea 的文件 app.ini
上配置数据库选项。这类似于编写 Ansible 任务,即使它是一个配置文件,并且可以轻松地定义变量和进行更改。如果您使用 group_vars,这可以进一步扩展,这允许您为所有系统和特定组(例如,生产环境与开发环境)定义变量。这使得管理变量更容易,并且您不必在每个角色中指定相同的变量。
配置系统
我们已经介绍了您可以在系统上使用 Ansible 执行的几件事,但我们尚未讨论如何配置系统。这是一个使用 OpenStack 云解决方案配置虚拟机 (VM) 的示例。
- name: create a VM in openstack
osp_server:
name: cloudera-namenode
state: present
cloud: openstack
region_name: andromeda
image: 923569a-c777-4g52-t3y9-cxvhl86zx345
flavor_ram: 20146
flavor: big
auto_ip: yes
volumes: cloudera-namenode
所有 OpenStack 模块都以 os
开头,这使得查找它们更容易。上面的配置使用 osp-server 模块,该模块允许您添加或删除实例。它包括 VM 的名称、其状态、其云选项以及它如何验证 API。有关 cloud.yml 的更多信息可在 OpenStack 文档中找到,但如果您不想使用 cloud.yml,则可以使用一个字典,其中使用 auth
选项列出您的凭据。如果要删除 VM,只需将 state:
更改为 absent
。
假设您有一个服务器列表,因为您无法弄清楚如何使应用程序工作而关闭了它们,并且您想再次启动它们。您可以使用 os_server_action
重新启动它们(或者如果您想从头开始,则可以重建它们)。
这是一个启动服务器并告诉模块实例名称的示例
- name: restart some servers
os_server_action:
action: start
cloud: openstack
region_name: andromeda
server: cloudera-namenode
大多数 OpenStack 模块都使用类似的选项。因此,要重建服务器,我们可以使用相同的选项,但将 action
更改为 rebuild
并添加我们想要使用的 image
os_server_action:
action: rebuild
image: 923569a-c777-4g52-t3y9-cxvhl86zx345
做其他事情
有很多用于系统管理任务的模块,但如果您要执行的任务没有对应的模块该怎么办呢?可以使用 shell 和 command 模块,它们允许您像在命令行中一样运行任何命令。这是一个使用 OpenStack CLI 的示例。
- name: run an opencli command
command: "openstack hypervisor list"
您可以使用 Ansible 以多种方式完成日常系统管理任务。使用这种自动化工具可以将您最困难的任务转化为简单的解决方案,节省您的时间,并让您的工作日更短、更轻松。
4 条评论