2377 字
12 分钟
Ansible 自动化运维学习手册
1. 简介
Ansible 是一款开源的自动化运维工具,适用于配置管理、应用部署、任务自动化等场景。
1.1 核心特性
- 无代理(Agentless):不需要在被管理节点安装客户端,通过 SSH 协议通信
- 幂等性:多次执行结果一致,已满足条件的操作不会重复执行
- 模块化:通过模块实现各种功能,支持自定义模块
- YAML 编写:Playbook 使用 YAML 语法,易读易写
1.2 架构组成
| 组件 | 说明 |
|---|---|
| 控制节点(Control Node) | 安装 Ansible 的机器,执行命令和 Playbook |
| 被管理节点(Managed Node) | 被 Ansible 管理的目标主机 |
| Inventory(主机清单) | 定义被管理节点的列表和分组 |
| Module(模块) | 执行具体任务的功能单元 |
| Playbook(剧本) | 定义任务执行顺序和逻辑的 YAML 文件 |
1.3 工作原理
- 控制节点读取 Inventory 确定目标主机
- 通过 SSH 连接到被管理节点
- 将模块代码传输到被管理节点的临时目录
- 执行模块并返回结果
- 清理临时文件
1.4 常用命令参考
# 查看 Ansible 版本ansible --version
# 查看模块帮助ansible-doc -s yum # 查看 yum 模块支持的参数ansible-doc -l # 列出所有可用模块ansible-doc yum # 查看 yum 模块完整文档
# Ansible ping 基于 SSH 协议,与系统 ping 命令原理不同ansible all -m ping2. 部署安装
在控制节点上安装 Ansible:
# 安装 EPEL 源后安装 Ansibleyum install -y epel-releaseyum install -y ansible3. SSH 密钥配置
3.1 方式一:密码认证(快速测试)
在不配置 SSH 免密的情况下,可以在 hosts 文件中直接指定用户名和密码:
[webserver]masterworker
[webserver:vars]ansible_ssh_user='root'ansible_ssh_pass='000000'3.2 方式二:密钥认证(推荐)
在控制节点生成密钥对并分发到被管理节点:
# 生成密钥对ssh-keygen -t rsa
# 分发公钥到被管理节点ssh-copy-id root@masterssh-copy-id root@worker配置完成后,Inventory 只需列出主机即可,无需指定密码:
[webserver]masterworker3.3 使用自定义密钥文件
如果密钥文件不在默认路径,可在 Inventory 中指定:
[webserver]masterworker
[webserver:vars]ansible_ssh_private_key_file=/root/.ssh/mykey4. Ansible 基础命令
# 使用默认主机清单 ping 所有主机ansible all -m ping
# 自定义主机清单进行 ping 测试ansible -i hostlist all -m ping -o
# 指定主机组执行命令ansible webservers -m ping
# 指定单台主机执行命令ansible 192.168.1.10 -m ping
# 使用 shell 模块执行命令ansible all -m shell -a 'uptime'
# 使用 command 模块(默认模块,不支持管道和重定向)ansible all -m command -a 'df -h'
# 并行控制(同时连接 10 台主机)ansible all -m ping -f 10
# 使用 sudo 执行ansible all -m shell -a 'cat /etc/shadow' --become --become-user=root
# 列出主机清单中的主机ansible all --list-hosts
# 列出主机清单中的组ansible all --list-hosts -l5. Inventory 主机清单
/etc/ansible/hosts 是 Ansible 的默认主机清单配置文件。
5.1 增加主机组
[webserver]masterworker5.2 增加用户名密码
[webserver:vars]ansible_ssh_user='root'ansible_ssh_pass='000000'5.3 子分组
[master]master
[worker]worker5.4 自定义主机列表
# 使用 -i 参数指定自定义主机清单文件ansible -i hostlist all -m ping -o6. Ad-Hoc 点对点模式
Ad-Hoc 是 Ansible 的临时命令模式,用于快速执行单次任务。
6.1 shell 模块
# 全部节点执行 shell 命令ansible all -m shell -a 'yum install -y vsftpd'6.2 copy 复制模块
# 复制文件并设置权限ansible worker -m copy -a 'src=/etc/hosts dest=/tmp/hosts-new owner=root group=bin mode=777'
# 复制文件并备份原文件ansible worker -m copy -a 'src=/etc/hosts dest=/tmp/hosts-new owner=root group=bin mode=777 backup=yes'6.3 user 用户模块
# 创建用户ansible master -m user -a 'name=test state=present'
# 创建用户并设置密码(使用 openssl 生成加密密码)echo "Admin@123" | openssl passwd -1 -stdinansible master -m user -a 'name=New password="$1$kmfEEso4$lBVADkcl/Sqx.0NtAV5iI1"'
# 创建用户并设置 nologin shellansible master -m user -a 'name=New shell=/sbin/nologin append=yes'
# 删除用户ansible master -m user -a 'name=test state=absent'6.4 yum 软件包管理模块
# 安装软件包(最新版)ansible all -m yum -a 'name="httpd" state=latest'
# 卸载软件包ansible all -m yum -a 'name="httpd" state=absent'6.5 service 服务模块
# 启动服务ansible all -m service -a 'name=httpd state=started'
# 启动服务并设置开机自启ansible all -m service -a 'name=httpd state=started enabled=yes'
# 停止服务ansible all -m service -a 'name=httpd state=stopped'
# 重启服务ansible all -m service -a 'name=httpd state=restarted'
# 启动服务但关闭开机自启ansible all -m service -a 'name=httpd state=started enabled=no'6.6 file 文件模块
# 创建文件并设置权限ansible all -m file -a 'path=/tmp/88.text mode=777 state=touch'
# 创建目录并设置权限ansible all -m file -a 'path=/tmp/99 mode=777 state=directory'
# 删除文件或目录ansible all -m file -a 'path=/tmp/88.text state=absent'6.7 setup 收集模块
# 显示全部节点的系统信息ansible all -m setup
# 过滤显示 IPv4 地址ansible all -m setup -a 'filter=ansible_all_ipv4_addresses'6.8 fetch 拉取模块
# 从远程节点拉取文件到本地ansible worker -m fetch -a 'src=/root/hi dest=/root/'6.9 cron 定时任务模块
# 配置定时任务(每10分钟同步 NTP 时间)ansible worker -m cron -a 'name="test" minute="*/10" job="/sbin/ntpdate 172.129.20.22 &> /dev/null"'6.10 group 用户组模块
# 创建用户组ansible all -m group -a 'name=test gid=1010 state=present'
# 删除用户组ansible all -m group -a 'name=test state=absent'6.11 script 脚本模块
# 在远程节点执行本地脚本ansible all -m script -a "/root/test.sh"6.12 unarchive 解压模块
# 在远程节点解压本地压缩文件ansible all -m unarchive -a 'src=/root/test.tar.gz dest=/home'7. YAML 语法
YAML(YAML Ain’t Markup Language)是 Playbook 的编写语言。
7.1 基本规则
- 大小写敏感
- 使用缩进表示层级关系(推荐 2 个空格)
- 缩进不允许使用 Tab,只允许空格
#表示注释- 开头顶格加冒号,参数空两格、横杠加一个空格
7.2 列表
fruits: - Apple - Orange - Strawberry7.3 字典
martin: name: Martin Developer job: Developer skill: Elite7.4 字符串
# 普通字符串(无需引号)name: hello world
# 含特殊字符时需加引号path: "/usr/local/bin"msg: "Hello: World"
# 多行字符串(保留换行符)description: | 第一行 第二行 第三行
# 多行字符串(折叠为单行,空行变换行)summary: > 这是一段很长的 文本内容7.5 布尔值
# 以下都表示 trueenabled: trueenabled: Trueenabled: yesenabled: on
# 以下都表示 falsedisabled: falsedisabled: Falsedisabled: nodisabled: off7.6 空值
# 以下都表示空value: nullvalue: ~value:7.7 锚点与引用
# 定义锚点defaults: &defaults timeout: 30 retries: 3
# 引用锚点development: <<: *defaults host: dev.example.com
production: <<: *defaults host: prod.example.com7.8 条件与循环(Playbook 中使用)
# 条件判断tasks: - name: Install httpd yum: name=httpd state=present when: ansible_os_family == "RedHat"
# 循环tasks: - name: Install packages yum: name={{ item }} state=present loop: - httpd - vim - net-tools8. Playbook 剧本
8.1 基础 Playbook 示例
编写 YAML 剧本完成 Web 服务的部署、配置、启动:
- hosts: worker tasks: - name: Install Apache yum: name=httpd state=present - name: Copy Apache Conf copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf - name: Start httpd service: name=httpd state=started enabled=yes8.2 Playbook 常用命令
# 语法检查ansible-playbook web.yaml --syntax-check
# 列出任务ansible-playbook web.yaml --list-tasks
# 列出主机ansible-playbook web.yaml --list-hosts
# 执行剧本ansible-playbook web.yaml
# 验证服务端口netstat -ntpl | grep 80808.3 Handlers 触发器
当配置文件发生变化时,通过 notify 通知 handlers 重启服务:
# web.yaml(带触发器)- hosts: worker tasks: - name: Install Apache yum: name=httpd state=present - name: Copy Apache Conf copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf notify: Restart Apache # 通知 handlers 触发器 - name: Start httpd service: name=httpd state=started enabled=yes handlers: - name: Restart Apache service: name=httpd state=restarted9. Roles 角色
Roles 是 Ansible 中 Playbook 的目录组织结构,将代码和文件模块化,具有易读、可重用、层次清晰的优点。
9.1 目录结构
roles/├── vsftpd/ # 角色名(随意命名)│ ├── files/ # 普通文件 / 替换文件│ │ └── index.txt│ ├── handlers/ # 触发器程序│ │ └── main.yaml│ ├── tasks/ # 主任务│ │ └── main.yaml│ ├── templates/ # Jinja2 模板文件(含变量)│ │ └── vsftpd.conf.j2│ └── vars/ # 自定义变量│ └── main.yaml└── site.yaml # 主剧本9.2 准备目录结构
mkdir -p roles/vsftpd/{files,handlers,tasks,templates,vars}touch roles/site.yamltouch roles/vsftpd/{handlers,tasks,vars}/main.yamlecho 1234 > roles/vsftpd/files/index.txtyum install -y vsftpdcp /etc/vsftpd/vsftpd.conf roles/vsftpd/templates/vsftpd.conf.j2yum install -y treetree roles/9.3 编写任务 (tasks/main.yaml)
---- name: Install vsftpd yum: name=vsftpd state=latest- name: copy copy: src=index.txt dest=/opt/- name: copy conf template: src=vsftpd.conf.j2 dest=/etc/vsftpd/vsftpd.conf notify: restart vsftpd- name: make vsftpd service: name=vsftpd state=started enabled=yes9.4 准备配置文件 (files/index.txt)
12349.5 编写触发器 (handlers/main.yaml)
---- name: restart vsftpd service: name=vsftpd state=restarted9.6 编写主剧本 (site.yaml)
---- hosts: worker roles: - vsftpd9.7 执行与验证
# 语法检查ansible-playbook site.yaml --syntax-check
# 执行剧本ansible-playbook site.yaml9.8 Roles 工作流程总结
- 在
roles/下创建角色目录,包含files、handlers、tasks、templates、vars五个子目录 - 在
roles/根目录编写site.yaml主剧本 - 在
tasks/中编写main.yaml定义任务流程 - 在
templates/中编写.j2模板文件(Jinja2 格式,支持变量替换) - 在
handlers/中编写触发器,配合notify使用 - 在
vars/中定义变量,在files/中放置普通文件 - 使用
ansible-playbook site.yaml --syntax-check检验语法 - 使用
ansible-playbook site.yaml执行部署
10. Ansible 集群部署 OpenStack
10.1 所需软件包
openstack_ansible_train.tar.gzAnsible.tar.gzCentOS-7-x86_64-DVD-1804.isochinaskills_cloud_iaas.iso
内存要求:4G
10.2 主机名与网络配置
# 控制节点hostnamectl set-hostname controller
# 计算节点hostnamectl set-hostname compute1172.129.20.22 controller172.129.20.33 compute110.3 配置免密登录
ssh-keygenssh-copy-id controllerssh-copy-id compute110.4 配置 YUM 仓库(Controller 节点)
mv /etc/yum.repos.d/* /media/mkdir -p /opt/{centos,iaas}mount -o loop chinaskills_cloud_iaas.iso /opt/iaas/mount -o loop CentOS-7-x86_64-DVD-1804.iso /opt/centos/rpm -ivp /opt/centos/Packages/vsftpd-3.0.2-22.el7.x86_64.rpmecho "anon_root=/opt/" > /etc/vsftpd/vsftpd.confsystemctl start vsftpd && systemctl enable vsftpdtar zxvf ansible.tar.gz -C /opt/[centos]name=centosbaseurl=ftp://c7ck/centosenabled=1gpgcheck=0
[iaas]name=iaasbaseurl=ftp://c7ck/iaas/iaas-repoenabled=1gpgcheck=0
[ansible]name=ansiblebaseurl=ftp://c7ck/ansibleenabled=1gpgcheck=0yum clean all && yum makecache10.5 配置 Ansible
yum install ansible -y[controller]172.129.20.22[compute]172.129.20.33ansible all -m ping10.6 配置 Ansible 变量
controller_ip: 172.129.20.22compute1_ip: 172.129.20.33controller_name: controllerPASSWD: '000000'network_segment_IP: 172.129.20.0Physical_NAME: provider10.7 编写 Jinja2 模板
HOST_IP_NODE={% if ansible_fqdn == "compute1" %}172.129.20.33{% endif %}HOST_NAME_NODE={% if ansible_fqdn == "compute1" %}compute1{% endif %}INTERFACE_IP={% if ansible_fqdn == "controller" %}172.129.20.22{% elif ansible_fqdn == "compute1" %}172.129.20.33{% endif %}INTERFACE_NAME={{External_Network}}10.8 执行部署
---- name: move repos shell: mv /etc/yum.repos.d/* /media- name: create local.repo copy: src=local.repo dest=/etc/yum.repos.d/- name: install iaas-xiandian yum: name=iaas-xiandian state=present- name: openrc.sh template: src=openrc.sh.j2 dest=/etc/xiandian/openrc.sh- name: install pre-host shell: iaas-pre-host.shcd openstack_ansible_train_1804ansible-playbook install_openstack.yaml Ansible 自动化运维学习手册
https://blog.xeu.asia/posts/ansible-guide/