一、Ansible 概述
1、什么是 Ansible
Ansible 是基于 Python 开发,集合了众多优秀运维工具的优点,实现了批量运行命令、部署程序、配置系统等功能的自动化运维管理工具。默认通过 SSH 协议进行远程命令执行或下发配置,无需部署任何客户端代理软件,从而使得自动化环境部署 变得更加简单。可同时支持多台主机并行管理,使得管理主机更加便捷。
2、Ansible 的架构组成
Ansible 可以看作是一种基于模块进行工作的框架结构, 批量部署能力就是由 Ansible 所运行的模块实现的。简而言之 Ansible 是基于 “模块” 完成各种 “任务” 的。
其基本框架结构如下图 所示。
组件名称 英文 功能描述 核心引擎 Ansible core 即 Ansible 本身 主机清单 Host Inventory 用来定义 Ansible 所管理主机,默认在 Ansible 的 hosts 配置文件中定义被管理主机,也支持自定义动态主机清单和指定其它配置文件位置 连接插件 Connect plugin 负责和被管理主机实现通信,除支持 SSH 连接外,还支持其它连接方式,需用连接插件将主机连接到 Ansible 剧本 Playbook(yaml,jinjia2) 用来集中定义 Ansible 任务的配置文件,可将多个任务定义在一个剧本中,由 Ansible 自动执行,控制主机可针对多台被管理主机同时运行多个任务 核心模块 Core modules 是 Ansible 自带的模块,使用这些模块将资源分发到被管理主机使其执行特定任务或匹配特定状态 自定义模块 Custom modules 用于完成模块功能的补充,可借助相关插件完成记录日志、发送邮件等功能 3、Ansible 与 SaltStack 的对比
(1) Ansible 安装部署简单
默认情况下,SaltStack 需要安装客户端接收服务器发送过来的命令。Ansible 不需要在被控服务器上部署任何的客户端,直接使用 ssh 通道进行远程命令的执行或者下发配置。
(2) SaltStack 响应速度快
默认情况下,Ansible 使用 的是标准的 SSH 协议,而 SaltStack 使用 ZeroMQ 进行通信和传输。因此,仅仅从响应速度来讲,SaltStack 比 Ansible 快很多,甚至快十几倍。在一般运维场景下,Ansible 的响应速度完全可以满足需求。
(3) Ansible 更安全
Ansible 使用标准的 SSH 连接传输数据,不需要在远程主机上启动守护进程。此外,标准的 SSH 数据传输本身就是加密传输,远程主机不易被攻击。
(4) 对 Windows 的支持
SaltStack 对 Windows 的支持比较友好,Ansible 从 1.7 版本开始加入了对 Windows 的支持。由于 Windows 默认没有 SSH,而 Ansible 有依赖 SSH 进行通信,所以在 Windows 下 Ansible 需要依赖 PowerShell 来实现远程管理。Ansible 必须使用 Linux 系统运行控制端。
(5) Ansible 自身运维比较简单
SaltStack 需要在 Master 和 Minion 主机启动一个守护进程,自身需要检测守护进程的运行状态,增加了运维成本。Ansible 和服务器之间用 SSH 进行通信,服务器上值需要运行 SSH 进程就可以进行运维操作。因此,从工具本身的运维角度来说,Ansible 要比 SaltStack 简单很多。
二、安装部署 Ansible 服务
Ansible 自动化运维环境由控制主机与被管理主机组成。由于 Ansible 是基于 SSH 协议进行通信的,所以控制主机安装 Ansible 软件后不需要重启或运行任何程序,被管理主机也不需要安装和运行任何代理程序。
资源清单
操作系统 主机名 IP 地址 组 角色 openEuler 24.03 ansible-node1 192.168.10.101 管理节点 openEuler 24.03 ansible-node2 192.168.10.102 web 被管理主机 openEuler 24.03 ansible-node3 192.168.10.103 db 被管理主机 1、基础环境布置
(1) 关闭防火墙及内核
systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i '/^SELINUX=/s/enforcing/disabled/' /etc/selinux/config
(2) 修改主机名
hostnamectl set-hostname ansible-node1 bash cat <<EOF >> /etc/hosts 192.168.10.101 ansible-node1 192.168.10.102 ansible-node2 192.168.10.103 ansible-node3 EOF hostnamectl set-hostname ansible-node2 bash hostnamectl set-hostname ansible-node3 bash
2、安装ansible
dnf -y install ansible
3、编辑配置文件
cd /etc/ansible/ vim hosts ###编辑内容 [web] 192.168.10.102 ansible_ssh_user=root ansible_ssh_pass=aptech1! ansible_ssh_port=22 [db] 192.168.10.103 ansible_ssh_user=root ansible_ssh_pass=aptech1! ansible_ssh_port=22
4、优化(账密模式下)
vim ansible.cfg
5、测试联通
ansible all -m ping
三、Ansible命令应用基础
模块名称 核心功能 常用参数 典型示例 特殊说明 command 在远程主机执行单条命令(非 shell 环境) chdir
:执行前切换目录
creates
:若文件存在则不执行
removes
:若文件不存在则不执行- name: 查看内存使用<br> command: free -m
不支持管道 、重定向
>等 shell 语法;不执行.profile 等环境配置;返回码非 0 会报错shell 通过 /bin/sh
执行命令(支持 shell 特性)chdir
:执行前切换目录
stdin
:向命令传入标准输入
executable
:指定 shell(如/bin/bash
)- name: 统计nginx进程数<br> shell: ps -ef | grep nginx | wc -l
支持变量扩展和通配符;安全性需注意(避免注入风险);可执行脚本文件 user 管理系统用户(创建 / 修改 / 删除) name
:用户名(必选)
state
:状态(present
/absent
)
uid
:用户 ID
group
:主组
groups
:附加组
home
:家目录
shell
:默认 shell- name: 创建dev用户<br> user:<br> name: dev<br> uid: 1001<br> groups: sudo<br> shell: /bin/bash
密码需用 password
参数传入加密值(可通过ansible-vault
加密);支持system: yes
创建系统用户cron 管理 crontab 定时任务 name
:任务名称(唯一标识)
minute/hour/day/month/weekday
:时间规则
job
:执行命令
user
:执行用户
state
:状态(present
/absent
)- name: 每日备份日志<br> cron:<br> name: "backup logs"<br> hour: 3<br> job: "tar -zcf /backup/logs.tar.gz /var/log"
支持 special_time: reboot
(重启时执行);重复任务需保证name
唯一group 管理用户组(创建 / 修改 / 删除) name
:组名(必选)
state
:状态(present
/absent
)
gid
:组 ID
system
:是否为系统组- name: 创建dev组<br> group:<br> name: dev<br> gid: 2001<br> state: present
修改 gid
会影响已有文件的组权限;删除组前需确保无用户以此为主要组copy 本地文件 / 目录复制到远程主机 src
:本地源路径
dest
:远程目标路径(必选)
mode
:权限(如0644
)
owner/group
:所有者
backup
:覆盖前备份(yes
/no
)
content
:直接写入内容(替代src
)- name: 部署配置文件<br> copy:<br> src: ./nginx.conf<br> dest: /etc/nginx/<br> mode: 0644<br> owner: root
目录复制默认递归( recurse: yes
);仅当内容变化时才执行操作(幂等性)file 管理文件 / 目录属性(权限、链接等) path
:目标路径(必选)
state
:类型(file
/directory
/link
/absent
)
mode
:权限
src
:符号链接的源路径(state: link
时)
owner/group
:所有者- name: 创建数据目录<br> file:<br> path: /data<br> state: directory<br> mode: 0755
state: absent
会删除文件 / 目录(递归);符号链接需同时指定src
和path
script 本地脚本上传到远程并执行(以远程用户权限) script
:本地脚本路径(必选)
chdir
:远程执行目录
creates
:若文件存在则不执行- name: 执行初始化脚本<br> script: ./init.sh chdir=/tmp
脚本权限不影响执行;支持所有可执行脚本(bash/python 等,需远程主机有解释器) yum 管理 RPM 系软件包(CentOS/RHEL) name
:包名(*
表示所有包)
state
:状态(present
/latest
/absent
)
update_cache
:更新缓存(yes
/no
)
enablerepo
:启用特定仓库- name: 安装nginx并更新到最新版<br> yum:<br> name: nginx<br> state: latest
state: latest
会升级包;name: '*' state: latest
等同于yum update
service 管理系统服务(启动 / 停止 / 重启) name
:服务名(必选)
state
:状态(started
/stopped
/restarted
/reloaded
)
enabled
:开机自启(yes
/no
)- name: 启动并设置nginx自启<br> service:<br> name: nginx<br> state: started<br> enabled: yes
支持 systemd、upstart 等多种服务管理器; reloaded
用于平滑重载配置setup 收集远程主机 facts 信息(系统变量) filter
:过滤 facts(如ansible_*_mb
)
gather_subset
:指定收集子集(如!all,!min,network
)- name: 收集内存相关信息<br> setup:<br> filter: "ansible_memtotal_mb"
facts 可通过 {{ ansible_facts['变量名'] }}
引用;默认在 playbook 开始时自动收集1、command模块
ansible all -m command -a 'ls' ###ansible:Ansible 命令行工具,用于触发 Ansible 任务执行 ###all:针对 Ansible Inventory(主机清单)中所有主机执行操作,也可替换为具体主机组 / 主机名 ###-m command:使用 command 模块,该模块用于在远程节点执行简单命令,不涉及 shell 特性(如管道、重定向等复杂语法时常用) ###-a 'ls':-a 用于传递模块参数,这里给 command 模块传的参数是 ls ,即执行列出目录内容的命令
2、shell模块
ansible all -m shell -a 'useradd lisi' ansible all -m shell -a 'echo aaa|passwd --stdin lisi' # 使用ansible在所有主机(all)上执行shell模块 # 创建用户lisi ansible all -m shell -a 'useradd lisi' # 使用ansible在所有主机(all)上执行shell模块 # 为用户lisi设置密码为aaa(通过管道方式非交互设置密码) ansible all -m shell -a 'echo aaa|passwd --stdin lisi'
ansible db -m shell -a 'sed -i "s/^111/222/" /opt/bbb' ansible db -m shell -a 'cat /opt/bbb' # 使用ansible在db组的所有主机上执行shell模块 # 调用sed命令修改/opt/bbb文件:将所有以111开头的行,替换为222开头 # sed -i表示直接修改文件内容,s/^111/222/是替换规则(^表示行首) ansible db -m shell -a 'sed -i "s/^111/222/" /opt/bbb' # 使用ansible在db组的所有主机上执行shell模块 # 查看/opt/bbb文件的内容,验证前面的修改是否生效 ansible db -m shell -a 'cat /opt/bbb'
3、user模块
ansible db -m user -a 'name="wangwu" state=present' ansible db -m user -a 'name="wangwu" state=absent' # 使用ansible在db组的主机上执行user模块 # 创建名为wangwu的用户(state=present表示确保用户存在) ansible db -m user -a 'name="wangwu" state=present' # 使用ansible在db组的主机上执行user模块 # 删除名为wangwu的用户(state=absent表示确保用户不存在) ansible db -m user -a 'name="wangwu" state=absent'
4、cron模块
ansible db -m cron -a 'hour=2 minute=30 weekday=1-5 name="bak mysql" job=/root/mysql_backup.sh state=present' ansible db -m cron -a 'hour=2 minute=30 weekday=1-5 name="bak mysql" job=/root/mysql_backup.sh state=absent' # 使用ansible在db组主机上执行cron模块 # 创建一个定时任务:每周一至周五的凌晨2点30分执行MySQL备份脚本 # hour=2 表示小时为2点,minute=30 表示30分,weekday=1-5 表示周一到周五(1是周一,5是周五) # name="bak mysql" 给定时任务命名(用于标识和后续管理) # job=/root/mysql_backup.sh 指定要执行的脚本路径 # state=present 确保该定时任务存在(不存在则创建,存在则保持配置) ansible db -m cron -a 'hour=2 minute=30 weekday=1-5 name="bak mysql" job=/root/mysql_backup.sh state=present' # 使用ansible在db组主机上执行cron模块 # 删除名为"bak mysql"的定时任务 # 所有参数需与创建时保持一致,以便准确匹配要删除的任务 # state=absent 确保该定时任务不存在(存在则删除,不存在则不操作) ansible db -m cron -a 'hour=2 minute=30 weekday=1-5 name="bak mysql" job=/root/mysql_backup.sh state=absent'
5、group模块
ansible db -m group -a 'name=mysql gid=1500 system=yes' ansible db -m user -a 'name=zhaoliu uid=306 system=yes group=mysql state=present' # 使用ansible在db组主机上执行group模块 # 创建名为mysql的系统组,指定gid为1500 # name=mysql:指定组名称为mysql # gid=1500:指定组ID为1500 # system=yes:标识为系统组(通常用于系统服务相关的用户组) ansible db -m group -a 'name=mysql gid=1500 system=yes' # 使用ansible在db组主机上执行user模块 # 创建名为zhaoliu的系统用户,指定uid为306,并加入mysql组 # name=zhaoliu:指定用户名称为zhaoliu # uid=306:指定用户ID为306 # system=yes:标识为系统用户(通常用于运行系统服务) # group=mysql:指定用户的主组为mysql # state=present:确保用户存在(不存在则创建) ansible db -m user -a 'name=zhaoliu uid=306 system=yes group=mysql state=present'
6、copy模块
ansible db -m copy -a 'src=/root/aaa dest=/opt/bbb owner=zhaoliu mode=600' ansible db -m shell -a 'cat /opt/bbb' # 使用ansible在db组主机上执行copy模块 # 将控制端/root/aaa文件复制到目标主机的/opt/bbb路径 # 并设置文件所有者为zhaoliu,权限为600(所有者可读可写,其他用户无权限) # src=/root/aaa:本地源文件路径 # dest=/opt/bbb:目标主机上的文件路径 # owner=zhaoliu:设置文件所有者为zhaoliu用户 # mode=600:设置文件权限为600(rw-------) ansible db -m copy -a 'src=/root/aaa dest=/opt/bbb owner=zhaoliu mode=600' # 使用ansible在db组主机上执行shell模块 # 查看目标主机上/opt/bbb文件的内容,验证文件是否正确复制 ansible db -m shell -a 'cat /opt/bbb'
7、file模块
(1) 属主属组
ansible db -m file -a 'owner=root group=zhangsan mode=666 path=/opt/bbb' ansible db -m shell -a 'ls -l /opt/bbb' # 使用ansible在db组主机上执行file模块 # 修改/opt/bbb文件的属性:所有者设为root,所属组设为zhangsan,权限设为666 # owner=root:将文件所有者设置为root用户 # group=zhangsan:将文件所属组设置为zhangsan组 # mode=666:设置文件权限为666(所有者、所属组及其他用户均可读写) # path=/opt/bbb:指定要操作的文件路径 ansible db -m file -a 'owner=root group=zhangsan mode=666 path=/opt/bbb' # 使用ansible在db组主机上执行shell模块 # 查看/opt/bbb文件的详细属性(包括所有者、所属组和权限) # 用于验证前面的属性修改是否生效 ansible db -m shell -a 'ls -l /opt/bbb'
(2) 链接
ansible db -m file -a 'src=/opt/bbb path=/opt/ccc state=link' ansible db -m shell -a 'ls -l /opt/' # 使用ansible在db组主机上执行file模块 # 为/opt/bbb文件创建一个符号链接/opt/ccc # src=/opt/bbb:指定源文件路径,即被链接的文件 # path=/opt/ccc:指定符号链接的路径和名称 # state=link:表示创建符号链接(软链接) ansible db -m file -a 'src=/opt/bbb path=/opt/ccc state=link' # 使用ansible在db组主机上执行shell模块 # 查看/opt目录下的文件列表及详细信息 # 用于验证符号链接/opt/ccc是否已正确创建 ansible db -m shell -a 'ls -l /opt/'
8、script模块
vim aaa.sh ###编辑内容### ls -l /opt ###授权### chmod +x aaa.sh
ansible db -m script -a 'aaa.sh' # 使用ansible在db组的主机上执行script模块 # 运行控制端当前目录下的aaa.sh脚本到目标主机上 # script模块会将控制端的本地脚本传输到目标主机,然后在目标主机上执行 # aaa.sh:指定本地要执行的脚本路径(相对路径,相对于当前执行ansible命令的目录) ansible db -m script -a 'aaa.sh'
9、yum模块
ansible db -m yum -a 'name=httpd' ansible db -m yum -a 'name=httpd state=absent' # 使用ansible在db组主机上执行yum模块 # 安装httpd软件包(默认state=present,确保软件包存在) # name=httpd:指定要操作的软件包名称为httpd(Apache网页服务器) ansible db -m yum -a 'name=httpd' # 使用ansible在db组主机上执行yum模块 # 卸载httpd软件包 # name=httpd:指定要卸载的软件包名称 # state=absent:确保软件包不存在(即卸载该软件包) ansible db -m yum -a 'name=httpd state=absent'
10、Service模块
ansible web -m yum -a 'name=httpd' ansible web -m service -a 'enabled=true name=httpd state=started' ansible web -m shell -a 'netstat -anpt | grep httpd' # 使用ansible在web组主机上执行yum模块 # 安装httpd软件包(Apache网页服务器) # name=httpd:指定要安装的软件包名称 # 默认state=present,确保httpd软件包存在(未安装则安装) ansible web -m yum -a 'name=httpd' # 使用ansible在web组主机上执行service模块 # 配置并启动httpd服务 # enabled=true:设置httpd服务开机自启 # name=httpd:指定要操作的服务名称 # state=started:确保httpd服务处于运行状态(未启动则启动) ansible web -m service -a 'enabled=true name=httpd state=started' # 使用ansible在web组主机上执行shell模块 # 检查httpd服务的网络连接状态 # netstat -anpt:查看所有监听端口和关联的进程 # grep httpd:筛选出与httpd相关的网络连接信息 # 用于验证httpd服务是否正常监听端口 ansible web -m shell -a 'netstat -anpt | grep httpd'
11、setup模块
ansible web -m setup # 使用ansible在web组的主机上执行setup模块 # 收集web组所有主机的系统facts(facts是Ansible收集的目标主机详细信息) # 这些信息包括主机名、IP地址、操作系统版本、硬件信息、环境变量等 ansible web -m setup