Shell / ELK / K8s网络 / Ansible / 故障处理 · 点击展开答案
#!/bin/bash
# 磁盘使用率超阈值告警脚本
THRESHOLD=80 # 告警阈值(%)
LOG="/var/log/disk_alert.log"
# df 解析:跳过首行,提取使用率和挂载点
df -h | awk 'NR>1 {print $5, $6}' | while read usage mount; do
# 去掉百分号,转为数字
usage_num=${usage%%%}
if [ "$usage_num" -ge "$THRESHOLD" ]; then
msg="[$(date '+%F %T')] WARN: $mount 使用率 ${usage} 超过 ${THRESHOLD}%"
echo "$msg" | tee -a "$LOG"
# 发钉钉告警(替换 webhook)
curl -s -X POST "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$msg\"}}"
fi
done
# 每10分钟执行一次 */10 * * * * /bin/bash /opt/scripts/disk_check.sh
awk NR>1 跳标题行、${usage%%%} 去百分号、-ge 数值比较。这三个细节要能解释清楚。
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log # 采集 Nginx 访问日志
fields:
service: nginx # 自定义字段,便于 Kibana 过滤
output.elasticsearch:
hosts: ["http://es01:9200"]
index: "nginx-logs-%{+yyyy.MM.dd}" # 按天建索引
# 查看 Service 对应的 Endpoints(实际 Pod IP) kubectl get endpoints <svc-name> # 查看 iptables 转发规则(验证 ClusterIP 原理) iptables -t nat -L KUBE-SERVICES | grep <clusterIP>
/tmp 目录copy(MD5 对比不变不传)、yum(已装跳过)、service(已运行不重启)creates / when 条件控制# 非幂等写法(每次都执行)
- shell: echo "hello" > /tmp/test.txt
# 幂等写法(文件存在就跳过)
- shell: echo "hello" > /tmp/test.txt
args:
creates: /tmp/test.txt # 文件存在则跳过
# 或用 when 判断
- name: 初始化数据库
shell: mysql -u root < /tmp/init.sql
when: not db_initialized.stat.exists
# my.cnf 配置 slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 # 超过2秒记录 # 实时分析(找出最慢的SQL) mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
Using filesort 或 Using temporary 要警惕-- 查看执行计划 EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 1; -- type=ALL 且无索引 → 创建联合索引 ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);
# redis.conf # RDB:900秒内有1次写则触发快照 save 900 1 save 300 10 save 60 10000 # AOF:每秒刷盘(推荐,兼顾性能和安全) appendonly yes appendfsync everysec # no=最快丢数据多 | always=最安全但慢
Deployment 维护两个 ReplicaSet(旧版本 RS 缩减,新版本 RS 扩增),交替进行,保证服务不中断。
# deployment.yaml
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 最多允许1个Pod不可用(保证服务)
maxSurge: 1 # 最多允许超出期望副本数1个(加速更新)
# 触发滚动更新(改镜像) kubectl set image deployment/myapp app=harbor.xx.com/app:v2 # 查看更新进度 kubectl rollout status deployment/myapp # 查看历史版本 kubectl rollout history deployment/myapp # 回滚到上一版本 kubectl rollout undo deployment/myapp # 回滚到指定版本 kubectl rollout undo deployment/myapp --to-revision=2
upstream backend {
# ip_hash; # 开启 IP 会话保持
least_conn; # 最少连接算法
server 192.168.1.10:8080 weight=3; # 权重3
server 192.168.1.11:8080 weight=1;
server 192.168.1.12:8080 backup; # 备用节点
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# 第一层:网络是否可达 ping <服务IP> # 基础连通性 traceroute <服务IP> # 路由追踪 curl -Iv http://<服务IP>:<port> # 端口层测试 # 第二层:端口是否监听 ss -tlnp | grep <port> # 服务是否在监听 telnet <IP> <port> # 端口通不通 # 第三层:进程是否存活 systemctl status <service> ps aux | grep <process> # 第四层:看服务日志 journalctl -u <service> --since "10 min ago" tail -f /var/log/nginx/error.log # 第五层:资源是否耗尽 free -h # 内存 df -h # 磁盘(日志写满也会导致服务挂) ulimit -n # 文件描述符是否耗尽
kubectl get pod -n <ns> # Pod 是否 Running kubectl logs <pod> --previous # 上次崩溃的日志 kubectl describe svc <svc> # Service Endpoints 是否有 IP
inode(索引节点)存储文件的元数据:权限、所有者、大小、时间戳、数据块指针。文件名不在 inode 里,文件名存在目录项里,目录项指向 inode 编号。
# 磁盘空间还有,但无法创建新文件 df -h # 显示磁盘有剩余 df -i # inode 使用率 100% ← 根因 # 查看哪个目录 inode 最多 for dir in /var /tmp /home; do echo "$dir: $(find $dir | wc -l)" done
# 找出文件数最多的目录 find / -xdev -type f | cut -d/ -f2 | sort | uniq -c | sort -rn | head # 批量删除(谨慎确认路径后执行) find /var/lib/php/sessions/ -type f -mtime +7 -delete # 根本解法:调整 mkfs 时的 inode 密度(只能重新格式化) mkfs.ext4 -T largefile /dev/sdX # 适合大文件场景,inode 更少但文件更大
df -h 看空间,df -i 看 inode。磁盘没满但写不进文件,先查 inode。