自动化运维 - Ansible
# 简介
一个使用 Python 开发的自动化运维工具
- 批量 SSH
- 无需客户端:基于 SSH 实现
# 安装
只需安装在本机,即管理机
pip install ansible
# 检查
ansible ---version
# 免密登录 (可选)
由于是基于 SSH 实现的群控,因此要么密码登录、要么公钥登录,如果是使用 cloud-init 部署的服务器,在模板中添加控制机的公钥到被控机上即可轻松实现,如果没有这么做,可参考 SSH 密钥对 - ssh-keygen
ssh-copy-id username@your_server_ip
# 主机清单 (inventory, hosts)
- Building an inventory — Ansible Community Documentation (opens new window)
- How to build your inventory — Ansible Community Documentation (opens new window)
ansible 支持 2 个格式的配置: ini
、 yaml
;默认读取的文件为 /etc/ansible/hosts
# ini
创建一个项目目录,用于存放主机清单 (inventory) 配置
mkdir ansible_inventory
cd ansible_inventory
vim inventory.ini
inventory.ini
[myhosts]
# 别名 ansible_host=主机ip ansible_port=ssh端口 ansible_user=用户名 ansible_password=密码
192.0.2.50
192.0.2.51
192.0.2.52
创建 myhosts
组,下面有: 192.0.2.50
、 192.0.2.51
、 192.0.2.52
# 校验配置
ansible-inventory -i inventory.ini --list
# 测试配置连通性
ansible 组名 -m ping -i inventory.ini
# yaml(推荐)
# 定义
等效上面的 ini
myhosts: # 组名
hosts: # 分组下的主机
my_host_01: # 主机别名
ansible_host: 192.0.2.50 # 属性
ansible_port: 5555
my_host_02:
ansible_host: 192.0.2.51
my_host_03:
ansible_host: 192.0.2.52
- Ansible 存在两个隐藏组:
all
:即所有主机ungrouped
:不属于任何组的主机,主用用于 ini 文件中,在 yaml 文件中需要放在ungrouped
属性下,算不上 “隐藏” 了
- 分组规范:可使用
What
、Where
、When
三种方式定义分组- What:什么服务器,如数据库服务器、Web 服务器
- Where:哪里的服务器,如机房 1、机房 2
- When:什么开发阶段的服务器,如开发、生产、测试服务器
# 分组关系
# 父子
Note
将已经定义的 host 加入到另一个分组时,将 host 添加到另一个分组的 hosts
下,而不是 children
。
prod: # 父分组
children:
east: # 子分组
test:
children:
west:
# 共同属性(变量)
atlanta:
hosts:
host1:
host2:
vars: # 组内变量;变量会应用到组内所有主机上
ntp_server: ntp.atlanta.example.com
proxy: proxy.atlanta.example.com
多个分组之间的合并规则参考:How to build your inventory — Ansible Community Documentation (opens new window)
# 基本命令
# ansible
# -m 模块名
# -u <username>
# -k 回车后,输入密码连接
# -i inventory配置文件路径;不填默认读取/etc/ansible/hosts(hosts是文件)
# --become --ask-become-pass:需要提取操作时使用
# 测试配置连通性
ansible 组名|别名 -m ping -i inventory.ini
# 主机选择语法
# 常用命令
# 查看主机逻辑线程总数
ansible all -m shell -a "lscpu | grep '^CPU(s):' | awk '{print $2}'"
# 查看内存
ansible all -m command -a "free -g"
# 模块与场景
# 文件分发 - copy
# 添加backup=yes:备份目标主机原文件为`原文件+时间`
ansible 组名 -m copy -a 'src=本机文件路径 dest=目标主机路径 owner=文件所有者 group=组 mode=权限(777)'
# ansible 组名 -m copy -a 'src=/tmp/aaa.txt dest=/tmp/bbb.txt'
# 文件收集 - fetch
# flat=yes:不添加的话,会在本地文件路径下创建完整的目标主机路径
ansible 别名 -m fetch -a "src=目标主机路径 dest=本机文件路径"
# ansible host4 -m fetch -a "src=/tmp/file23.txt dest=/root/"
# 定时任务 - cron
ansible 组名 -m cron -a 'name="sync time from ntpserver" minute="*/10" job="/sbin/ntpdate 192.168.174.129 &> /dev/null"'
# 执行脚本 - script
ansible 组名 -m script -a "本机脚本路径"
# ansible 组名 -m script -a "/root/haha.sh"
# 解压到目标主机 - unarchive
ansible 组名 -m unarchive -a 'src=/root/111.tar dest=/home'
# 执行命令 - shell
ansible 组名 -m shell -a '命令'
# ansible 组名 -m shell -a 'hostname'
# 剧本 (playbook)
# 定义
- yaml 格式文件
playbook.yaml
- name: My first play # 名称
hosts: myhosts # 受影响的主机别名or组名
tasks:
- name: Ping my hosts # 步骤(任务)名称
ansible.builtin.ping: # 调用ping模块
- name: Print message
ansible.builtin.debug:
msg: Hello world
# 执行
ansible-playbook -i inventory.ini playbook.yaml
# 配置 (ansible.cfg)
/etc/ansible/ansible.cfg
[defaults]
host_key_checking = false
# 参考
上次更新: 2025/09/23, 22:16:43