Ansible学习-基础部分(一)
1. 简介
编写程序实现运维自动化:shell、Python
ansible可以实现:OS config、Task Excute、Depployment
1. OS Provisioning:PXE可以实现DHCP和tftp,cobbler
2. OS config:命令批量执行,保持任务执行的状态:puppet、saltstack
3. Task Excute(命令任务执行的工具,独立出来):fabric,func,saltstack
4. deployment(实现应用程序部署):fabric
基于管理节点和被管理节点,需要考虑安全因素,ansible没有客户端,以SSH服务来操控。
功能
批量执行远程命令,可以对远程的多台主机同时进行命令的执行
批量安装和配置软件服务,可以对远程的多台主机进行自动化的方式配置和管理各种服务
编排高级的企业级复杂的IT架构任务,Ansible的Playbook和role可以轻松实现大型的IT复杂架构
提供自动化运维工具开发API
核心模块:Paramiko,PyYAML,jinjia2
Paramiko: 通过 SSH 连接远程服务器
PyYAML: 在 YAML 配置与 Python 数据之间转换
jinjia2: 将模板与变量组合成最终文本( 批量生成 Nginx 配置、Docker Compose 文件、K8s 清单)
2. Ansible的特性
- minimal learning curve(最小学习曲线) auditability(可以认证的) 基于Python语言来实现
- Modles in any language (支持多模块化,模块支持任意变成语言)
- Paramiko (Python 对 ssh 的实现),PyYAML,jinja2(模块语言) 三个关键模块
- No bootstarpping (无需客户端引导)
- No DAG ordering,Fails Fast (无依赖关系)幂等性,一个任务执行1遍和先执行N遍效果一样,不因重复执行带来意外情况(非绝对,大部分情况)。只关心数据和执行的结果,不关心过程
- No agents(没有代理)类似于Zabbix就有代理
- No server(没有服务器端)
- 安全:基于openssh,No additiional PKI (无需依赖证书)
- yaml,not code (简化的标签格式定义文档文本格式,学习简易)
- strong multi-tier solution (支持多角色)
3.核心组件
- ansible core
- host iventory 主机池
- core modules
- custom modules 自定义模块
- playbook (yaml ,jinjia2) 运行将多个主机的配置的任务写在yaml格式的配置文件中,支持Python的jinjia2 模板语言
- connect plugin (连接每个管理主机的插件)
- API (第三方应用程序调用的程序接口)

4. 安装
可以使用源码包编译安装
社区文档:Ansible 入门 — Ansible 社区文档
安装epel源后,也可以使用dnf进行安装
配置文件路径:/etc/ansible/ansible.cfg
invertory文件(主机池):/etc/ansible/hosts
角色配置区:/etc/ansible/roles
5. 配置文件
主配置文件
因为我使用的是比较新版本的Ansible,配置文件中显示
# Since Ansible 2.12 (core):
# To generate an example config file (a "disabled" one with all default settings, commented out):
使用下面的命令生成生成一个示例配置文件
# $ ansible-config init --disabled > ansible.cfg
#
使用下面的命令,生成一个包含更多现有插件配置项的配置文件
# Also you can now have a more complete file by including existing plugins:
# ansible-config init --disabled -t all > ansible.cfg
# For previous versions of Ansible you can check for examples in the 'stable' branches of each version
# Note that this file was always incomplete and lagging changes to configuration settings
使用的是较早版本的 Ansible,可以到 GitHub 对应版本的 stable 分支中查看配置文件示例
# for example, for 2.9: https://github.com/ansible/ansible/blob/stable-2.9/examples/ansible.cfg
新版本配置文件中,比较核心的参数
[defaults]
# (pathlist) Comma separated list of Ansible inventory sources
;inventory=/etc/ansible/hosts # 指定 Ansible 管理哪些远程主机
# 默认远程登录用户
;remote_user= # 指定 Ansible 连接远程服务器时使用的用户。
# SSH 主机密钥检查
;host_key_checking=True # 控制 SSH 连接时是否检查远程主机的身份密钥。
# 并发执行数量
;forks=5 # 控制 Ansible 同时可以执行多少个任务进程。
# 默认执行模块
;module_name=command # 指定使用 ansible Ad-Hoc 命令时,默认使用哪个模块。shell也可以
# Python 解释器
;interpreter_python=auto
# 日志配置
;log_path= # 指定 Ansible 日志保存位置。
# 插件过滤
# The default is /etc/ansible/plugin_filters.yml
;plugin_filters_cfg=
# 默认智能模式
;transport=smart
| 连接方式 | 说明 |
|---|---|
smart |
根据环境自动选择 SSH 或 Paramiko(旧版 Ansible 的行为) |
ssh |
使用 SSH 连接远程 Linux 主机 |
paramiko |
使用 Python Paramiko 库建立 SSH 连接 |
local |
在 Ansible 控制节点本地执行 |
docker |
连接 Docker 容器 |
winrm |
通过 WinRM 管理 Windows 主机 |
主机清单配置
如果在没有配置主机清单的情况,只能对localhost进行探测,这个ping不是icmp协议。
报错信息为:Ansible 没有读取到有效的 Inventory 主机清单文件

