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 工作原理#

  1. 控制节点读取 Inventory 确定目标主机
  2. 通过 SSH 连接到被管理节点
  3. 将模块代码传输到被管理节点的临时目录
  4. 执行模块并返回结果
  5. 清理临时文件

1.4 常用命令参考#

Terminal window
# 查看 Ansible 版本
ansible --version
# 查看模块帮助
ansible-doc -s yum # 查看 yum 模块支持的参数
ansible-doc -l # 列出所有可用模块
ansible-doc yum # 查看 yum 模块完整文档
# Ansible ping 基于 SSH 协议,与系统 ping 命令原理不同
ansible all -m ping

2. 部署安装#

在控制节点上安装 Ansible:

Terminal window
# 安装 EPEL 源后安装 Ansible
yum install -y epel-release
yum install -y ansible

3. SSH 密钥配置#

3.1 方式一:密码认证(快速测试)#

在不配置 SSH 免密的情况下,可以在 hosts 文件中直接指定用户名和密码:

/etc/ansible/hosts
[webserver]
master
worker
[webserver:vars]
ansible_ssh_user='root'
ansible_ssh_pass='000000'

3.2 方式二:密钥认证(推荐)#

在控制节点生成密钥对并分发到被管理节点:

Terminal window
# 生成密钥对
ssh-keygen -t rsa
# 分发公钥到被管理节点
ssh-copy-id root@master
ssh-copy-id root@worker

配置完成后,Inventory 只需列出主机即可,无需指定密码:

/etc/ansible/hosts
[webserver]
master
worker

3.3 使用自定义密钥文件#

如果密钥文件不在默认路径,可在 Inventory 中指定:

[webserver]
master
worker
[webserver:vars]
ansible_ssh_private_key_file=/root/.ssh/mykey

4. Ansible 基础命令#

Terminal window
# 使用默认主机清单 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 -l

5. Inventory 主机清单#

/etc/ansible/hosts 是 Ansible 的默认主机清单配置文件。

5.1 增加主机组#

[webserver]
master
worker

5.2 增加用户名密码#

[webserver:vars]
ansible_ssh_user='root'
ansible_ssh_pass='000000'

5.3 子分组#

[master]
master
[worker]
worker

5.4 自定义主机列表#

Terminal window
# 使用 -i 参数指定自定义主机清单文件
ansible -i hostlist all -m ping -o

6. Ad-Hoc 点对点模式#

Ad-Hoc 是 Ansible 的临时命令模式,用于快速执行单次任务。

6.1 shell 模块#

Terminal window
# 全部节点执行 shell 命令
ansible all -m shell -a 'yum install -y vsftpd'

6.2 copy 复制模块#

Terminal window
# 复制文件并设置权限
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 用户模块#

Terminal window
# 创建用户
ansible master -m user -a 'name=test state=present'
# 创建用户并设置密码(使用 openssl 生成加密密码)
echo "Admin@123" | openssl passwd -1 -stdin
ansible master -m user -a 'name=New password="$1$kmfEEso4$lBVADkcl/Sqx.0NtAV5iI1"'
# 创建用户并设置 nologin shell
ansible master -m user -a 'name=New shell=/sbin/nologin append=yes'
# 删除用户
ansible master -m user -a 'name=test state=absent'

6.4 yum 软件包管理模块#

Terminal window
# 安装软件包(最新版)
ansible all -m yum -a 'name="httpd" state=latest'
# 卸载软件包
ansible all -m yum -a 'name="httpd" state=absent'

6.5 service 服务模块#

Terminal window
# 启动服务
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 文件模块#

Terminal window
# 创建文件并设置权限
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 收集模块#

Terminal window
# 显示全部节点的系统信息
ansible all -m setup
# 过滤显示 IPv4 地址
ansible all -m setup -a 'filter=ansible_all_ipv4_addresses'

6.8 fetch 拉取模块#

Terminal window
# 从远程节点拉取文件到本地
ansible worker -m fetch -a 'src=/root/hi dest=/root/'

6.9 cron 定时任务模块#

Terminal window
# 配置定时任务(每10分钟同步 NTP 时间)
ansible worker -m cron -a 'name="test" minute="*/10" job="/sbin/ntpdate 172.129.20.22 &> /dev/null"'

6.10 group 用户组模块#

Terminal window
# 创建用户组
ansible all -m group -a 'name=test gid=1010 state=present'
# 删除用户组
ansible all -m group -a 'name=test state=absent'

6.11 script 脚本模块#

Terminal window
# 在远程节点执行本地脚本
ansible all -m script -a "/root/test.sh"

6.12 unarchive 解压模块#

Terminal window
# 在远程节点解压本地压缩文件
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
- Strawberry

7.3 字典#

martin:
name: Martin Developer
job: Developer
skill: Elite

7.4 字符串#

# 普通字符串(无需引号)
name: hello world
# 含特殊字符时需加引号
path: "/usr/local/bin"
msg: "Hello: World"
# 多行字符串(保留换行符)
description: |
第一行
第二行
第三行
# 多行字符串(折叠为单行,空行变换行)
summary: >
这是一段很长的
文本内容

