2026年5月12日
`知识点回顾`
1.oss购买与使用
和nas的区别类似网盘和共享硬盘
可以直接访问nas资源,还有很多nas没有的功能,如图片审计,内容鉴别
2.CDN购买与使用
CDN是什么 分布式内容分发网络
配置cname解析到CDN让用户访问静态资源时直接去离他最近的CDN去找提高用户体验,访问速度CDN加速
预热:CDN没有的,源站的新内容,为提高用户体验提前将资源放到CDN
刷新:源站内容更新,CDN还是旧内容需要刷新删除CDN旧资源让CDN会源站拿新资源
3.waf
web应用防火墙
防止相关安全工具如cc,dos..
4.ESS弹性伸缩
自动根据需求扩容示例减少实例
增加:自动添加实例
减少:自动减少实例
自愈:当示例故障自动创建相同配置的实例
5.NAT
网络地址转换
SNAT:源地址转换
内网IP+端口->公网IP+随机端口
DNAT:目标地址转换
公网IP+随机端口->内网IP+端口
00.总回顾

系统负载高排查流程(面试题)
Linux系统负载高排查流程
一、快速确认负载情况
bash
# 查看系统负载和运行时间
uptime
# 或
top -bn1 | head -5
# 查看cpu核心数(用于判断负载是否超过核心数)
nproc
解读: load average 的 1/5/15 分钟值,若长期高于 CPU 核心数(如 4 核 > 4.0),说明负载过高。
二、定位负载来源(进程级)
bash
# 动态查看进程(按CPU或内存排序,交互模式按 P 按CPU排序,M按内存)
top
# 或更现代的工具
htop
# 查看占用CPU最高的10个进程
ps aux --sort=-%cpu | head -11
# 查看占用内存最高的10个进程
ps aux --sort=-%rss | head -11
# 统计所有进程CPU使用率(查看是否存在大量进程)
ps -eo %cpu --no-headers | awk '{sum+=$1} END {print "总CPU使用率:", sum,"%"}'
三、分类排查常见原因
1. CPU 使用率高(us/sy 高)
bash
# 查看详细CPU使用情况
mpstat -P ALL 1 5
# 查看中断情况
watch -n 1 "cat /proc/interrupts | head -20"
常见原因: 业务程序死循环、计算密集任务、频繁GC、系统调用过多。
2. 高 I/O 等待(wa 高)
bash
# 查看磁盘I/O状态
iostat -x 1 5
# 查看哪个进程在读写磁盘
iotop -o
# 查看进程I/O
pidstat -d 1
常见原因: 磁盘性能不足、大量随机读写、日志刷盘过快、swap 换入换出。
3. 内存不足导致频繁 swap(si/so 高)
bash
# 查看内存和swap使用
free -h
# 查看虚拟内存统计
vmstat 1 5
# 查看哪些进程占用swap
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{print ""}' $file 2>/dev/null; done | sort -k 2 -n -r | head -10
4. 进程数/线程数过多(运行队列长)
bash
# 查看系统总进程数和线程数
ps -e | wc -l
ps -eLf | wc -l
# 查看特定进程的线程数
ps -Lf <PID> | wc -l
# 查看进程状态分布(R=运行,D=不可中断睡眠,S=睡眠)
ps -eo stat | cut -c1 | sort | uniq -c
常见原因: Web服务线程池过大、fork bomb、连接数爆炸。
5. 系统平均负载高但CPU空闲(常见于 D 状态进程)
bash
# 查看是否有大量D状态(不可中断睡眠)进程
ps aux | awk '$8=="D" {print}'
# 查看进程调用栈确定卡在哪
cat /proc/<PID>/stack
echo t > /proc/sysrq-trigger # 输出所有任务栈到内核日志
dmesg | tail -50
常见原因: NFS 故障、磁盘/SAN 故障、内核驱动问题。
四、针对性工具排查
现象 工具 关键指标
不确定方向 htop, glances 全屏显示所有资源
历史趋势 sar -u 1 3, sar -q 需安装 sysstat
短时间内峰值 atop 记录历史快照
内核/系统调用 perf top, strace -p PID 热点函数追踪
网络连接过多 ss -s, netstat -an | wc -l TIME_WAIT/CLOSE_WAIT
僵尸进程 ps aux | grep Z 父进程未 wait
五、排查决策树
text
系统负载高
│
├─ top/htop 观察
│
├─ %us + %sy 高 ──→ 定位CPU进程 → 优化代码/增加CPU/迁移服务
│
├─ %wa 高 ──→ iostat 看磁盘
│ ├─ await > 20ms → 磁盘性能瓶颈
│ └─ %util 100% → 磁盘I/O饱和
│
├─ si/so > 0 ──→ free -h
│ ├─ available 接近 0 → 增加内存/减少内存使用
│ └─ cache 大但没释放 → 检查 swappiness
│
├─ 平均负载高但CPU空闲
│ ├─ ps aux | grep " D" → 存储/NFS问题
│ ├─ 大量 R 状态进程 → 核数不足
│ └─ 大量进程上下文切换 → vmstat 看 cs
│
└─ 以上都不明显 → dmesg | tail -20 检查内核日志/OOM
六、常用一键诊断脚本
bash
#!/bin/bash
echo "=== CPU核心数 ==="; nproc
echo "=== 负载 ==="; uptime
echo "=== CPU使用率 ==="; mpstat 1 1 | awk '/Average/ && !/CPU/ {print "user:"$3"% system:"$5"% iowait:"$6"% idle:"$12"%"}'
echo "=== 内存 ==="; free -h
echo "=== Top10 CPU进程 ==="; ps aux --sort=-%cpu | head -11
echo "=== Top10 内存进程 ==="; ps aux --sort=-%rss | head -11
echo "=== D状态进程 ==="; ps aux | awk '$8=="D"'
echo "=== 进程状态统计 ==="; ps -eo stat | cut -c1 | sort | uniq -c | sort -nr
echo "=== 磁盘I/O ==="; iostat -x 1 1 | awk '$1 ~ /^[sv]d/ || $1 ~ /^nvm/'
echo "=== 中断情况 ==="; cat /proc/interrupts | head -5
七、注意事项
不要只看负载绝对值:必须结合 CPU 核心数判断(4 核负载 4.0 刚好用满,8 核负载 4.0 比较空闲)
区分瞬时峰值和持续高负载:15 分钟负载更能说明问题
云服务器注意:可能受同宿主机其他 VM 影响(steal 高),查看 top 中的 %st
容器环境:需要检查容器本身的限制(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us)
java程序负载高排查流程
Java程序负载高
│
├─ 1. top/htop 确认 Java 进程 CPU 高
│
├─ 2. jstat -gcutil <PID> <─── 关键决策点
│
├─ FGC 频繁 (>1次/分钟 或 FGC>YGC的1/10)
│ │
│ ├─ jmap -histo:live 查看对象
│ │ ├─ 某个类实例数异常多 → 内存泄漏
│ │ └─ 大对象/数组 → 检查代码
│ │
│ ├─ jstat -gccause 查看触发原因
│ │
│ └─ 增加 -Xmx,优化代码减少对象创建
│
├─ YGC 频繁 (>5次/秒)
│ │
│ ├─ 年轻代太小 → 调整 -Xmn 或 -XX:NewRatio
│ ├─ 晋升阈值太低 → 调高 -XX:MaxTenuringThreshold
│ └─ survivor 空间不足 → 调整 -XX:SurvivorRatio
│
├─ 单线程 CPU 100%
│ │
│ ├─ top -H -p <PID> 找 TID
│ ├─ jstack <PID> | grep -A 50 "nid=0x..."
│ │
│ ├─ 业务代码死循环 → 修复代码
│ ├─ 频繁 GC(虽少见,但确认)→ 按 GC 流程
│ └─ 大量正则匹配 → 优化正则或缓存 Pattern
│
├─ 多线程 CPU 分散高
│ │
│ ├─ jstack 统计线程状态
│ │
│ ├─ RUNNABLE 大量 → 真计算密集,需扩容
│ ├─ WAITING/TIMED_WAITING 大量 → 活锁/频繁唤醒
│ └─ BLOCKED 大量 → 锁竞争,优化锁粒度
│
└─ CPU 不高但平均负载高
│
├─ 检查 io wait (top 的 %wa)
│ ├─ 高 → 磁盘日志刷太狠,异步落盘
│ └─ 正常 → strace 查系统调用
│
└─ 大量 D 状态线程 → jstack 看不到,需系统级排查
java优化25K+
选择合适的 GC 算法
内存大小调优
GC 日志分析
GC 优化决策表
问题 指标 解决方案
YGC 频繁 >5次/秒 增大 -Xmn 或调整 -XX:SurvivorRatio
YGC 时间长 >50ms 减少年轻代对象大小,对象池复用
FGC 频繁 >1次/分钟 增加 -Xmx,检查内存泄漏
FGC 时间长 >1s 改用 G1/ZGC,减少引用对象
Promotion Failed jstat 看到老年代增长快 调高 -XX:MaxTenuringThreshold
元空间 OOM Metaspace 持续增长 设置 -XX:MaxMetaspaceSize,检查动态类加载
代码层面优化
集合使用优化
并发优化
I/O 优化
数据库与外部调用优化
连接池配置
架构层面优化
限流降级
优先级 P0(立即做):
├── 数据库 N+1 查询
├── 明显的内存泄漏(堆一直增长)
├── 无限增长的缓存/集合
└── 没有连接池的 DB/Redis 调用
优先级 P1(本周内):
├── GC 参数调优
├── 大对象频繁创建
├── 线程池参数优化
└── 索引优化 + SQL 慢查询
优先级 P2(迭代中):
├── 本地缓存引入
├── 异步化非核心路径
├── 零拷贝/批处理优化
└── 代码细节优化(StringBuilder、集合初始容量等)
优先级 P3(长期):
├── 架构演进(微服务拆分)
├── 数据分片/读写分离
└── 全链路压测常态化
01.Ansible
1.Ansible介绍
Ansible 是一款开源的自动化运维工具,基于 Python 开发,用于配置管理、应用部署、任务自动化、IT 编排等场景。
┌─────────────────────────────────────────────────────────────────┐
│ Ansible 功能体系 │
├─────────────────────────────────────────────────────────────────┤
│ 配置管理 │ 应用部署 │ 任务编排 │ 基础设施即代码 │ 安全合规 │ 故障修复 │
├─────────────────────────────────────────────────────────────────┤
│ 核心能力层 │
│ 幂等性 │ 无代理 │ 声明式语言 │ 模块化 │ 可扩展 │ 回滚支持 │
├─────────────────────────────────────────────────────────────────┤
│ 生态集成层 │
│ 云平台(AWS/Azure/GCP) │ 容器(K8s/Docker) │ 网络设备 │ 数据库 │
与其他工具对比
| 工具 | 架构 | 语言 | 学习曲线 | 适用场景 |
|---|---|---|---|---|
| Ansible | 无代理 | YAML | 低 | 配置管理、应用部署、任务编排 |
| SaltStack | 有代理 | YAML + Python | 中 | 大规模配置管理、远程执行 |
| Puppet | 有代理 | 专有 DSL | 高 | 配置管理、合规性 |
| Chef | 有代理 | Ruby DSL | 高 | 基础设施即代码 |
| Terraform | 无代理 | HCL | 中 | 基础设施 provisioning(侧重创建) |
功能