# Ex 1: Ungrouped hosts, specify before any group headers:
# 域名和IP都可以
## green.example.com
## blue.example.com
192.168.155.120
192.168.155.130
# Ex 2: A collection of hosts belonging to the 'webservers' group:
# 分类:定义 Web 服务器组
[webservers]
## alpha.example.org
## beta.example.org
192.168.150.140
## 192.168.1.110
# If you have multiple hosts following a pattern, you can specify
# them like this:
# 主机IP范围
## www[001:006].example.com
# You can also use ranges for multiple hosts:
## db-[99:101]-node.example.com
# Ex 3: A collection of database servers in the 'dbservers' group:
[dbservers] # 数据库服务器组
##
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
192.168.155.120
192.168.155.110 ansible_connection=local
# ansible_connection=local 自己调用自己,不会用远程连接
# Ex4: Multiple hosts arranged into groups such as 'Debian' and 'openSUSE':
## [Debian]
## alpha.example.org
## beta.example.org
## [openSUSE]
## green.example.com
## blue.example.com
# 机器特别多的情况
[allserver:ziji]
webservers
dbservers

这个报错需要输入密码,要在命令后加一个-k
ansible 192.168.155.120 -m ping -k

查看 Inventory 是否读取成功
ansible-inventory --list
查看主机分类
ansible-inventory --graph
最好是做所有机器之间免密登录。
#!/bin/bash
dnf -y install sshpass &> /dev/null
rm -rf /root/.ssh/known_hosts
password="root"
ip=(192.168.155.110 192.168.155.120 192.168.155.130 192.168.155.140)
if [ ! -f /root/.ssh/id_rsa ];then
ssh-keygen -t rsa -b 2048 -f /root/.ssh/id_rsa -N "" &> /dev/null
fi
for i in ${ip[@]}
do
echo "now $i"
sshpass -p "$password" ssh-copy-id -o StrictHostKeyChecking=no root@$i &> /dev/null
done
echo "All done"
sleep 7
ehco "删除脚本文件"
rm -rf $0

针对某个分类执行命令,也支持通配符

6. Ansible命令语法
ansible <host-patten> [-f forks] [-m modules_name] [-a args]
host-partten:表示对哪些主机生效
-f fork: 一次性处理多少主机(启动并发线程数)
-m moduile_name : 要使用的模块
-a args:传输模块特有的参数
-v 显示详细信息
-C 检测运行模式(测试执行)
-i 指定主机清单文件(默认为/etc/ansible/hosts)
-k 基于ssh密码传输(非基于密钥认证)
--list 列出对执行的所有主机
--syntax-check : 对 playbook 剧本实现语法检测
连接相关选项
-c CONNECTION:使用什么方式连接目标主机,默认为smart
-u REMOTE USER: 指定目标主机连接的用户名,默认为None

