Ansible 学习笔记
简介
- 基于Python开发的自动化运维工具
- 集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点
- 基于模块工作,本身没有批量部署能力,批量部署由运行的模块实现
- 提供自动化运维框架
作用
- 批量系统配置
- 批量程序部署
- 批量运行命令
框架组成
- Connection Plugins:负责和被监控端实现通信
- Host Inventory:定义监控主机的配置文件
- 模块:
- 核心模块
- command模块
- 自定义模块
- 插件:完成记录日志邮件等功能
- Playbook:剧本,非必需,可让节点一次性运行多个任务
架构图
架构字段解释
- Ansible:核心程序
- Host Inventory:主机清单(可定义主机组和主机)
- 模块:实际执行任务的组件
- Playbook:Yaml定义的剧本文件(类似shell脚本)
- Connect Plugin:连接插件
工作原理
- 控制端通过inventory定义主机组
- 通过编写playbook或AD-HOC命令
- 使用SSH将模块推送到被控端
- 被控端执行任务(要求被控端有Python2环境)
- 任务完成后返回结果
命令执行过程
- 加载配置文件(/etc/ansible/ansible.cfg)
- 查找主机配置文件
- 加载对应模块文件
- 生成临时Python脚本并传输到远程主机
- 存储在远程主机的
~/.ansible/tmp/
目录 - 添加执行权限
- 执行并返回结果
- 删除临时文件
执行流程理解图
特性
- No Agents:无需在被控端安装客户端
- No Server:无服务端架构
- Modules in Any Languages:支持任意语言开发模块
- YAML:使用YAML语言编写playbook
- SSH by Default:默认基于SSH工作
- Multi-tier Solution:支持多级指挥
配置文件
配置文件优先级(从高到低):
- 项目目录下的
ansible.cfg
- 用户家目录下的
.ansible.cfg
- 默认的
/etc/ansible/ansible.cfg
主要配置项
1 | #inventory = /etc/ansible/hosts # 主机列表 |
优点
- 轻量级,客户端无需安装agent
- 批量任务可写成脚本且无需分发
- 基于Python,维护简单
- 支持sudo
环境搭建
主机规划
主机 | IP | 角色 |
---|---|---|
h1 | 192.168.50.60 | master |
h2 | 192.168.50.61 | host1 |
h3 | 192.168.50.62 | host2 |
h4 | 192.168.50.63 | host3 |
SSH免密登录配置
1 | ssh-keygen -t dsa -f ~/.ssh/id_dsa -P "" |
安装
1 | yum install -y ansible |
主机清单配置
1 | [hosts] |
测试
1 | ansible webservers -m command -a 'uptime' |
常用模块
setup模块
查看远程主机基本信息
1 | ansible webservers -m setup |
fetch模块
从主机获取文件
1 | ansible 192.168.50.61 -m fetch -a 'src=/root/t2 dest=/root' |
file模块
设置文件属性
选项:
force
: 强制创建软链接(yes|no)group
: 文件属组mode
: 文件权限owner
: 文件属主path
: 文件路径(必选)recurse
: 递归设置属性(仅目录)src
: 源文件路径(仅state=link时)dest
: 链接目标路径(仅state=link时)state
:directory
: 创建目录file
: 不创建文件link
: 创建软链接hard
: 创建硬链接touch
: 创建空文件或更新修改时间absent
: 删除文件/目录
示例:
1 | # 创建符号链接 |
copy模块
复制文件到远程主机
选项:
backup
: 覆盖前备份(yes|no)content
: 直接设置文件内容(替代src)dest
: 目标绝对路径(必选)directory_mode
: 递归设置目录权限force
: 强制覆盖(yes|no)src
: 本地源文件路径
示例:
1 | ansible hosts -m copy -a "src=/etc/ansible/ansible.cfg dest=/tmp/ansible.cfg owner=root group=root mode=0755" |
command模块
在远程主机执行命令
选项:
creates
: 文件存在时不执行free_form
: Linux命令chdir
: 执行前切换目录removes
: 文件不存在时不执行executable
: 指定shell路径
示例:
1 | ansible webservers -m command -a "ls -al /tmp" |
shell模块
支持管道操作的命令执行
示例:
1 | # 执行远程脚本 |
cron模块
管理计划任务
选项:
minute/hour/day/month/weekday
: 时间设置job
: 任务命令name
: 任务名称user
: 执行用户state
: present(添加)|absent(删除)
示例:
1 | # 创建任务 |
hostname模块
管理主机名
示例:
1 | # 修改主机名 |
yum模块
软件包管理
示例:
1 | # 安装tree |
service模块
服务管理
示例:
1 | # 启动ntpdate服务 |
group模块
用户组管理
示例:
1 | # 添加系统组 |
user模块
用户管理
选项:
name
: 用户名state
: present(新增)|absent(删除)force
: 删除时是否删除家目录system
: 是否系统用户uid
: 指定UIDshell
: 指定shellhome
: 指定家目录
示例:
1 | # 添加系统用户 |
YAML语法
- 数据序列化格式
- 基本结构:例如:
1
2
3
4key: value
- item1
- item2
- item3{name: jerry, age: 21}
Playbook
核心元素
- Tasks: 任务列表
- Variables: 变量
- Templates: 模板文件
- Handlers: 条件触发任务
- Roles: 角色
基础组件
Hosts
: 目标主机remote_user
: 执行用户sudo_user
: sudo用户tasks
: 任务列表
运行Playbook
1 | # 语法检查 |
示例
1. 添加用户和组
1 | - hosts: all |
2. 配置HTTP服务
1 | - hosts: hosts |
更多模块
synchronize
: 使用rsync同步文件raw
: 直接执行命令(类似shell)
模块帮助
# 列出所有模块
ansible-doc -l
# 查看模块帮助
ansible-doc -s MOD_NAME
Ansible 概念
这些概念适用于 Ansible 的所有用途。在使用 Ansible 或阅读文档之前,您应该了解它们。
-
[控制节点]
-
[被管理节点]
-
[清单]
-
[剧本]
-
[剧集]
-
[角色]
-
[任务]
-
[处理器]
-
-
-
[模块]
-
[插件]
-
[集合]
[控制节点]
运行 Ansible CLI 工具(ansible-playbook
、ansible
、ansible-vault
等)的机器。您可以使用任何满足软件要求的计算机作为控制节点——笔记本电脑、共享桌面和服务器都可以运行 Ansible。您也可以在称为执行环境的容器中运行 Ansible。
可以使用多个控制节点,但 Ansible 本身并不协调它们之间的工作,有关此类功能,请参见AAP
。
[被管理节点]
也称为“主机”,这些是您旨在用 Ansible 管理的目标设备(服务器、网络设备或任何计算机)。
除非您使用ansible-pull
,否则通常不会在被管理节点上安装 Ansible,但这很少见,也不是推荐的设置。
[清单]
由一个或多个“清单源”提供的被管理节点列表。您的清单可以指定每个节点的特定信息,例如 IP 地址。它还用于分配组,这既允许在剧集中选择节点,也允许批量分配变量。
要了解有关清单的更多信息,请参阅使用清单部分。有时,清单源文件也称为“主机文件”。
[剧本]
它们包含剧集(这是 Ansible 执行的基本单元)。这既是“执行概念”,也是我们用来描述ansible-playbook
操作的文件的方式。
剧本是用 YAML 编写的,易于阅读、编写、共享和理解。要了解有关剧本的更多信息,请参阅Ansible 剧本。
[剧集]
Ansible 执行的主要上下文,此剧本对象将被管理节点(主机)映射到任务。剧集包含变量、角色和已排序的任务列表,并且可以重复运行。它基本上由对映射的主机和任务的隐式循环组成,并定义如何迭代它们。
[角色]
可在剧集内部使用的可重用 Ansible 内容(任务、处理器、变量、插件、模板和文件)的有限分发。
要使用任何角色资源,必须将角色本身导入剧集。
[任务]
应用于被管理主机的“操作”的定义。您可以使用ansible
或ansible-console
(两者都会创建一个虚拟剧集)一次执行单个任务。
[处理器]
任务的一种特殊形式,仅在之前的任务发出通知并且导致“已更改”状态时才执行。
[模块]
Ansible 复制到并在每个被管理节点上执行(如有需要)的代码或二进制文件,以完成每个任务中定义的操作。
每个模块都有其特定的用途,从管理特定类型数据库上的用户到管理特定类型网络设备上的 VLAN 接口。
您可以使用任务调用单个模块,也可以在剧本中调用多个不同的模块。Ansible 模块分组在集合中。要了解 Ansible 包含多少集合,请参阅集合索引。
[插件]
扩展 Ansible 核心功能的代码片段。插件可以控制您如何连接到被管理节点(连接插件)、操作数据(过滤器插件),甚至控制在控制台中显示的内容(回调插件)。
有关详细信息,请参阅使用插件。
[集合]
Ansible 内容的分发格式,可以包含剧本、角色、模块和插件。您可以通过Ansible Galaxy安装和使用集合。
要了解有关集合的更多信息,请参阅使用 Ansible 集合。
集合资源可以彼此独立且离散地使用。
Ansible 简介
Ansible 提供开源自动化,可降低复杂性并在任何地方运行。使用 Ansible 可以自动执行几乎任何任务。以下是 Ansible 的一些常见用例
-
消除重复并简化工作流程
-
管理和维护系统配置
-
持续部署复杂的软件
-
执行零停机滚动更新
Ansible 使用简单的、人类可读的脚本(称为剧本)来自动化您的任务。您在剧本中声明本地或远程系统的期望状态。Ansible 确保系统保持在该状态。
作为自动化技术,Ansible 围绕以下原则设计
无代理架构
通过避免在 IT 基础设施上安装额外软件来降低维护开销。
简单性
自动化剧本使用简单的 YAML 语法,代码就像文档一样易于阅读。Ansible 也是分散式的,使用 SSH 和现有的操作系统凭据来访问远程机器。
可扩展性和灵活性
通过模块化设计轻松快速地扩展您自动化的系统,该设计支持各种操作系统、云平台和网络设备。
幂等性和可预测性
当系统处于您的剧本描述的状态时,即使多次运行剧本,Ansible 也不会更改任何内容。
使用 Ansible 开始自动化
通过创建自动化项目、构建清单和创建“Hello World”剧本开始使用 Ansible。
-
安装 Ansible。
1
pip install ansible
-
在您的文件系统上创建一个项目文件夹。
1
mkdir ansible_quickstart && cd ansible_quickstart
使用单一目录结构可以更轻松地添加到源代码管理,以及重用和共享自动化内容。
构建清单
清单将受管节点组织在集中式文件中,这些文件为 Ansible 提供系统信息和网络位置。使用清单文件,Ansible 可以使用单个命令管理大量主机。
要完成以下步骤,您需要至少一个主机系统的 IP 地址或完全限定域名 (FQDN)。出于演示目的,主机可以在容器或虚拟机中本地运行。您还必须确保您的公共 SSH 密钥已添加到每个主机上的 authorized_keys
文件中。
继续 Ansible 入门并按如下步骤构建清单
-
在您在 上一步中创建的
ansible_quickstart
目录中创建一个名为inventory.ini
的文件。 -
向
inventory.ini
文件添加一个新的[myhosts]
组,并指定每个主机系统的 IP 地址或完全限定域名 (FQDN)。1
2
3
4[myhosts]
192.0.2.50
192.0.2.51
192.0.2.52 -
验证您的清单。
1
ansible-inventory -i inventory.ini --list
-
Ping 清单中的
myhosts
组。1
ansible myhosts -m ping -i inventory.ini
注意
如果控制节点和受管节点上的用户名不同,请使用
ansible
命令传递-u
选项。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21192.0.2.50 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
192.0.2.51 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
192.0.2.52 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
INI 或 YAML 格式的清单
您可以使用 INI
文件或 YAML
创建清单。在大多数情况下,例如上一步中的示例,对于少量受管节点,INI
文件简单易读。
随着受管节点数量的增加,使用 YAML
格式创建清单变得更合理。例如,以下是 inventory.ini
的等效项,它声明受管节点的唯一名称并使用 ansible_host
字段
1 | myhosts: |
构建清单的技巧
-
确保组名有意义且唯一。组名也区分大小写。
-
避免在组名中使用空格、连字符和前导数字(使用
floor_19
,而不是19th_floor
)。 -
根据主机的**什么**、**哪里**和**何时**逻辑地将主机分组到您的清单中。
什么
根据拓扑结构对主机分组,例如:db、web、leaf、spine。
哪里
按地理位置对主机分组,例如:数据中心、区域、楼层、建筑物。
何时
按阶段对主机分组,例如:开发、测试、过渡、生产。
使用元组
使用以下语法创建一个元组来组织清单中的多个组
以下清单说明了数据中心的结构基础。此示例清单包含一个 network
元组,其中包括所有网络设备,以及一个 datacenter
元组,其中包括 network
组和所有 Web 服务器。
1 | leafs: |
创建变量
变量设置受管节点的值,例如 IP 地址、FQDN、操作系统和 SSH 用户,因此您无需在运行 Ansible 命令时传递它们。
变量可以应用于特定主机。
1 | webservers: |
变量也可以应用于组中的所有主机。
1 | webservers: |
创建剧本
剧本是 Ansible 用于部署和配置受管节点的自动化蓝图,采用 YAML
格式。
剧本
一系列定义 Ansible 执行操作顺序的剧目,自上而下,以实现总体目标。
剧目
一个有序的任务列表,映射到清单中的受管节点。
任务
对单个模块的引用,定义 Ansible 执行的操作。
模块
Ansible 在受管节点上运行的代码或二进制单元。Ansible 模块按集合分组,每个模块都有一个完全限定的集合名称 (FQCN)。
完成以下步骤以创建用于 ping 主机并打印“Hello world”消息的剧本
-
在您之前创建的
ansible_quickstart
目录中创建一个名为playbook.yaml
的文件,内容如下:1
2
3
4
5
6
7
8
9- name: My first play
hosts: myhosts
tasks:
- name: Ping my hosts
ansible.builtin.ping:
- name: Print message
ansible.builtin.debug:
msg: Hello world -
运行您的剧本。
1
ansible-playbook -i inventory.ini playbook.yaml
Ansible 返回以下输出
1 | PLAY [My first play] **************************************************************************** |
在此输出中,您可以看到
-
您为剧目和每个任务指定的名称。您应始终使用易于验证和排查剧本问题的描述性名称。
-
“收集事实”任务隐式运行。默认情况下,Ansible 会收集有关您的清单的信息,以便在剧本中使用。
-
每个任务的状态。每个任务的状态为
ok
,表示它已成功运行。 -
剧目摘要,总结了每个主机上所有任务的结果。在此示例中,共有三个任务,因此
ok=3
表示每个任务都已成功运行。
恭喜,您已开始使用 Ansible!