7.5 布尔值#

# 以下都表示 true
enabled: true
enabled: True
enabled: yes
enabled: on
# 以下都表示 false
disabled: false
disabled: False
disabled: no
disabled: off

7.6 空值#

# 以下都表示空
value: null
value: ~
value:

7.7 锚点与引用#

# 定义锚点
defaults: &defaults
timeout: 30
retries: 3
# 引用锚点
development:
<<: *defaults
host: dev.example.com
production:
<<: *defaults
host: prod.example.com

7.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-tools

8. Playbook 剧本#

8.1 基础 Playbook 示例#

编写 YAML 剧本完成 Web 服务的部署、配置、启动:

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
- name: Start httpd
service: name=httpd state=started enabled=yes

8.2 Playbook 常用命令#

Terminal window
# 语法检查
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 8080

8.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=restarted

9. 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 准备目录结构#

Terminal window
mkdir -p roles/vsftpd/{files,handlers,tasks,templates,vars}
touch roles/site.yaml
touch roles/vsftpd/{handlers,tasks,vars}/main.yaml
echo 1234 > roles/vsftpd/files/index.txt
yum install -y vsftpd
cp /etc/vsftpd/vsftpd.conf roles/vsftpd/templates/vsftpd.conf.j2
yum install -y tree
tree roles/

9.3 编写任务 (tasks/main.yaml)#

roles/vsftpd/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=yes

9.4 准备配置文件 (files/index.txt)#

1234

9.5 编写触发器 (handlers/main.yaml)#

roles/vsftpd/handlers/main.yaml
---
- name: restart vsftpd
service: name=vsftpd state=restarted

9.6 编写主剧本 (site.yaml)#

roles/site.yaml
---
- hosts: worker
roles:
- vsftpd

9.7 执行与验证#

Terminal window
# 语法检查
ansible-playbook site.yaml --syntax-check
# 执行剧本
ansible-playbook site.yaml

9.8 Roles 工作流程总结#

  1. roles/ 下创建角色目录,包含 fileshandlerstaskstemplatesvars 五个子目录
  2. roles/ 根目录编写 site.yaml 主剧本
  3. tasks/ 中编写 main.yaml 定义任务流程
  4. templates/ 中编写 .j2 模板文件(Jinja2 格式,支持变量替换)
  5. handlers/ 中编写触发器,配合 notify 使用
  6. vars/ 中定义变量,在 files/ 中放置普通文件
  7. 使用 ansible-playbook site.yaml --syntax-check 检验语法
  8. 使用 ansible-playbook site.yaml 执行部署

10. Ansible 集群部署 OpenStack#

10.1 所需软件包#

  • openstack_ansible_train.tar.gz
  • Ansible.tar.gz
  • CentOS-7-x86_64-DVD-1804.iso
  • chinaskills_cloud_iaas.iso

内存要求:4G

10.2 主机名与网络配置#

Terminal window
# 控制节点
hostnamectl set-hostname controller
# 计算节点
hostnamectl set-hostname compute1
/etc/hosts
172.129.20.22 controller
172.129.20.33 compute1

10.3 配置免密登录#

Terminal window
ssh-keygen
ssh-copy-id controller
ssh-copy-id compute1

10.4 配置 YUM 仓库(Controller 节点)#

Terminal window
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.rpm
echo "anon_root=/opt/" > /etc/vsftpd/vsftpd.conf
systemctl start vsftpd && systemctl enable vsftpd
tar zxvf ansible.tar.gz -C /opt/
/etc/yum.repos.d/local.repo
[centos]
name=centos
baseurl=ftp://c7ck/centos
enabled=1
gpgcheck=0
[iaas]
name=iaas
baseurl=ftp://c7ck/iaas/iaas-repo
enabled=1
gpgcheck=0
[ansible]
name=ansible
baseurl=ftp://c7ck/ansible
enabled=1
gpgcheck=0
Terminal window
yum clean all && yum makecache

10.5 配置 Ansible#

Terminal window
yum install ansible -y
/etc/ansible/hosts
[controller]
172.129.20.22
[compute]
172.129.20.33
Terminal window
ansible all -m ping

10.6 配置 Ansible 变量#

openstack_ansible/group_vars/all
controller_ip: 172.129.20.22
compute1_ip: 172.129.20.33
controller_name: controller
PASSWD: '000000'
network_segment_IP: 172.129.20.0
Physical_NAME: provider

10.7 编写 Jinja2 模板#

roles/init/templates/openrc.sh.j2
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 执行部署#

roles/init/tasks/main.yaml
---
- 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.sh
Terminal window
cd openstack_ansible_train_1804
ansible-playbook install_openstack.yaml
Ansible 自动化运维学习手册
https://blog.xeu.asia/posts/ansible-guide/
作者
Xeu
发布于
2024-06-18
许可协议
CC BY-NC-SA 4.0