6.1 Ansible常用模块
查看所有模块
ansible-doc -l # 列出所有模块
ansible-doc -s [modles] # 查看模块用法
6.1.1 连通性测试模块
ping 模块
# ping 模块
测试 Ansible 是否能够通过 SSH 连接远程主机并执行模块。
6.1.2 命令模块
command 模块
# command 模块
在远程主机执行普通 Linux 命令,不支持幂等(幂等性指同一个操作无论执行一次还是多次,系统产生的结果都是一致的,不会因为重复执行而产生副作用。)
特点:
默认不通过 Shell 解释命令。
不支持管道 |。
不支持重定向 >。
不支持 Shell 变量展开。
shell模块
# shell 模块
通过远程 Shell 执行命令。
ansible all -m shell -a "ps aux | grep nginx"

6.1.3 文件管理模块
copy 模块
# copy 模块
作用:将控制端的文件复制到远程主机。
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts mode=0644"
ansible 192.168.155.120 -m copy -a "content="ni hao" dest=/tmp/hosts.txt mode=0644"
ansible 192.168.155.120 -m copy -a "content='ni hao\nasdasdasdasd\n' dest=/tmp/hosts.txt mode=0644"
拷贝真个目录:
ansible all -m copy -a "src=/root/ dest=/tmp"
| 参数 | 含义 |
|---|---|
src |
本地源文件 |
dest |
远程目标路径 |
mode |
文件权限 |
owner |
文件所有者 |
group |
文件所属组 |
content |
将Content里的文字,输入到远程目标路径文件内容里 |
在使用 copy 模块拷贝目录时,src 末尾有没有斜杠,决定了拷贝的层级:
src 写法 |
拷贝结果 | 举例(拷贝到 /tmp) |
|---|---|---|
src=/root/ (带斜杠) |
拷贝该目录里面的内容 | /tmp/file1, /tmp/dir1/ |
src=/root (无斜杠) |
拷贝该目录本身(包含目录名) | /tmp/root/file1, /tmp/root/dir1/ |

file 模块
# file 模块
作用:创建、删除文件或目录,修改权限和属主。
创建目录:
ansible all -m file -a "path=/data state=directory"
创建空文件:
ansible all -m file -a "path=/data/test.txt state=touch"
删除文件:
ansible all -m file -a "path=/data/test.txt state=absent"
修改权限:
ansible all -m file -a "path=/data mode=0755"
软连接
ansible 192.168.155.120 -m file -a "src=/root/anaconda-ks.cfg path=/mnt/a.link state=link"
| state | 作用 |
|---|---|
directory |
创建目录 |
touch |
创建空文件或更新时间 |
file |
管理已存在的文件属性 |
absent |
删除文件或目录 |
link |
创建软链接 |
recurse |
递归设置目录 /srv/www 下所有内容的权限 |
force |
强行删除 |

fetch 模块
# fetch 模块
作用:从远程主机下载文件到 Ansible 控制端。
ansible all -m fetch -a "src=/etc/hostname dest=/tmp/backup"
注意:fetch 与 copy 方向相反。
copy:控制端 → 被管理主机。fetch:被管理主机 → 控制端。

对于大目录、多文件、经常变动的目录,copy 模块性能很差,且不支持完全同步删除。推荐用 synchronize 模块(rsync)
注意:synchronize 需要目标机安装 rsync。
ansible all -m synchronize -a "src=/root/ dest=/tmp/ delete=yes"
6.1.4 软件包管理模块
yum | dnf 模块
# yum 模块或或者dnf模块
作用:使用 YUM 管理软件包,适用于 Rocky Linux 等 RPM 系发行版。
安装nginx,安装最新版本latest
ansible all -m yum -a "name=nginx state=present"
卸载nginc,removed
ansible all -m yum -a "name=nginx state=absent"

6.1.5 服务管理模块
service 模块
# service 模块
作用:管理远程 Linux 服务。
启动nginx
ansible all -m service -a "name=nginx state=started"
| 参数 | 含义 |
|---|---|
| name | 服务名称 |
| state=started | 启动 |
| state=stopped | 停止 |
| state=restarted | 重启 |
| state=reloaded | 重新加载 |
| enabled=yes | 设置开机自启 |