Ansible框架学习流程

02.安装Ansible
#准备一台服务器kylin
1.安装Python
2.安装Ansible
3.配置Ansible
1.安装Python
1.下载
[root@ansible ~]# wget https://www.python.org/ftp/python/3.8.16/Python-3.8.16.tgz
2.解压
[root@ansible ~]# tar xzf Python-3.8.16.tgz
3.配置
[root@ansible ~]# cd Python-3.8.16/
[root@ansible Python-3.8.16]# ./configure --enable-optimizations
4.编译
[root@ansible Python-3.8.16]# make -j$(nproc)
5.安装
[root@ansible Python-3.8.16]# make altinstall
2.安装Ansible
[root@ansible Python-3.8.16]# pip3.8 install ansible -i https://mirrors.aliyun.com/pypi/simple/
3.配置Ansible
#默认没有、手动创建
1.创建配置目录
[root@ansible ~]# mkdir /etc/ansible
2.配置文件
[root@ansible ~]# vim /etc/ansible/ansible.cfg
[defaults]
host_key_checking = False # 控制 Ansible 是否检查远程主机的 SSH 密钥指纹
deprecation_warnings = False # 控制是否显示“弃用警告”
interpreter_python = /usr/bin/python3 # 指定使用的python3版本
[inventory] # 主机清单的位置默认/etc/ansible/hosts
[privilege_escalation] # sudo提权选项
[paramiko_connection] # 连接插件
[ssh_connection] # SSH远程连接插件
[persistent_connection] # SSH持久连接选项 默认选项
[accelerate]
[selinux]
[colors] # 颜色选项 默认
[diff] # copy模块对比内容 默认
注意:粘贴后将注释删除
#重要配置
1.禁用 SSH 主机密钥检查 (host_key_checking = False): 便于自动化,牺牲少量安全性。
2.禁用弃用警告 (deprecation_warnings = False): 让输出更干净。
3.强制使用 Python 3 (interpreter_python = /usr/bin/python3): 确保与现代系统的兼容性,这是一个非常重要的设置。
yum -y install sshpass # 为了支持SSH用户名密码方式管理后端
#忽略命令行警告提示
[root@ansible ~]# export PYTHONWARNINGS="ignore"
03.主机清单
配置文件/etc/ansible/hoss
基于用户名+密码
定义格式:可以是IP地址、域名、主机名称
1.定义单台
2.定义组
3.定义子组(一个组内包含了多个组)
基于免密钥
1.基于用户名+密码方式
1.1.定义单台
1.配置定义
[root@ansible ~]# cat /etc/ansible/hosts
172.16.1.7 ansible_ssh_user=root ansible_ssh_password='oldboy123.com' ansible_ssh_port=22
web01 ansible_ssh_host=172.16.1.7 ansible_ssh_user=root ansible_ssh_password='oldboy123.com'
2.测试
[root@ansible ~]# ansible 172.16.1.7 -m ping
172.16.1.7 | SUCCESS => {
"changed": false,
"ping": "pong"
}
[root@ansible ~]# ansible web01 -m ping
web01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
1.2.定义组
1.定义
[root@ansible ~]# cat /etc/ansible/hosts
172.16.1.7 ansible_ssh_user=root ansible_ssh_password='oldboy123.com' ansible_ssh_port=22
web01 ansible_ssh_host=172.16.1.7 ansible_ssh_user=root
ansible_ssh_password='oldboy123.com'
#定义一个webs组组内包含web01、web02
[webs]
web01 ansible_ssh_host=172.16.1.7
web02 ansible_ssh_host=172.16.1.8
#定义一个组变量webs
[webs:vars]
ansible_ssh_user=root
ansible_ssh_password='oldboy123.com'
#定义一个mysql组组内包含nfs、db01
[mysql]
nfs ansible_ssh_host=172.16.1.31
db01 ansible_ssh_host=172.16.1.51
#定义一个组变量
[mysql:vars]
ansible_ssh_user=root
ansible_ssh_password='oldboy123.com'
2.测试
#web组
[root@ansible ~]# ansible webs -m ping
web01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
web02 | SUCCESS => {
"changed": false,
"ping": "pong"
}
#MySQL组
[root@ansible ~]# ansible mysql -m ping
nfs | SUCCESS => {
"changed": false,
"ping": "pong"
}
db01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
1.3.定义子组(一个组内包含了多个组)
1.定义
[root@ansible ~]# cat /etc/ansible/hosts
172.16.1.7 ansible_ssh_user=root ansible_ssh_password='oldboy123.com' ansible_ssh_port=22
web01 ansible_ssh_host=172.16.1.7 ansible_ssh_user=root ansible_ssh_password='oldboy123.com'
[webs]
web01 ansible_ssh_host=172.16.1.7
web02 ansible_ssh_host=172.16.1.8
[webs:vars]
ansible_ssh_user=root
ansible_ssh_password='oldboy123.com'
[mysql]
nfs ansible_ssh_host=172.16.1.31
db01 ansible_ssh_host=172.16.1.51
[mysql:vars]
ansible_ssh_user=root
ansible_ssh_password='oldboy123.com'
#定义子组
[lnmp:children]
webs
mysql
2.测试
[root@ansible ~]# ansible lnmp -m ping
web01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
nfs | SUCCESS => {
"changed": false,
"ping": "pong"
}
db01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
web02 | SUCCESS => {
"changed": false,
"ping": "pong"
}
2.基于免秘钥方式
1.ansible服务端生成密钥对
2.将公钥拷贝到客户端
3.配置主机清单
2.1.ansible服务端生成密钥对
[root@ansible ~]# ssh-keygen
2.2.将公钥拷贝到客户端
[root@ansible ~]# ssh-copy-id 172.16.1.51
[root@ansible ~]# ssh-copy-id 172.16.1.31
[root@ansible ~]# ssh-copy-id 172.16.1.7
[root@ansible ~]# ssh-copy-id 172.16.1.8
2.3.配置主机清单
1.定义
[root@ansible ~]# cat /etc/ansible/hosts
web01 ansible_host=172.16.1.7
[webs]
172.16.1.7
172.16.1.8
[mysql]
172.16.1.31
172.16.1.51
[lnmp:children]
mysql
webs
2.测试
[root@ansible ~]# ansible web01 -m ping
web01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
[root@ansible ~]# ansible webs -m ping
172.16.1.7 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.16.1.8 | SUCCESS => {
"changed": false,
"ping": "pong"
}
[root@ansible ~]# ansible lnmp -m ping
172.16.1.8 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.16.1.7 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.16.1.31 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.16.1.51 | SUCCESS => {
"changed": false,
"ping": "pong"
}
04.Ansible-Ad-hoc
ansible所有的命令通过模块封装、将封装后的函数拷贝到目标主机,然后在目标主机进行执行。
语法:ansible 主机 -m 模块 -a '参数'
ansible #命令
172.16.1.7 #主机 组 子组 所有
-m #指定模块
-a '参数'
帮助:ansible-doc 模块 /EXA示例
常用的模块:
1.yum模块
2.file模块
3.copy模块
4.cron模块
5.user模块
6.systemd模块
7.command模块
1.yum模块
yum:
name: lrzsz #指定名称
state:present #对上面的软件做什么 present安装 absent 卸载
案例1:在web01安装lrzsz
[root@ansible ~]# ansible web01 -m yum -a 'name=lrzsz state=present'
web01 | SUCCESS => {
"ansible_facts": {
"pkg_mgr": "dnf"
},
"changed": false,
"msg": "Nothing to do",
"rc": 0,
"results": []
}
案例2:卸载web01的lrzsz
[root@ansible ~]# ansible web01 -m yum -a 'name=lrzsz state=absent'
web01 | CHANGED => {
"ansible_facts": {
"pkg_mgr": "dnf"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Removed: lrzsz-0.12.20-46.ky10.x86_64"
]
}
[root@web01 ~]# rpm -qa|grep lrzsz
案例3:同时卸载webs组内成员的lrzsz
[root@ansible ~]# ansible webs -m yum -a 'name=lrzsz state=absent'
172.16.1.7 | SUCCESS => {
"ansible_facts": {
"pkg_mgr": "dnf"
},
"changed": false,
"msg": "Nothing to do",
"rc": 0,
"results": []
}
172.16.1.8 | CHANGED => {
"ansible_facts": {
"pkg_mgr": "dnf"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Removed: lrzsz-0.12.20-46.ky10.x86_64"
]
}
2.file模块
案例1:在web01上创建test.txt
[root@ansible ~]# ansible web01 -m file -a 'path=/root/test.txt owner=www group=www mode=0600 state=touch'
web01 | CHANGED => {
"changed": true,
"dest": "/root/test.txt",
"gid": 666,
"group": "www",
"mode": "0600",
"owner": "www",
"size": 0,
"state": "file",
"uid": 666
}
案例2:修改属组属主权限
[root@ansible ~]# ansible web01 -m file -a 'path=/root/test.txt owner=root group=www mode=0700 state=touch'
web01 | CHANGED => {
"changed": true,
"dest": "/root/test.txt",
"gid": 666,
"group": "www",
"mode": "0700",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
[root@web01 ~]# ll test.txt
-rwx------ 1 root www 0 5月 12 19:48 test.txt
案例3:删除web01的test.txt
[root@ansible ~]# ansible web01 -m file -a 'path=/root/test.txt state=absent'
web01 | CHANGED => {
"changed": true,
"path": "/root/test.txt",
"state": "absent"
}
[root@web01 ~]# ll test.txt
ls: 无法访问 'test.txt': 没有那个文件或目录
案例4:在web01上创建Oldboy目录
[root@ansible ~]# ansible web01 -m file -a 'path=/root/oldboy state=directory'
web01 | CHANGED => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/oldboy",
"size": 6,
"state": "directory",
"uid": 0
}
[root@web01 ~]# ll -d oldboy/
drwxr-xr-x 2 root root 6 5月 12 19:52 oldboy/
案例5:递归创建1/2/3
[root@ansible ~]# ansible web01 -m file -a 'path=/root/1/2/3 state=directory'
web01 | CHANGED => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/1/2/3",
"size": 6,
"state": "directory",
"uid": 0
}
[root@web01 ~]# tree 1/
1/
└── 2
└── 3
案例6:删除目录3
[root@ansible ~]# ansible web01 -m file -a 'path=/root/1/2/3 state=absent'
web01 | CHANGED => {
"changed": true,
"path": "/root/1/2/3",
"state": "absent"
}
[root@web01 ~]# tree 1/
1/
└── 2
3.copy模块
copy:
src: oldboy.txt #指定源文件
dest: /opt/ #拷贝到目标主机的哪个位置
owner:www #指定属主
group:www #指定属组
mode: 0600 #指定权限
backup:yes #备份目标文件
content:将此参数后面的内容直接写入到目标文件中
案例1:将ansible上的oldboy.txt复制到web01和web02
[root@ansible ~]# ansible webs -m copy -a 'src=oldboy.txt dest=/root/ owner=www group=www mode=0600'
172.16.1.8 | CHANGED => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/root/oldboy.txt",
"gid": 666,
"group": "www",
"mode": "0600",
"owner": "www",
"path": "/root/oldboy.txt",
"size": 0,
"state": "file",
"uid": 666
}
172.16.1.7 | CHANGED => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/root/oldboy.txt",
"gid": 666,
"group": "www",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0600",
"owner": "www",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1778587729.2665346-70582-172379670004905/source",
"state": "file",
"uid": 666
}
[root@web01 ~]# ll oldboy.txt
-rw------- 1 www www 0 5月 12 20:08 oldboy.txt
[root@web02 ~]# ll oldboy.txt
-rw------- 1 www www 0 5月 12 20:04 oldboy.txt
案例2:将ansible上的test目录拷贝到客户端/opt下
[root@ansible ~]# ansible web01 -m copy -a 'src=test dest=/opt/'
web01 | CHANGED => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/opt/test/1.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1778588332.3438325-70723-26068290391465/source",
"state": "file",
"uid": 0
}
[root@web01 ~]# ll /opt/test/
总用量 0
-rw-r--r-- 1 root root 0 5月 12 20:18 1.txt
案例3:再次复制oldboy.txt到web01,目标已经存在了,新的文件会覆盖目标文件。如果备份目标文件使用backup
[root@ansible ~]# ansible web01 -m copy -a 'src=oldboy.txt dest=/root/ backup=yes'
web01 | SUCCESS => {
"changed": false,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/root/oldboy.txt",
"gid": 666,
"group": "www",
"mode": "0600",
"owner": "www",
"path": "/root/oldboy.txt",
"size": 0,
"state": "file",
"uid": 666
}
案例4:将content后的字符串写入到目标文件中
[root@ansible ~]# ansible web01 -m copy -a 'content=hehe... dest=/root/index.html'
web01 | CHANGED => {
"changed": true,
"checksum": "5bfa829e3063cd78dc3bd4a1fc4a0517dc727177",
"dest": "/root/index.html",
"gid": 0,
"group": "root",
"md5sum": "3a9df9b21e18a0d7c1f01e2e1f7f239e",
"mode": "0644",
"owner": "root",
"size": 7,
"src": "/root/.ansible/tmp/ansible-tmp-1778588659.071053-70790-132531399529035/source",
"state": "file",
"uid": 0
}
[root@web01 ~]# cat index.html
hehe...
4.cron模块
案例1.创建定时任务间隔5分钟执行时间同步
[root@ansible ~]# ansible web01 -m cron -a 'name=时间同步 minute=*/5 hour=* job="ntpdate ntp1.aliyun.com"'
web01 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"时间同步"
]
}
[root@web01 ~]# crontab -l
#Ansible: 时间同步
*/5 * * * * ntpdate ntp1.aliyun.com
案例2:创建定时任务-定时打包
[root@ansible ~]# ansible web01 -m cron -a 'name=备份 minute=00 hour=00 job="tar zcf /opt/a.tar.gz /etc/hosts"'
web01 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"时间同步",
"备份"
]
}
[root@web01 ~]# crontab -l
#Ansible: 时间同步
*/5 * * * * ntpdate ntp1.aliyun.com
#Ansible: 备份
00 00 * * * tar zcf /opt/a.tar.gz /etc/hosts
案例3:删除定时任务
[root@ansible ~]# ansible web01 -m cron -a 'name=时间同步 state=absent'
web01 | CHANGED => {
"changed": true,
"envs": [],
"jobs": [
"备份"
]
}
[root@web01 ~]# crontab -l
#Ansible: 备份
00 00 * * * tar zcf /opt/a.tar.gz /etc/hosts
5.user模块
group:
name: test01 #指定组名称
gid: 667 #指定gid
user:
name: test01 #用户的名称
uid: 667 #指定uid
group: test01 #指定小组 得提前创建
shell: /bin/bash #指定解释器 /sbin/nologin
create_home: false #不创建家目录、默认是创建目录
state:present #创建或者删除用户 absent
remove: yes #就是userdel后面的-r参数
案例1:创建test01组
[root@ansible ~]# ansible web01 -m group -a 'name=test01 gid=667'
web01 | CHANGED => {
"changed": true,
"gid": 667,
"name": "test01",
"state": "present",
"system": false
}
[root@web01 ~]# grep 'test01' /etc/group
test01:x:667:
案例2:创建普通账号指定uid667 gid667的test01
[root@ansible ~]# ansible web01 -m user -a 'name=test01 uid=667 group=test01 state=present'
web01 | CHANGED => {
"changed": true,
"comment": "",
"create_home": true,
"group": 667,
"home": "/home/test01",
"name": "test01",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 667
}
[root@web01 ~]# id test01
用户id=667(test01) 组id=667(test01) 组=667(test01)
案例3:创建虚拟账号 指定uid668 gid668的test02
[root@ansible ~]# ansible web01 -m group -a 'name=test02 gid=668'
[root@ansible ~]# ansible web01 -m user -a 'name=test02 uid=668 group=test02 shell=/sbin/nologin create_home=false state=present'
web01 | CHANGED => {
"changed": true,
"comment": "",
"create_home": false,
"group": 668,
"home": "/home/test02",
"name": "test02",
"shell": "/sbin/nologin",
"state": "present",
"system": false,
"uid": 668
}
[root@web01 ~]# id test02
用户id=668(test02) 组id=668(test02) 组=668(test02)
[root@web01 ~]# grep 'test02' /etc/passwd
test02:x:668:668::/home/test02:/sbin/nologin
[root@web01 ~]# ll /home/test02
ls: 无法访问 '/home/test02': 没有那个文件或目录
案例4:删除用户
[root@ansible ~]# ansible web01 -m user -a 'name=test01 state=absent remove=yes'
web01 | CHANGED => {
"changed": true,
"force": false,
"name": "test01",
"remove": true,
"state": "absent"
}
[root@web01 ~]# id test01
id: “test01”:无此用户
6.systemd模块
systemd:
name: nginx
state: started restarted stopped reloaded
enabled: yes #开机自启
案例环境准备
1.安装Nginx
[root@ansible ~]# ansible 172.16.1.31 -m yum_repository -a 'name=nginx description="EPEL YUM repo" baseurl="https://nginx.org/packages/centos/7/$basearch/" gpgcheck=no enabled=yes'
172.16.1.31 | CHANGED => {
"changed": true,
"repo": "nginx",
"state": "present"
}
2.安装Nginx
[root@ansible ~]# ansible 172.16.1.31 -m yum -a 'name=nginx state=present'
172.16.1.31 | CHANGED => {
"ansible_facts": {
"pkg_mgr": "dnf"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: nginx-1:1.26.1-2.el7.ngx.x86_64",
"Installed: compat-openssl10-1:1.0.2o-8.ky10.x86_64"
]
}
[root@nfs ~]# nginx -v
nginx version: nginx/1.26.1
3.配置首页
[root@ansible ~]# ansible 172.16.1.31 -m copy -a 'content=nfs.... dest=/usr/share/nginx/html/index.html'
172.16.1.31 | CHANGED => {
"changed": true,
"checksum": "5027a40c28fd2777a280aeb3d4a768daa4d1770d",
"dest": "/usr/share/nginx/html/index.html",
"gid": 0,
"group": "root",
"md5sum": "9695feb4677e8eacdfa32f12ba876ace",
"mode": "0644",
"owner": "root",
"size": 7,
"src": "/root/.ansible/tmp/ansible-tmp-1778591002.2800891-71287-190603958703588/source",
"state": "file",
"uid": 0
}
[root@nfs ~]# cat /usr/share/nginx/html/index.html
nfs....
案例1:启动Nginx
[root@ansible ~]# ansible 172.16.1.31 -m systemd -a 'name=nginx state=started'
[root@nfs ~]# netstat -tnulp|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10965/nginx: master
案例2:停止nginx
[root@ansible ~]# ansible 172.16.1.31 -m systemd -a 'name=nginx state=stopped'
[root@nfs ~]# netstat -tnulp|grep 80
[root@nfs ~]#
案例3:重启Nginx
[root@ansible ~]# ansible 172.16.1.31 -m systemd -a 'name=nginx state=restarted'
[root@nfs ~]# netstat -tnulp|grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 11560/nginx: master
案例4:重新加载
[root@ansible ~]# ansible 172.16.1.31 -m systemd -a 'name=nginx state=reloaded'
案例5:启动并加入开机自启
[root@ansible ~]# ansible 172.16.1.31 -m systemd -a 'name=nginx state=started enabled=yes'
[root@nfs ~]# systemctl status nginx|grep enable
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
7.command模块
不建议使用
[root@ansible ~]# ansible 172.16.1.31 -m command -a 'mkdir /root/oldboy'
172.16.1.31 | CHANGED | rc=0 >>
[root@nfs ~]# ll oldboy/ -d
drwxr-xr-x 2 root root 6 5月 12 21:17 oldboy/
正文完