官网
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 |
apt install -y ansible
mkdir ansible_test
cd ansible_test/
ssh-keygen
ssh-copy-id [email protected]
建立库存(Inventory)将被管节点的IP信息等存储在文件中,让控制节点便于管理
vim inventory.ini
root@ansible:~/ansible_test# cat inventory.ini
[myhosts]
192.168.200.100
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 从上到下执行操作的顺序的一系列操作,以实现总体目标
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
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 读取/etc/ansible/hosts作为默认库存文件,但在本实验环境中没有这个默认文件。库存文件最常见的格式是 INI 和 YAML
该文件为ini格式,是全局模式生效。上述入门实验中inventory.ini是局部生效,需要通过-i参数指定。
vim /etc/ansible/hosts
[组名1]
ip1
ip2
[组名2]
ip3
ip4
组名1:
hosts:
ip1:
ip2:
组名2:
hosts:
ip3:
ip4:
即使没有在 inventory 文件中定义任何组,Ansible 也会创建两个默认组:all和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:
如果有许多具有相似模式的主机,例如主机实例的IP地址是连续的,则可以将它们添加为一个范围,而不是单独列出每个主机名:
[webservers]
www[01:50].example.com
# ...
webservers:
hosts:
www[01:50].example.com:
[webservers]
www[01:50:2].example.com
# ...
webservers:
hosts:
www[01:50:2].example.com:
上面的例子会使子域 www01、www03、www05、…、www49 匹配,但不匹配 www00、www02、www50 等,因为步幅(增量)每一步是 2 个单位。
基础语法
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 | 简洁输出 |
常用命令
ansible all -m ping -i inventory.ini
ansible webservers -m shell -a "uptime" -u root -i inventory.ini
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
用于执行 YAML 格式的 Playbook,可实现更复杂的任务自动化。
基本语法
ansible-playbook <playbook.yml> -i <inventory> [选项]
选项 | 说明 |
---|---|
-i | 指定库存文件 |
-l | 限定作用的主机(如 webservers) |
-t | 只运行带有指定标签的任务 |
–syntax-check | 仅检查 Playbook 语法 |
–check | 进行试运行,但不实际执行 |
-e | “变量=值” 传递额外变量 |
–step | 逐步执行每个任务 |
-vvv | 增加调试信息 |
常用命令
ansible-playbook site.yml -i inventory.ini
ansible-playbook site.yml -i inventory.ini -l web
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"
用于管理和查看库存(inventory)。
基本语法
ansible-inventory -i <inventory> [选项]
选项 | 说明 |
---|---|
–list | 以 JSON 格式显示所有主机 |
–graph | 以树状结构显示库存 |
–host | 显示特定主机信息 |
–yaml | 以 YAML 格式输出 |
–vars | 显示变量信息 |
常用命令
ansible-inventory -i inventory.ini --list
ansible-inventory -i inventory.ini --list --yaml
ansible-inventory -i inventory.ini --graph
ansible-inventory -i inventory.ini --host web01
用于加密/解密敏感数据(如密码、密钥)。
基本语法
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
ansible-playbook secure-playbook.yml --ask-vault-pass
用于管理 Ansible 角色(Roles)
ansible-galaxy <subcommand> [选项]
常用命令
ansible-galaxy init my_role
ansible-galaxy install geerlingguy.nginx
ansible-galaxy remove geerlingguy.nginx
ansible-galaxy list
官网
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 模块(Modules)是 执行任务的核心组件,它们用于管理服务器、网络设备、云资源等。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 all -m shell -a "echo hello | tee /tmp/test.txt"
---
- 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