6.1.6 用户和组管理模块
user 模块
# user 模块
作用:创建、修改和删除用户。
创建用户:
ansible all -m user -a "name=zhangsan state=present"
删除用户:
ansible all -m user -a "name=zhangsan state=absent"
删除用户并且删除家目录
ansible 192.168.155.120 -m user -a 'user=zhangsan remove=yes state=absent'
创建用户并指定家目录:
ansible all -m user -a "name=zhangsan home=/home/zhangsan create_home=yes"
# 创建服务用户
ansible all -m user -a "name=myapp system=yes shell=/sbin/nologin create_home=no"
ansible 192.168.155.120 -m user -a 'user=zhangsan uid=2000 group=root shell=/bin/sh state=present'

group模块
group:
作用:创建组
创建组
ansible all -m group -a "name=public gid=2500 state=present"
删除组
ansible all -m group -a "name=public state=absent"

6.1.7 更改主机信息
hostname模块
# hostname
作用:更改主机名

6.1.7 下载模块
Get_url模块
# Get_url
作用:主要用于 从远程 URL 下载文件到被管理主机,类似于 Linux 中的 wget 命令。
ansible 192.168.155.120 -m Get_url -a "url=https://nginx.org/download/nginx-1.28.3.tar.gz dest=/root/"
| 参数 | 作用 |
|---|---|
url |
指定文件下载地址 |
dest |
指定文件保存路径 |
mode |
设置文件权限 |
owner |
设置文件所有者 |
group |
设置文件所属组 |
force |
是否强制重新下载 |
checksum |
校验下载文件完整性 |
timeout |
设置下载超时时间(秒) |
url_username |
HTTP 身份验证用户名 |
url_password |
HTTP 身份验证密码 |
validate_certs |
是否验证 HTTPS 证书 |
backup |
下载前备份已存在的目标文件 |
headers |
设置 HTTP 请求头 |

6.1.8 压缩
archive模块
# archive模块
作用:将文件或目录压缩打包。
ansible 192.168.155.120 -m archive -a "path=/tmp/nginx-1.28.3 dest=/root/nginx.tar.gz format=gz"
| 参数 | 作用 | 示例 |
|---|---|---|
path |
指定需要压缩的文件或目录 | path=/data |
dest |
指定压缩包保存路径 | dest=/tmp/data.tar.gz |
format |
指定压缩格式 | format=gz |
owner |
设置压缩包所有者 | owner=root |
group |
设置压缩包所属组 | group=root |
mode |
设置压缩包权限 | mode=0644 |
force_archive |
是否强制创建压缩包 | force_archive=yes |

unarchive模块
# archive模块
作用:解压缩
| 参数 | 作用 | 示例 |
|---|---|---|
src |
指定压缩包路径 | src=/root/data.tar.gz,,copy= yes|no,是否在本机执行 |
dest |
指定解压目标目录 | dest=/opt |
remote_src |
压缩包是否已经存在于远程主机 | remote_src=yes |
owner |
设置解压文件所有者 | owner=root |
group |
设置解压文件所属组 | group=root |
mode |
设置解压文件权限 | mode=0755 |
creates |
指定文件存在时跳过解压 | creates=/opt/data |
list_files |
是否列出压缩包中的文件 | list_files=yes |
exclude |
排除指定文件 | exclude=file.txt |
include |
仅解压指定文件 | include=file.txt |

6.1.9 运行本地脚本
script模块
# script模块
作用:本地有脚本,在远程执行。脚本文件也无需执行权限
ansible 192.168.155.120 -m script -a '/root/a.sh'
| 参数 | 作用 | 示例 |
|---|---|---|
chdir |
执行脚本之前,先切换到远程主机的 /data 目录。 |
chdir=/data |
creates |
如果远程主机已经存在 /data/install.log,就跳过脚本执行;不存在才执行。 |
creates=/data/install.log |
removes |
指定文件不存在时跳过脚本执行 | removes=/data/test.txt |
executable |
指定远程执行脚本的解释器 | executable=/bin/bash |

