Ansible服务介绍
Ansible
- 入门案例
- 构建ansible库存
- 默认库存文件
- 默认组
- 分组群组
- 主机范围
- Ansible命令行工具
- ansible命令
- ansible-playbook 命令
- ansible-inventory 命令
- ansible-vault 命令
- ansible-galaxy 命令
- Ansible剧本
- Ansible模块
官网
Ansible 是一款由python开发的开源自动化工具,专注于 配置管理、应用部署、任务编排 和 持续交付。它通过简单的 YAML 语法定义自动化流程,无需在被管理节点安装额外客户端,仅依赖 SSH 和 Python 即可运行。
核心特性
-
无代理架构
通过 SSH(Linux)或 WinRM(Windows)协议直接管理目标主机,无需在被控端安装代理程序。 -
幂等性
任务可重复执行,确保系统最终状态一致,避免重复操作引发错误。 -
声明式语法
使用 YAML 编写 Playbook,描述“期望的系统状态”,而非具体操作步骤。 -
模块化设计
提供丰富的内置模块(如 copy、yum、service),支持自定义扩展。
核心组件
组件 | 说明 |
---|---|
Inventory | 定义被管理的主机列表,支持分组(如 webservers、dbservers)。 |
Playbook | YAML 格式的任务蓝图,描述从配置到部署的完整流程。 |
Module | 执行具体任务的单元(如安装软件、操作文件),Ansible 内置 3000+ 模块。 |
Role | 可复用的任务集合,用于组织复杂 Playbook(如 nginx 角色部署 Web 服务器)。 |
Plugin | 扩展 Ansible 功能(如日志记录、连接类型、变量处理)。 |
工作原理
-
控制节点与被管节点
控制节点:安装 Ansible 的主机,负责发起任务。
被管节点:通过 Inventory 定义的目标机器,需支持 SSH 和 Python。 -
任务执行流程
步骤 1:用户编写 Playbook 或 Ad-Hoc 命令(临时任务)。
步骤 2:Ansible 解析 Inventory,确定目标主机。
步骤 3:通过 SSH 连接到目标主机,将模块代码推送至临时目录。
步骤 4:执行模块任务,返回 JSON 格式结果。
步骤 5:清理临时文件,汇总执行状态(成功/失败)。
入门案例
官网
系统环境:Ubuntu2404
节点 | IP |
---|---|
控制节点 | 192.168.200.160 |
被管节点 | 192.168.200.100 |
- 安装ansible
apt install -y ansible
- 创建测试目录
mkdir ansible_test
cd ansible_test/
- 节点免密:将控制节点的公钥添加到被管节点
ssh-keygen
ssh-copy-id root@192.168.200.100
建立库存(Inventory)将被管节点的IP信息等存储在文件中,让控制节点便于管理
vim inventory.ini
- 将被管节点的IP信息添加,节点名称为myhosts(自定义)
root@ansible:~/ansible_test# cat inventory.ini
[myhosts]
192.168.200.100
- 验证测试(列出节点列表和是否ping通)
root@ansible:~/ansible_test# ansible-inventory -i inventory.ini --list
{
"_meta": {
"hostvars": {}
},
"all": {
"children": [
"ungrouped",
"myhosts"
]
},
"myhosts": {
"hosts": [
"192.168.200.100"
]
}
}
root@ansible:~/ansible_test# ansible myhosts -m ping -i inventory.ini
192.168.200.100 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
创建剧本:定义 Ansible 从上到下执行操作的顺序的一系列操作,以实现总体目标
- 本剧本执行两个操作
- 使用ansible.builtin.ping模块来检查与目标主机的连接状态。这个模块不会发送ICMP请求,而是通过Ansible的内部机制来验证主机是否可达
- 使用ansible.builtin.debug模块来输出一条消息
root@ansible:~/ansible_test# vim playbook.yaml
root@ansible:~/ansible_test# cat playbook.yaml
- name: My first play
hosts: myhosts
tasks:
- name: Ping my hosts
ansible.builtin.ping:
- name: Print message
ansible.builtin.debug:
msg: Hello world
- 执行剧本:failed=0即为成功
root@ansible:~/ansible_test# ansible-playbook -i inventory.ini playbook.yaml
PLAY [My first play] ***************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [192.168.200.100]
TASK [Ping my hosts] ***************************************************************************************************
ok: [192.168.200.100]
TASK [Print message] ***************************************************************************************************
ok: [192.168.200.100] => {
"msg": "Hello world"
}
PLAY RECAP *************************************************************************************************************
192.168.200.100 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
构建ansible库存
官网
Ansible 需要知道有哪些主机供给管理,并且需要知道如何连接到这些主机。库存文件就是存放这些信息的位置。默认情况下,Ansible 读取/etc/ansible/hosts作为默认库存文件,但在本实验环境中没有这个默认文件。库存文件最常见的格式是 INI 和 YAML
默认库存文件
该文件为ini格式,是全局模式生效。上述入门实验中inventory.ini是局部生效,需要通过-i参数指定。
vim /etc/ansible/hosts
- 主机的信息可以如下所示进行添加,括号中的标题是组名,用于对主机进行分类,组名下面可以包含多个IP或域名
[组名1]
ip1
ip2
[组名2]
ip3
ip4
- 而使用yaml格式的库存文件格式对应如下:
组名1:
hosts:
ip1:
ip2:
组名2:
hosts:
ip3:
ip4:
默认组
即使没有在 inventory 文件中定义任何组,Ansible 也会创建两个默认组:all和ungrouped。
- all 是 所有主机的父组,即库存文件中的所有主机都会自动属于 all 组,包含所有范围。
all 组不需要显式定义,始终存在 - ungrouped 组包含所有未被分配到任何用户定义组的主机。
任何没有明确组的主机都会自动归入ungrouped组。
192.168.1.100 #因为没有定义组,所以他归为ungrouped 组
[webservers] #为all组的范围内
192.168.1.10
192.168.1.11
分组群组
父/子群组关系:在 Ansible 的 库存(Inventory) 中,分组群组(Group of Groups) 允许将多个组组织到更高级别的结构中,形成 父/子群组关系。这使得管理大量主机更加灵活和高效。例如通过编辑子组来从父组中添加或删除主机。
-
父组(Parent Group):一个包含多个子组的组,可以对整个父组应用任务、变量等。
-
子组(Child Group):属于某个父组的组,仍然可以独立定义和管理主机。
- 继承关系:
父组不会自动继承子组的变量(变量需要显式定义)。
父组包含的所有子组中的主机,但子组之间彼此独立。
- 继承关系:
在 INI 格式的库存文件中,可以使用 [group:children] 来定义父/子关系
# 定义子组
[webservers]
192.168.1.10
192.168.1.11
[dbservers]
192.168.1.20
192.168.1.21
# 定义父组,包含 webservers 和 dbservers
[all_servers:children]
webservers
dbservers
#webservers 组包含 192.168.1.10 和 192.168.1.11。
#dbservers 组包含 192.168.1.20 和 192.168.1.21。
#all_servers 是 webservers 和 dbservers 的 父组,它自身不包含主机,但包含这两个子组的所有主机。
在 YAML 格式中可以使用 [children:] 定义父/子群组
webservers:
hosts:
192.168.1.10:
192.168.1.11:
dbservers:
hosts:
192.168.1.20:
192.168.1.21:
all_servers:
children:
webservers:
hosts:
- 子组有几个属性需要注意:
任何属于子组成员的主机都会自动成为父组的成员。
群组可以有多个父群组和子群组,但不能有循环关系。
主机也可以属于多个组,但在运行时,每个主机只有一个实例。Ansible 会合并来自多个组的数据
主机范围
如果有许多具有相似模式的主机,例如主机实例的IP地址是连续的,则可以将它们添加为一个范围,而不是单独列出每个主机名:
- 在 INI 中:
[webservers]
www[01:50].example.com
- 在 YAML 中:
# ...
webservers:
hosts:
www[01:50].example.com:
- 定义主机的数字范围时,您可以指定步幅(序列号之间的增量):
在 INI 中:
[webservers]
www[01:50:2].example.com
- 在 YAML 中:
# ...
webservers:
hosts:
www[01:50:2].example.com:
上面的例子会使子域 www01、www03、www05、…、www49 匹配,但不匹配 www00、www02、www50 等,因为步幅(增量)每一步是 2 个单位。
Ansible命令行工具
ansible命令
基础语法
ansible <主机组或all> -m <模块名> -a "<参数>" -i <库存文件> [选项]
- 常见参数
参数 | 说明 |
---|---|
-i | 指定库存文件(ini 或 yaml) |
-m | 指定 Ansible 模块(如 ping、shell、copy) |
-a “” | 传递给模块的参数 |
-u | 指定远程执行的用户 |
-k | 提示输入 SSH 密码(如果不使用密钥认证) |
-K | 提示输入 sudo 密码 |
-b | 使用 sudo(即 become)执行 |
–list-hosts | 列出匹配的主机但不执行 |
-o | 简洁输出 |
常用命令
- 测试所有主机是否可达(使用 ping 模块)
ansible all -m ping -i inventory.ini
- 以 root 用户在webservers 主机上执行命令
ansible webservers -m shell -a "uptime" -u root -i inventory.ini
- 以普通用户执行,但使用 sudo 提权
ansible webservers -m shell -a "whoami" -b -i inventory.ini
- 复制文件到远程服务器
ansible webservers -m copy -a "src=/etc/hosts dest=/tmp/hosts" -b
- 仅列出符合条件的主机
ansible webservers --list-hosts
ansible-playbook 命令
用于执行 YAML 格式的 Playbook,可实现更复杂的任务自动化。
基本语法
ansible-playbook <playbook.yml> -i <inventory> [选项]
- 常见参数
选项 | 说明 |
---|---|
-i | 指定库存文件 |
-l | 限定作用的主机(如 webservers) |
-t | 只运行带有指定标签的任务 |
–syntax-check | 仅检查 Playbook 语法 |
–check | 进行试运行,但不实际执行 |
-e | “变量=值” 传递额外变量 |
–step | 逐步执行每个任务 |
-vvv | 增加调试信息 |
常用命令
- 运行 playbook
ansible-playbook site.yml -i inventory.ini
- 仅作用于 web 组
ansible-playbook site.yml -i inventory.ini -l web
- 只运行有 “install” 标签的任务
ansible-playbook site.yml -t install
- 进行语法检查
ansible-playbook site.yml --syntax-check
- 试运行,不修改系统
ansible-playbook site.yml --check
- 传递额外变量
ansible-playbook deploy.yml -e "version=2.1.0"
ansible-inventory 命令
用于管理和查看库存(inventory)。
基本语法
ansible-inventory -i <inventory> [选项]
- 常见参数
选项 | 说明 |
---|---|
–list | 以 JSON 格式显示所有主机 |
–graph | 以树状结构显示库存 |
–host | 显示特定主机信息 |
–yaml | 以 YAML 格式输出 |
–vars | 显示变量信息 |
常用命令
- 列出所有主机
ansible-inventory -i inventory.ini --list
- 以 YAML 格式输出
ansible-inventory -i inventory.ini --list --yaml
- 显示树状结构
ansible-inventory -i inventory.ini --graph
- 查询单个主机信息
ansible-inventory -i inventory.ini --host web01
ansible-vault 命令
用于加密/解密敏感数据(如密码、密钥)。
基本语法
ansible-vault <subcommand> <file>
常用命令
- 创建加密文件(需输入密码)
ansible-vault create secret.yml
- 编辑加密文件
ansible-vault edit secret.yml
- 查看加密文件内容
ansible-vault view secret.yml
- 加密已存在的文件
ansible-vault encrypt config.yml
- 解密文件
ansible-vault decrypt config.yml
- 运行加密的 playbook(需要输入密码)
ansible-playbook secure-playbook.yml --ask-vault-pass
ansible-galaxy 命令
用于管理 Ansible 角色(Roles)
ansible-galaxy <subcommand> [选项]
常用命令
- 创建一个新的 Role
ansible-galaxy init my_role
- 下载 Role
ansible-galaxy install geerlingguy.nginx
- 删除 Role
ansible-galaxy remove geerlingguy.nginx
- 列出已安装的角色
ansible-galaxy list
Ansible剧本
官网
Ansible Playbooks 提供可重复、可重用、简单的配置管理和多机部署系统,非常适合部署复杂的应用程序,剧本以 YAML 格式表示
(1)Playbook 语法
对于 Ansible,几乎每个 YAML 文件都以列表开头。列表中的每个项目都是一个键/值对列表,通常称为“哈希”或“字典”。因此,我们需要知道如何在 YAML 中编写列表和字典。
YAML 还有另外一个小怪癖。所有 YAML 文件(无论是否与 Ansible 关联)都可以选择以 开头—和以 结尾…。这是 YAML 格式的一部分,表示文档的开始和结束。
列表的所有成员都是以相同缩进级别开始的行,以(破折号和空格)开头:"- "
---
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
...
(2)剧本执行
剧本按从上到下的顺序运行。在每个剧本中,任务也按从上到下的顺序运行。具有多个“剧本”的剧本可以编排多台机器部署,在您的 Web 服务器上运行一个剧本,然后在您的数据库服务器上运行另一个剧本,然后在您的网络基础设施上运行第三个剧本,依此类推。每个剧本至少定义两件事:
- 使用模式定位托管节点
- 至少要执行一项任务
(3)运行剧本
要运行你的剧本,使用ansible-playbook命令。
ansible-playbook playbook.yml -f 10
运行剧本时使用该–verbose标志可以查看成功模块和不成功模块的详细输出。
(4)在检查模式下运行剧本
Ansible 的检查模式允许执行剧本,而无需对系统进行任何更改。可以使用检查模式在生产环境中实施剧本之前对其进行测试。
要在检查模式下运行剧本,可以将-C或–check标志传递给ansible-playbook命令:
ansible-playbook --check playbook.yaml
执行此命令将正常运行剧本,但 Ansible 不会实施任何修改,而只会提供其所做的更改报告。此报告包含文件修改、命令执行和模块调用等详细信息。
检查模式提供了一种安全实用的方法来检查剧本的功能,而不会对系统造成意外更改。此外,它还是一种有用的工具,可用于排除剧本无法按预期运行的故障。
Ansible模块
Ansible 模块(Modules)是 执行任务的核心组件,它们用于管理服务器、网络设备、云资源等。Ansible 具有 数百个模块,可以实现 系统管理、软件安装、文件操作、数据库管理 等自动化任务
- Ansible 模块分类
模块类别 | 作用 |
---|---|
基础模块 | ping、setup、command、shell |
文件管理 | copy、fetch、file、template |
用户和权限 | user、group、authorized_key、sudoers |
软件包管理 | yum、apt、dnf、pip |
服务管理 | systemd、service、cron、supervisorctl |
网络管理 | firewalld、iptables、uri、get_url |
云服务 | aws_s3、azure_rm、gcp_compute |
数据库管理 | mysql_db、postgresql_db、mongodb_user |
版本控制 | git、svn |
容器管理 | docker_container、k8s |
其他工具 | debug、wait_for、fail |
- ansible命令使用模块示例
ansible all -m shell -a "echo hello | tee /tmp/test.txt"
- 剧本yaml文件用法示例
---
- name: Ansible 模块示例
hosts: all # 在所有主机执行
become: yes # 以 sudo 权限执行
tasks:
# 1. 系统管理模块
- name: 测试主机连通性
ping:
- name: 获取系统信息
setup:
- name: 执行 shell 命令
shell: echo "Hello, Ansible!"
# 2. 文件管理模块
- name: 复制文件到远程主机
copy:
src: /etc/hosts
dest: /tmp/hosts
- name: 从远程主机拉取文件
fetch:
src: /var/log/syslog
dest: /tmp/syslog.log
- name: 创建目录
file:
path: /data/logs
state: directory
mode: '0755'
- name: 使用模板生成配置文件
template:
src: templates/config.j2
dest: /etc/myapp/config.conf
# 3. 用户管理模块
- name: 创建用户
user:
name: devuser
state: present
- name: 创建用户组
group:
name: devgroup
state: present
- name: 添加 SSH 公钥
authorized_key:
user: devuser
key: "{{ lookup('file', 'id_rsa.pub') }}"
# 4. 软件包管理模块
- name: 安装软件包 (Ubuntu)
apt:
name: vim
state: present
when: ansible_os_family == "Debian"
- name: 安装软件包 (CentOS)
yum:
name: nano
state: present
when: ansible_os_family == "RedHat"
- name: 安装 Python 包
pip:
name: requests
state: present
# 5. 服务管理模块
- name: 启动并启用 Nginx
service:
name: nginx
state: started
enabled: yes
- name: 配置定时任务
cron:
name: "定时任务示例"
job: "/usr/bin/echo '定时任务执行' >> /var/log/cron.log"
minute: "0"
hour: "3"
# 6. 网络管理模块
- name: 开启防火墙端口
firewalld:
port: 80/tcp
state: enabled
permanent: yes
when: ansible_os_family == "RedHat"
- name: 下载远程文件
get_url:
url: https://example.com/file.tar.gz
dest: /tmp/file.tar.gz
# 7. 数据库管理模块
- name: 创建 MySQL 数据库
mysql_db:
name: exampledb
state: present
- name: 创建 PostgreSQL 数据库
postgresql_db:
name: exampledb
state: present
# 8. 版本控制模块
- name: 克隆 Git 仓库
git:
repo: "https://github.com/example/repository.git"
dest: /var/www/html
# 9. 容器管理模块
- name: 运行 Docker 容器
docker_container:
name: mycontainer
image: nginx
state: started
- name: 部署 Kubernetes 资源
k8s:
state: present
src: my-deployment.yaml