在我之前的文章中,我讨论了如何使用 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 中的旧版本。
要为某些用户部署 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,软件包模块将调用 DNF 软件包管理器。
如果您正在进行软件包的简单安装,软件包模块将起作用。如果您正在进行更复杂的工作,您将必须为您的系统使用正确的模块。例如,如果您想忽略 GPG 密钥并在基于 RHEL 的系统上安装所有安全软件包,则需要使用 yum 模块。根据您的 打包模块,您将有不同的选项,但它们通常比 Ansible 的通用软件包模块提供更多参数。
这是一个使用软件包模块的示例
- 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 有不同的模块来启动服务。就像我们之前的示例一样,我们使用软件包模块来执行软件包的通用安装,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 文件。使用模板配置应用程序最棒的事情之一是使用模板。您可以使用您需要的完整配置来配置整个文件,例如 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 条评论