6.1.10 修改远程主机文件内容
lineinfile 模块
# lineinfile 模块
作用:确保文件中存在某一行,或者修改、删除指定行。lineinfile模块,功能有点类似sed
12.ansible lineinfile模块 replace内容替换模块 - 老夫聊发少年狂88 - 博客园
| 参数 / 取值 | 作用 |
|---|---|
path |
指定要修改的文件路径 |
line |
要添加或替换成的完整行 |
regexp |
使用正则表达式匹配目标行 |
state=present |
确保指定行存在(默认) |
state=absent |
删除匹配的行 |
insertafter |
在指定行之后插入 |
insertbefore |
在指定行之前插入 |
backup=yes |
修改前备份文件 |
create=yes |
文件不存在时创建文件 |
backrefs |
1.backrefs为no时,如果没有匹配,则添加一行line。如果匹配了,则把匹配内容替被换为line内容。 2.backrefs为yes时,如果没有匹配,则文件保持不变。如果匹配了,把匹配内容替被换为line内容。 |
# 整行替换
ansible 192.168.155.120 -m lineinfile -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen' line='Listen 8080'"

replace 模块
# replace 模块
作用:使用正则表达式匹配文件中的内容,并将匹配到的内容替换成指定内容。
# 备份原文件后在实现替换
ansible 192.168.155.120 -m replace -a "path=/etc/httpd/conf/httpd.conf regexp='Listen 80' replace='Listen 8080' backup=yes"
| 参数 | 作用 |
|---|---|
path |
指定需要修改的文件 |
regexp |
正则表达式,匹配需要替换的内容 |
replace |
替换后的内容 |
backup=yes |
修改前备份文件 |
after |
仅处理指定内容之后的部分 |
before |
仅处理指定内容之前的部分 |
lineinfile 和 replace 的区别
| 对比项 | lineinfile | replace |
|---|---|---|
| 主要作用 | 按行添加、修改、删除 | 按正则匹配内容并替换 |
| 匹配方式 | regexp 匹配行 |
regexp 匹配文本 |
| 添加新行 | 支持 | 不适合 |
| 删除内容 | 可以删除匹配的行 | 可以替换为空字符串 |
| 批量替换 | 主要针对匹配行 | 适合多个文本匹配 |
| 典型场景 | 修改配置文件某一行 | 批量替换配置内容 |
6.1.11 收集被管理主机的系统信息(Facts)
setup模块
# setup模块
简单来说:控制端通过 setup 模块获取远程主机的操作系统、IP 地址、CPU、内存、主机名、磁盘等信息。
ansible 192.168.155.120 -m setup

| 参数 | 作用 |
|---|---|
filter |
根据名称筛选 Facts |
gather_subset |
指定收集哪些类别的信息 |
gather_timeout |
设置收集超时时间 |
fact_path |
指定远程主机自定义 Facts 文件目录 |
只查看 IP 地址
ansible 192.168.155.120 -m setup -a "filter=ansible_all_ipv4_addresses"
查看主机名
ansible 192.168.155.120 -m setup -a "filter=ansible_hostname"
查看操作系统信息
ansible 192.168.155.120 -m setup -a "filter=ansible_distribution*"
可以获取发行版名称、版本等信息。
查看 CPU 信息
ansible 192.168.155.120 -m setup -a "filter=ansible_processor*"
查看内存信息
ansible 192.168.155.120 -m setup -a "filter=ansible_mem*"
只收集网络信息
ansible 192.168.155.120 -m setup -a "gather_subset=network"
Ansible命令执行过程
- 加载自己的配置文件
- 加载自己对对应的模块文件,如shell
- 通过ansible 将模块或命令生成对应的临时Python文件,并将该文件传输到远程服务器的对应执行用户
$HOME/.ansible/tmp/ansible-tmp-数字/XXX.py文件。 - 给文件执行权限,并执行
- 执行并返回结果
- 删除临时py文件,sleep 0 退出
执行状态:
绿色:执行成功,并且不需要做改变的操作
黄色:执行成功,并且对目标主机做更改
红色:执行失败

浙公网安备 33010602011771号