配置管理系统与代码即配置(CaC)工具详解
1. 引言
在系统管理领域,配置管理(CM)和代码即配置(CaC)是至关重要的概念与工具。它们能够帮助系统管理员高效地部署、配置和维护 IT 系统。本文将详细介绍几种常见的 CM 系统,如 Puppet、CFEngine,并重点介绍 Ansible 这一强大的 CaC 工具。
2. Puppet 系统
Puppet 是一种广泛使用的 CM 系统,通过编写清单(manifest)来定义系统的配置。以下是一个简单的 Puppet 配置示例,用于配置 Nginx:
require => File['/etc/nginx/sites-available/yourdomain.tld.conf'],
}
# Restart Nginx when the configuration changes
service { 'nginx':
ensure => running,
enable => true,
subscribe => File['/etc/nginx/sites-enabled/yourdomain.tld.conf'],
}
当你创建好清单并将其放置在 Puppet 服务器上后,安装在服务器上的 Puppet 代理会自动获取并执行这些配置。通信通过 TLS 协议进行加密,保障了数据的安全性。
Puppet 代理节点会运行一个 Puppet 代理进程,通过 TCP 端口 8140 连接到主服务器。代理会向服务器发送证书签名请求(CSR),管理员必须批准该请求。一旦 CSR 被批准,代理就可以访问服务器的 Puppet 配置。
代理运行时,会向主服务器请求其配置,服务器会返回一个资源目录,代理会根据该目录对节点进行配置,如安装软件包、更新配置文件或启动/停止服务。配置完成后,代理会向服务器发送报告,用于监控和审计。
3. CFEngine 系统
CFEngine 是一个开源的 CM 系统,由 Mark Burgess 于 1993 年创建。它以其强大而灵活的语言来描述系统配置和执行策略,适用于复杂的 IT 环境。CFEngine 的第一个版本于 1994 年发布,是现存最古老的 CM 工具之一。
CFEngine 不断更新和改进,以适应不断变化的 IT 环境和新兴技术。最新版本 3.18 具有改进的加密、增强的监控功能和更好的云基础设施支持。
以下是一个简单的 CFEngine 配置示例:
##############################################################
# cf.main - for master infrastructure server
##################################################################
###
# BEGIN cf.main
###
control:
access = ( root ) # Only root should run this
site = ( main )
domain = ( example.com )
sysadm = ( admin@example.com )
repository = ( /var/spool/cfengine )
netmask = ( 255.255.255.0 )
timezone = ( CET )
#################################################################
files:
Prepare::
/etc/motd m=0644 r=0 o=root act=touch
4. Ansible 工具
Ansible 是我们选择的 CaC 工具,它用 Python 编写,源代码可自由下载和修改(遵循 Apache License 2.0)。Ansible 具有以下特点:
-
模块化
:Ansible 不是一个单一的工具,而是一个核心程序,每个任务都作为一个单独的模块编写,形成一个库。这种设计产生了一个清晰的 API,任何人都可以使用它来编写自己的模块。
-
幂等性
:无论执行多少次配置,结果始终相同。这是 Ansible 最重要的基本特性之一,你无需知道哪些操作已经执行,当扩展配置并再次运行工具时,它会自动检测系统状态并只应用新的操作。
-
无代理
:Ansible 不会在被配置的系统上安装代理。但要执行 Ansible 脚本,目标系统需要有连接方式(通常是运行 SSH 服务器)和安装 Python 语言。这种模式带来了以下优点:
- Ansible 不关心通信协议,使用 SSH 但不实现它,将细节留给操作系统、SSH 服务器和客户端。你可以自由更换 SSH 解决方案,Ansible 剧本应能按预期工作。
- Ansible 项目无需为管理节点开发和维护单独的程序,这不仅减轻了开发者的负担,还降低了安全漏洞被发现和利用的可能性。
- 在使用代理的解决方案中,如果代理程序因任何原因停止工作,就无法向系统交付新的配置。而 SSH 服务器通常广泛使用,故障概率可忽略不计。
- 使用 SSH 作为通信协议降低了防火墙阻止 CM 系统通信端口的风险。
-
声明式
:编写 Ansible 剧本的人无需过多关注具体的操作方式,只需指定 Ansible 完成后系统的期望状态。例如,要确保 Nginx 安装,配置条目如下:
- name: install nginx
package:
name: nginx
state: present
5. Ansible 的使用基础
5.1 安装 Ansible
在不同的操作系统上安装 Ansible 的方法不同:
-
Debian 系发行版
:
$ sudo apt-get install ansible
- Fedora Linux 发行版 :
$ sudo dnf install ansible
- 使用 Python 虚拟环境和 pip 安装最新版本 :
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -U pip
$ pip install ansible
5.2 简单命令示例:ad hoc ping
$ ansible all -m ping -i inventory
这个命令尝试连接指定主机并打印连接结果。其中,
-m ping
表示使用 ping 模块,
-i inventory
表示使用名为
inventory
的库存文件。如果不指定库存文件,Ansible 将尝试使用
/etc/ansible/hosts
,这通常不是一个好主意。
5.3 库存文件
库存文件是一个简单而强大的工具,用于列出、分组和为管理节点提供变量。以下是一个示例库存文件:
[www]
hostone ansible_host=192.168.1.2 ansible_ssh_private_key_file=~/.ssh/hostone.pem ansible_user=admin
这个文件定义了一个名为
www
的节点组,其中包含一个名为
hostone
的节点,并指定了其 IP 地址、SSH 私钥文件和登录用户名。
6. Ansible 的核心概念
6.1 任务(Tasks)
任务是 Ansible 配置的核心,是要在管理节点上运行的操作。任务包含在剧本(plays)中,可以直接放在剧本中,也可以通过角色(roles)间接包含。
6.2 角色(Roles)
角色是可重用的 Ansible 内容的有限分发,用于在剧本中组织任务、处理程序、变量、插件、模板和文件。通过将剧本分解为角色,可以更轻松高效地管理单独的任务,并且使包含这些任务的文件更易读。
角色在 Ansible 中有预定的目录结构,常见的子目录包括
tasks
、
templates
、
files
、
vars
和
handlers
。以下是一个角色目录结构的示例:
roles/
common/ # this hierarchy represents a "role"
tasks/
main.yml # <-- tasks file can include smaller files if warranted
handlers/
main.yml # <-- handlers file
templates/
ntp.conf.j2 # <------- templates end in .j2
files/
bar.txt # <-- files for use with the copy resource
foo.sh # <-- script files for use with the script resource
vars/
main.yml # <-- variables associated with this role
defaults/
main.yml # <-- default lower priority variables for this role
meta/
main.yml # <-- role dependencies
library/ # roles can also include custom modules
module_utils/ # roles can also include custom module_utils
lookup_plugins/ # or other types of plugins, like lookup in this case
6.3 剧本(Playbooks)
剧本是 Ansible 的入口点,是定义剧本的 YAML 文件。以下是一个简单的剧本示例,用于在管理节点上安装 Nginx 和 PHP 包:
---
- name: Install nginx and php
hosts: www
become: true
tasks:
- name: Install nginx
ansible.builtin.package:
name: nginx
state: present
- name: Install php
ansible.builtin.package:
name: php8
state: present
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
在运行剧本之前,建议使用
ansible-lint
工具检查剧本的语法错误和最佳实践:
$ ansible-lint install.yaml
7. 总结
使用 CaC 工具具有许多优点,如配置可以通过自动化工具进行语法检查、可以无限次应用且结果相同、可以在多个系统上并行运行、可以保存在版本控制系统中以便查看更改历史和注释,还可以由自动化工具运行,减少了人工干预。
Ansible 作为一种强大的 CaC 工具,通过其模块化、幂等性、无代理和声明式的特点,为系统管理员提供了一种高效、灵活的方式来管理系统配置。通过合理使用角色和剧本,可以更好地组织和管理复杂的配置任务。
流程图:Puppet 工作流程
graph LR
A[创建 Puppet 清单] --> B[放置在 Puppet 服务器]
B --> C[Puppet 代理获取清单]
C --> D[代理发送 CSR 请求]
D --> E{管理员批准 CSR}
E -- 是 --> F[代理访问配置]
F --> G[代理请求配置]
G --> H[服务器返回资源目录]
H --> I[代理应用配置]
I --> J[代理发送报告]
E -- 否 --> K[等待批准]
表格:Ansible 安装方法对比
| 操作系统 | 安装命令 |
|---|---|
| Debian 系发行版 |
sudo apt-get install ansible
|
| Fedora Linux 发行版 |
sudo dnf install ansible
|
| 使用 Python 虚拟环境和 pip |
python3 -m venv venv; source venv/bin/activate; pip install -U pip; pip install ansible
|
8. Ansible 剧本的实际操作与优化
8.1 剧本的调试与修正
当我们编写好一个 Ansible 剧本后,使用
ansible-lint
工具可以检查剧本中的语法错误和不符合最佳实践的地方。例如,对于之前的
install.yaml
剧本,运行
ansible-lint install.yaml
后可能会得到如下输出:
WARNING: PATH altered to expand ~ in it. Read https://stackoverflow.com/a/44704799/99834 and correct your system configuration.
WARNING Listing 9 violation(s) that are fatal
yaml[trailing-spaces]: Trailing spaces
install.yaml:1
yaml[truthy]: Truthy value should be one of [false, true]
install.yaml:4
fqcn[action-core]: Use FQCN for builtin module actions (package).
install.yaml:6 Use `ansible.builtin.package` or `ansible.legacy.package` instead.
[...]
yaml[empty-lines]: Too many blank lines (1 > 0)
install.yaml:18
Read documentation for instructions on how to ignore specific rule violations.
Rule Violation Summary
count tag profile rule associated tags
1 yaml[empty-lines] basic formatting, yaml
1 yaml[indentation] basic formatting, yaml
3 yaml[trailing-spaces] basic formatting, yaml
1 yaml[truthy] basic formatting, yaml
3 fqcn[action-core] production formatting
Failed after min profile: 9 failure(s), 0 warning(s) on 1 files.
根据这些提示,我们可以对剧本进行修正。修正后的剧本如下:
---
- name: Install nginx and php
hosts: www
become: true
tasks:
- name: Install nginx
ansible.builtin.package:
name: nginx
state: present
- name: Install php
ansible.builtin.package:
name: php8
state: present
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
8.2 剧本的运行与结果分析
使用
ansible-playbook
命令来运行剧本:
$ ansible-playbook -i inventory install.yaml
运行结果可能如下:
PLAY [Install nginx and php] ***************************************************
TASK [Gathering Facts] *********************************************************
ok: [hostone]
TASK [Install nginx] ***********************************************************
changed: [hostone]
TASK [Install php] *************************************************************
fatal: [hostone]: FAILED! => {"changed": false, "msg": "No package matching 'php8' is available"}
PLAY RECAP *********************************************************************
hostone : ok=2 changed=1 reachable=0 failed=1 skipped=0 rescued=0 ignored=0
从结果中可以看出,
nginx
安装成功,但
php8
安装失败,原因是目标系统中没有
php8
包。经过检查,发现实际可用的是
php7.4
包,修改剧本后再次运行:
$ ansible-playbook -i inventory install.yaml
新的运行结果如下:
PLAY [Install nginx and php] ***************************************************
TASK [Gathering Facts] *********************************************************
ok: [hostone]
TASK [Install nginx] ***********************************************************
ok: [hostone]
TASK [Install php] *************************************************************
changed: [hostone]
TASK [Start nginx] *************************************************************
ok: [hostone]
PLAY RECAP *********************************************************************
hostone : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
此时,
nginx
已安装,
php7.4
也安装成功,并且
nginx
已启动。
8.3 剧本的优化:循环任务
为了避免为每个要安装的包都编写一个单独的任务,我们可以使用循环。修改后的剧本如下:
---
- name: Install nginx and php
hosts: www
become: true
tasks:
- name: Install nginx
ansible.builtin.package:
name: '{{ item }}'
state: present
with_items:
- nginx
- php7.4
- gcc
- g++
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
在运行这个剧本之前,先使用
ansible-lint
检查:
$ ansible-lint install.yaml
如果检查通过,再运行剧本:
$ ansible-playbook -i inventory install.yaml
运行结果会显示每个包的安装情况。
8.4 剧本的优化:使用通知和处理程序
假设我们要安装一个 Nginx 的页面配置,并在服务设置完成后只重启一次 Nginx。可以使用
notify
和
handlers
来实现。完整的剧本如下:
---
- name: Install nginx and php
hosts: www
become: true
tasks:
- name: Install nginx
ansible.builtin.package:
name: '{{ item }}'
state: present
with_items:
- nginx
- php7.4
- gcc
- g++
notify:
- Start nginx
- name: Copy service configuration
ansible.builtin.copy:
src: "files/service.cfg"
dest: "/etc/nginx/sites-available/service.cfg"
owner: root
group: root
mode: '0640'
- name: Enable site
ansible.builtin.file:
src: "/etc/nginx/sites-available/service.cfg"
dest: "/etc/nginx/sites-enabled/default"
state: link
notify:
- Restart nginx
handlers:
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
运行这个剧本后,Ansible 会根据任务的执行情况触发相应的处理程序。
9. Ansible 角色的使用与管理
9.1 角色的概念与作用
随着剧本的复杂度增加,将任务分割成角色可以使管理更加清晰。角色可以根据管理节点的功能进行分组,例如 HTTP 服务器、数据库服务器、文件服务器等。一个管理节点可以有多个角色。
9.2 角色的目录结构
Ansible 角色有预定的目录结构,常见的子目录包括
tasks
、
templates
、
files
、
vars
和
handlers
。以下是一个角色目录结构的示例:
roles/
common/ # this hierarchy represents a "role"
tasks/
main.yml # <-- tasks file can include smaller files if warranted
handlers/
main.yml # <-- handlers file
templates/
ntp.conf.j2 # <------- templates end in .j2
files/
bar.txt # <-- files for use with the copy resource
foo.sh # <-- script files for use with the script resource
vars/
main.yml # <-- variables associated with this role
defaults/
main.yml # <-- default lower priority variables for this role
meta/
main.yml # <-- role dependencies
library/ # roles can also include custom modules
module_utils/ # roles can also include custom module_utils
lookup_plugins/ # or other types of plugins, like lookup in this case
9.3 实际创建角色
假设我们有一个
install.yaml
剧本,为了更好地管理任务,我们创建
www
和
development
两个角色。
首先,修改库存文件:
[www]
hostone ansible_host=192.168.1.2 ansible_ssh_private_key_file=~/.ssh/hostone.pem ansible_user=admin
[development]
hostone ansible_host=192.168.1.3 ansible_ssh_private_key_file=~/.ssh/hostone.pem ansible_user=admin
然后,修改
install.yaml
剧本:
---
- name: Install nginx and php
hosts: www
roles:
- www
become: true
- name: Install development packages
hosts: development
roles:
- development
become: true
www
角色的
tasks/main.yaml
文件内容如下:
---
- name: Install nginx
ansible.builtin.package:
name: '{{ item }}'
state: present
with_items:
- nginx
- php7.4
notify:
- Start nginx
- name: Copy service configuration
ansible.builtin.copy:
src: "files/service.cfg"
dest: "/etc/nginx/sites-available/service.cfg"
owner: root
group: root
mode: '0640'
- name: Enable site
ansible.builtin.file:
src: "/etc/nginx/sites-available/service.cfg"
dest: "/etc/nginx/sites-enabled/default"
state: link
notify:
- Restart nginx
www
角色的
handlers/main.yaml
文件内容如下:
---
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
listen: "Start nginx"
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
listen: "Restart nginx"
development
角色的
tasks/main.yaml
文件内容如下:
---
- name: Install compilers
ansible.builtin.package:
name: '{{ item }}'
state: present
with_items:
- gcc
- g++
10. 总结与展望
10.1 使用 CaC 工具的优势总结
使用代码即配置(CaC)工具具有诸多优势:
-
语法检查
:配置可以通过自动化工具进行语法检查,确保配置的正确性。
-
幂等性
:可以无限次应用且结果相同,避免了重复操作带来的问题。
-
并行运行
:可以在多个系统上并行运行,提高了配置效率。
-
版本控制
:可以保存在版本控制系统中,方便查看更改历史和注释。
-
自动化执行
:可以由自动化工具运行,减少了人工干预。
10.2 Ansible 的优势与应用前景
Ansible 作为一种强大的 CaC 工具,通过其模块化、幂等性、无代理和声明式的特点,为系统管理员提供了一种高效、灵活的方式来管理系统配置。在未来,随着 IT 系统的不断发展和复杂化,Ansible 的应用前景将更加广阔。通过合理使用角色和剧本,可以更好地组织和管理复杂的配置任务,满足不同场景的需求。
流程图:Ansible 剧本运行流程
graph LR
A[编写 Ansible 剧本] --> B[使用 ansible-lint 检查]
B -- 通过 --> C[使用 ansible-playbook 运行]
B -- 未通过 --> D[修正剧本]
D --> B
C --> E{任务执行情况}
E -- 成功 --> F[结束]
E -- 失败 --> G[分析失败原因]
G --> D
表格:Ansible 角色与任务管理对比
| 管理方式 | 优点 | 缺点 |
|---|---|---|
| 单一剧本 | 简单直接,适合简单配置 | 复杂配置时难以管理 |
| 角色管理 | 清晰组织任务,提高可维护性 | 需要了解角色目录结构 |
超级会员免费看
42

被折叠的 条评论
为什么被折叠?



