运维故障排查面试题
基础网络故障
1. 服务连接超时,现场如何一步步排查?
故障现象: 用户反馈系统突然无法访问,浏览器提示"连接超时"。
排查思路:
确认故障范围
bash# 先确认是单机问题还是全网问题 ping -c 5 api.example.com # 检查本机网络状态 ip addr ip route检查端口连通性
bash# 测试目标端口是否可达 telnet 192.168.1.100 80 nc -zv 192.168.1.100 80 # 检查端口监听状态 netstat -tlnp | grep 80 ss -tlnp | grep 80追踪路由和延迟
bash# 检查路由是否正确 traceroute -m 10 api.example.com mtr -n api.example.com # 检查是否有丢包 ping -c 100 api.example.com | grep -E 'loss|rtt'检查防火墙
bash# iptables 规则 iptables -L -n iptables -L -n -t nat # 查看是否有 DROP/REJECT 规则 iptables -L -n -v | grep DROP检查云服务商安全组/网络ACL
- 检查云平台安全组规则是否允许该端口
- 检查网络ACL是否阻止了流量
常见原因:
- 防火墙规则变更阻止了流量
- 云平台安全组规则被修改
- 端口服务未启动
- 绑定IP不正确(监听127.0.0.1而非0.0.0.0)
2. DNS 解析故障如何排查?
故障现象: 用户反映某些域名解析失败,或者解析到错误的IP地址。
排查思路:
测试 DNS 解析
bash# 使用 nslookup nslookup api.example.com # 使用 dig(更详细) dig api.example.com dig @8.8.8.8 api.example.com # 指定DNS服务器 # 使用 host host api.example.com检查系统 DNS 配置
bashcat /etc/resolv.conf # 检查 hosts 文件 cat /etc/hosts测试 DNS 递归查询
bash# 测试是否能访问外部DNS ping -c 2 8.8.8.8 # 测试 DNS 53 端口 nc -zv 8.8.8.8 53检查 DNS 服务状态
bash# 检查本地 DNS 缓存服务 systemctl status systemd-resolved systemctl status named # 查看 DNS 查询日志 journalctl -u named -f验证解析结果
bash# 对比不同 DNS 服务器的解析结果 dig @114.114.114.114 api.example.com dig @1.1.1.1 api.example.com # 检查 CDN 或负载均衡器的健康状态 curl -I https://api.example.com
常见原因:
/etc/resolv.conf配置被覆盖或清空- DNS 服务器宕机或网络不通
- 域名到期未续费或域名解析平台故障
- CDN 节点故障导致解析到错误IP
- 本地 DNS 缓存服务异常
3. 如何处理网络延迟突然升高的问题?
故障现象: 监控系统报警,网络延迟从 5ms 突然飙升到 500ms,用户访问变慢。
排查思路:
确认延迟情况
bash# 多地探测延迟 ping -c 20 api.example.com | tail -1 # 检查带宽使用 sar -n DEV 1 10 ifstat -i eth0检查网络设备状态
bash# 检查交换机端口状态 ethtool eth0 ethtool -S eth0 # 检查是否有大量丢包 netstat -i ip -s link检查是否有网络攻击
bash# 检查连接数异常 netstat -an | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20 # 检查 SYN_RECV 连接 netstat -an | grep SYN_RECV | wc -l # 检查 DDoS 防护是否触发 iptables -L -n -v | grep DROP检查 MTU 问题
bash# 检查 MTU 设置 ip link | grep mtu # 测试 MTU ping -M do -s 1400 api.example.com
常见原因:
- 带宽被占满(大文件下载、备份等)
- 遭受 DDoS 攻击
- 网络设备(交换机/路由器)故障或配置变更
- MTU 不匹配导致分片重传
- 运营商网络抖动
内存故障
4. Java 进程被 OOM Killer 杀掉,如何排查?
故障现象: 凌晨 3 点收到告警,Java 应用突然重启,日志里没有任何错误输出。
排查思路:
确认是 OOM Killer 杀掉的
bash# 查看系统日志 dmesg -T | grep -i "out of memory" dmesg -T | grep -i "killed process" # 查看 messages 日志 grep -i "oom" /var/log/messages grep -i "killed process" /var/log/messages分析进程内存使用
bash# 查看进程内存使用 ps aux | grep java | grep -v grep # 查看内存详情 cat /proc/$(pgrep -f java)/status | grep -E 'VmRSS|VmSize|VmPeak' # 查看内存趋势 top -b -n 1 -p $(pgrep -f java)检查 JVM 堆外内存
bash# 查看进程的内存映射 pmap -x $(pgrep -f java) | sort -k3 -n -r | head -20 # 查看 DirectBuffer jstat -gc $(pgrep -f java) # 需要 jstat 工具检查系统内存状态
bash# 查看内存使用 free -h # 查看内存分配详情 cat /proc/meminfo # 查看哪些进程占用内存最多 ps aux --sort=-%mem | head -10分析内存泄漏
bash# 生成堆Dump(需要先保留现场) jmap -dump:format=b,file=heap.hprof <pid> # 分析 Dump 文件 jhat heap.hprof # 或使用 MAT (Memory Analyzer Tool)
常见原因:
- JVM 堆内存设置过大,超过了系统可用内存
- 存在内存泄漏(大量对象未释放)
- 使用了堆外内存(DirectByteBuffer、JNI、mmap)未控制
- 系统其他进程占用了大量内存
- 容器内存限制未配置或配置过小
解决方案:
# 合理设置 JVM 内存参数
java -Xms512m -Xmx1024m \
-XX:NativeMemoryTracking=summary \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/java_oom.hprof \
-jar app.jar5. 内存使用率过高但找不到进程,如何处理?
故障现象:free -h 显示内存使用率 95%,但 ps 看到的进程内存相加远不到这个数。
排查思路:
确认内存确实被占用
bash# 详细查看内存使用 free -h cat /proc/meminfo # 查看实际可用内存 available=$(cat /proc/meminfo | grep MemAvailable | awk '{print $2}') echo "Available: $available KB"检查 Slab 内存
bash# 检查 Slab 占用(内核对象缓存) slabtop cat /proc/slabinfo # 常见的高内存 Slab # - dentry cache(目录项缓存) # - inode cache(inode缓存) # - ext4 inode cache检查临时文件占用
bash# 检查 /tmp 目录 du -sh /tmp/* # 检查 /var/tmp du -sh /var/tmp/* # 检查是否有大文件被删除但仍被占用 lsof +L1检查共享内存
bash# 查看共享内存 ipcs -m # 检查 tmpfs df -h | grep tmpfs mount | grep tmpfs检查内存碎片化
bash# 检查 buddyinfo cat /proc/buddyinfo # 检查 vmstat vmstat -s vmstat -m
常见原因:
- 内核 Slab 内存泄漏(rare,但真实存在)
- 大文件被删除但有进程还在使用(deleted 文件)
- 共享内存未释放
- tmpfs 占用过高
- 内存碎片化导致无法分配
解决方案:
# 清理 pagecache
sync && echo 3 > /proc/sys/vm/drop_caches
# 清理 Slab(需要内核支持)
echo 2 > /proc/sys/vm/drop_caches
# 如果是 deleted 文件问题,重启相关进程6. 交换分区(Swap)使用率过高如何处理?
故障现象: 监控告警 Swap 使用率超过 80%,系统变慢。
排查思路:
检查 Swap 使用情况
bash# 查看 Swap swapon -s free -h # 查看哪些进程在用 Swap for f in /proc/*/status; do awk '/VmSwap/{s+=$2}END{print s,FILENAME}' $f; done | sort -rn | head检查 swappiness 参数
bash# 查看 swappiness(默认60,太高会导致频繁使用swap) cat /proc/sys/vm/swappiness # 临时修改 sysctl vm.swappiness=10检查是否有内存泄漏
bash# 观察内存使用趋势 vmstat 5 10 # 检查进程内存增长 ps aux --sort=-%mem | head -10
解决方案:
# 关闭并重新开启 Swap(清理 Swap 中的数据)
swapoff -a && swapon -a
# 永久修改 swappiness
echo "vm.swappiness=10" >> /etc/sysctl.conf
sysctl -p磁盘故障
7. 磁盘空间满了如何快速定位?
故障现象: 应用报错 "No space left on device",磁盘空间不足。
排查思路:
快速定位占用最大的目录
bash# 查看根目录占用 du -sh /* # 查看各分区使用情况 df -h # 快速找到大文件(>100M) find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null按时间查找新文件
bash# 查找最近24小时内修改过的大文件 find / -type f -mtime -1 -size +50M 2>/dev/null # 查找指定目录下的大文件 du -ah /var | sort -rh | head -20检查日志文件
bash# 查找大日志文件 find /var -name "*.log" -exec ls -lh {} \; 2>/dev/null # 检查日志目录 du -sh /var/log/* # 清理旧日志(根据实际情况) truncate -s 0 /var/log/xxx.log检查临时文件
bash# 检查 /tmp du -sh /tmp/* # 检查 /var/tmp du -sh /var/tmp/* # 清理 10 天前的临时文件 find /tmp -type f -atime +10 -delete检查隐藏文件
bash# 检查 .trash 等隐藏目录 du -sh /home/*/.* 2>/dev/null
常见原因:
- 日志文件未轮转,持续增长
- 临时文件未清理
- 数据库数据文件过大
- 备份文件占用大量空间
- 镜像文件、大文件误传
预防措施:
# 配置 logrotate
cat /etc/logrotate.conf
cat /etc/logrotate.d/your-app
# 示例配置
/var/log/your-app/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data www-data
}8. 如何处理 inode 耗尽的问题?
故障现象: 磁盘还有空间,但无法创建文件,报错 "No space left on device"。
排查思路:
确认是 inode 问题
bash# 检查 inode 使用情况 df -i # 查看各分区的 inode 总数和已使用数 df -i /dev/sda1查找 inode 占用最多的目录
bash# 查找 inode 占用 for i in /*; do echo "$i: $(find $i -type f 2>/dev/null | wc -l)"; done | sort -k2 -n -r | head # 查找小文件 find / -type f -size -1k 2>/dev/null | wc -l常见的高 inode 原因
bash# 检查邮件队列 find /var/spool/postfix -type f | wc -l # 检查临时文件 find /tmp -type f | wc -l # 检查 session 文件 find /var/lib/php/session -type f | wc -l
解决方案:
# 清理不需要的文件
find /var/spool/postfix -type f -delete
find /tmp -type f -atime +7 -delete
# 删除空目录
find / -type d -empty -delete
# 如果是 ext4 文件系统,无法动态增加 inode
# 只能重新格式化(会丢失数据):
mkfs.ext4 -N 2000000 /dev/sdb1 # 指定 inode 数量9. 磁盘 I/O 过高导致系统卡顿,如何排查?
故障现象: 系统突然变得很慢,load average 飙升,SSH 登录都困难。
排查思路:
确认是 I/O 问题
bash# 查看 iowait top -b -n 1 | head # 或 mpstat -P ALL 1 1 # 查看 I/O 状态 iostat -x 1 5找出是哪个进程在大量 I/O
bash# 查看进程 I/O iotop -o # 查看 I/O 统计 pidstat -d 1 5 # 查看具体进程的 I/O cat /proc/<pid>/io检查磁盘健康状态
bash# 检查磁盘使用率 df -h # 检查磁盘读写速度 hdparm -Tt /dev/sda # 检查 SMART 状态 smartctl -a /dev/sda检查是否有大量的写操作
bash# 查看哪些文件在频繁写入 inotifywait -m -r /var 2>/dev/null & # 查看打开的文件 lsof +D / 2>/dev/null | head -20
常见原因:
- 数据库大量写入(批量导入、夜间统计任务)
- 日志写入过快(未配置 logrotate)
- 磁盘本身故障(前兆)
- 其他人正在备份/拷贝大文件
- inode 重删等后台任务
解决方案:
# 使用 ionice 限制 I/O 优先级
ionice -c2 -n7 -p <pid>
# 使用 cgroup 限制磁盘带宽
# 写入 /sys/fs/cgroup/blkio/user.slice/tasks
echo "8:0 1048576" > /sys/fs/cgroup/blkio/user.slice/blkio.throttle.read_bps_device10. 服务器突然变成只读文件系统,如何处理?
故障现象: 应用无法写入文件,报错 "Read-only file system"。
排查思路:
确认是否真的是只读
bash# 测试写入 touch /tmp/test_file mount | grep " / " # 查看当前挂载选项 cat /proc/mounts | grep " / "检查磁盘错误
bash# 查看系统日志 dmesg | grep -i error dmesg | grep -i "read-only" # 检查文件系统错误 fsck -n /dev/sda1检查硬件状态
bash# 检查 RAID 状态(如果使用 RAID) cat /proc/mdstat mdadm --detail /dev/md0 # 检查 SCSI/SSD 寿命 smartctl -a /dev/sda
解决方案:
# 重新挂载为读写(如果临时问题)
mount -o remount,rw /
# 如果是文件系统损坏,需要 fsck(需要先卸载)
umount /dev/sda1
fsck -y /dev/sda1
mount /dev/sda1
# 如果是 RAID 故障,需要修复 RAID
mdadm --manage /dev/md0 --add /dev/sdb1Docker 故障
11. Docker 容器无法启动,一直处于 Restarting 状态
故障现象: 容器启动后立即退出,然后反复重启。
排查思路:
查看容器状态
bash# 查看容器状态 docker ps -a # 查看容器日志 docker logs <container_id> docker logs --tail 100 <container_id> docker logs --since "2024-01-01" <container_id>检查容器配置
bash# 查看容器详细信息 docker inspect <container_id> # 查看启动命令 docker inspect --format '{{.Config.Cmd}}' <container_id> docker inspect --format '{{.Config.Entrypoint}}' <container_id>检查镜像是否正常
bash# 检查镜像是否存在 docker images # 拉取最新镜像 docker pull <image_name> # 手动测试运行镜像 docker run --rm <image_name> /bin/sh检查资源限制
bash# 检查内存限制 docker inspect --format '{{.HostConfig.Memory}}' <container_id> # 检查用户限制 docker inspect --format '{{.Config.User}}' <container_id>常见错误排查
bash# "permission denied" 错误 docker logs <container_id> | grep -i "permission" # "no such file or directory" 错误 docker logs <container_id> | grep -i "no such" # "exec format error" 错误(架构不匹配) docker run --rm <image_name> 2>&1
常见原因:
- Entrypoint 或 CMD 配置错误
- 镜像与主机架构不匹配(如在 ARM 上运行 x86 镜像)
- 权限问题(文件权限、用户 UID/GID)
- 依赖服务未启动(如需要 MySQL 但 MySQL 未启动)
- 健康检查失败导致重启
解决方案:
# 以交互模式启动排查
docker run -it --rm <image_name> /bin/sh
# 临时禁用健康检查启动
docker run -d --no-healthcheck <container_name> <image_name>
# 检查并修复权限
docker exec <container_id> ls -la /app
docker exec <container_id> chown -R app:app /app12. Docker 容器无法访问外网
故障现象: 容器内无法 ping 通外网,也无法 curl 访问外部服务。
排查思路:
检查宿主机网络
bash# 确认宿主机可以上网 ping -c 3 8.8.8.8 curl -s https://www.google.com # 检查 docker0 网桥 ip addr show docker0 iptables -L -n -t nat | grep DOCKER检查容器网络
bash# 进入容器检查 docker exec -it <container_id> /bin/sh # 在容器内检查 cat /etc/resolv.conf ip addr ip route ping -c 3 8.8.8.8检查 DNS 配置
bash# 检查 DNS 解析 docker exec -it <container_id> nslookup google.com docker exec -it <container_id> cat /etc/resolv.conf检查 iptables 规则
bash# 查看 Docker 的 iptables 规则 iptables -L -n -t nat | grep -i docker iptables -L FORWARD -n -v # 检查 FORWARD 链是否被阻止 iptables -L FORWARD -n | grep DROP检查网络驱动
bash# 查看容器使用的网络 docker inspect --format '{{.NetworkSettings.Networks}}' <container_id> # 测试不同网络模式 docker run --rm --network host <image_name> curl -s https://www.google.com
常见原因:
- Docker daemon 重启后 docker0 网桥未正常创建
- iptables 规则丢失或被清理
- 宿主机 DNS 配置影响容器
- 网络模式问题(bridge/host/none)
- 防火墙阻止了 Docker 网桥流量
解决方案:
# 重启 Docker 服务
systemctl restart docker
# 重建 docker0 网桥
ip link del docker0
systemctl restart docker
# 手动添加 iptables 规则
iptables -A FORWARD -i docker0 -j ACCEPT
iptables -A FORWARD -o docker0 -j ACCEPT
# 配置 Docker DNS
# 编辑 /etc/docker/daemon.json
{
"dns": ["8.8.8.8", "114.114.114.114"]
}13. Docker Volume 挂载后容器内无法写入
故障现象: 将宿主机目录挂载到容器,容器内应用无法写入该目录。
排查思路:
检查挂载情况
bash# 查看容器挂载信息 docker inspect --format '{{.Mounts}}' <container_id> # 查看容器内目录权限 docker exec -it <container_id> ls -la /app docker exec -it <container_id> id检查宿主机目录权限
bash# 查看宿主机目录权限 ls -la /data ls -ld /data # 检查 SELinux 状态 getenforce常见权限问题
bash# 检查是否是 SELinux 问题 ls -Z /data docker exec -it <container_id> ls -laZ /app # 检查 AppArmor 状态 apparmor_status
解决方案:
# 方案1:修改宿主机目录权限
chmod 777 /data
chown -R 1000:1000 /data
# 方案2:使用 SELinux 安全上下文(推荐)
chcon -Rt svirt_sandbox_file_t /data
# 方案3:在 Docker Compose 中配置
services:
app:
image: your-image
volumes:
- /data:/app:z # :z 表示自动设置 SELinux
# 方案4:禁用 SELinux(不推荐)
setenforce 014. Docker 镜像拉取失败,如何处理?
故障现象:docker pull 报错 "manifest unknown" 或 "connection timeout"。
排查思路:
确认镜像名称
bash# 检查镜像标签是否正确 docker images docker search <image_name> # 确认官方镜像路径 docker pull library/nginx:latest docker pull mysql:8.0网络问题排查
bash# 测试到 Docker Hub 的连接 curl -s https://registry-1.docker.io/v2/ # 测试 DNS 解析 nslookup registry-1.docker.io # 检查代理设置 echo $HTTP_PROXY echo $HTTPS_PROXY cat /etc/systemd/system/docker.service.d/http-proxy.conf登录认证问题
bash# 登录 Docker Hub docker login # 登录私有仓库 docker login registry.example.com # 检查认证信息 cat ~/.docker/config.json镜像仓库问题
bash# 检查 Docker Hub 状态 curl -s https://status.docker.com/rss/feed.xml # 使用镜像加速器 # 编辑 /etc/docker/daemon.json { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com" ] }
常见原因:
- 镜像标签不存在(latest 标签已被删除)
- 网络问题(防火墙、代理)
- 认证过期
- Docker Hub 限流(anonymous 限流 100次/6小时)
- 私有证书问题
Kubernetes 故障
15. Pod 一直处于 Pending 状态如何排查?
故障现象: Pod 创建后一直处于 Pending 状态,不进入 Running。
排查思路:
查看 Pod 详情
bash# 查看 Pod 状态和事件 kubectl describe pod <pod-name> -n <namespace> # 查看所有 Pod 状态 kubectl get pod -n <namespace> -o wide检查调度相关事件
bash# 查找调度失败原因 kubectl describe pod <pod-name> | grep -A 10 "Events:" # 常见关键词: # - "No nodes available" → 资源不足 # - "node(s) had taints" → 节点有污点 # - "didn't match Pod's node affinity" → 亲和性不匹配检查资源配额
bash# 检查命名空间资源配额 kubectl get resourcequota -n <namespace> kubectl describe resourcequota -n <namespace> # 检查 LimitRange kubectl get limitrange -n <namespace> kubectl describe limitrange -n <namespace>检查节点资源
bash# 查看节点状态 kubectl get nodes # 查看节点资源使用 kubectl describe node <node-name> # 查看资源不足的节点 kubectl top nodes检查污点和亲和性
bash# 查看节点污点 kubectl describe node <node-name> | grep -A 5 "Taints" # 查看 Pod 亲和性配置 kubectl get pod <pod-name> -o jsonpath='{.spec.affinity}'
常见原因:
- 集群资源不足(CPU/内存不够)
- 节点存在污点,Pod 未配置容忍
- PVC 挂载等待(存储类问题)
- 镜像拉取等待(私有仓库认证问题)
- 调度被限制(亲和性、优先级)
16. Pod 处于 CrashLoopBackOff 状态如何处理?
故障现象: Pod 启动后立即崩溃,然后反复重启。
排查思路:
查看容器状态
bash# 查看 Pod 状态 kubectl get pod <pod-name> # 查看最近日志 kubectl logs <pod-name> --previous kubectl logs <pod-name> --tail 100 # 查看所有容器日志 kubectl logs <pod-name> --all-containers=true进入容器调试
bash# 如果 Pod 有多个容器,指定容器 kubectl exec -it <pod-name> -c <container-name> -- /bin/sh # 检查应用配置 kubectl exec -it <pod-name> -- ls -la /app kubectl exec -it <pod-name> -- cat /app/config.yaml检查健康检查
bash# 查看健康检查配置 kubectl describe pod <pod-name> | grep -A 20 "Liveness" kubectl describe pod <pod-name> | grep -A 20 "Readiness" # 临时移除健康检查测试 kubectl patch pod <pod-name> -p '{"spec":{"containers":[{"name":"app","livenessProbe":null}]}}'检查资源限制
bash# 查看资源限制 kubectl describe pod <pod-name> | grep -A 5 "Limits" kubectl describe pod <pod-name> | grep -A 5 "Requests" # 检查 OOMKilled kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[*].lastState.terminated}'常见错误类型
bash# "Exit code 1" → 应用本身退出 # "Exit code 137" → OOMKilled (内存超限) # "Exit code 143" → 被 SIGTERM 终止 # "Error" → 启动命令执行失败
解决方案:
# 增加资源限制
kubectl patch deployment <name> -p '{"spec":{"template":{"spec":{"containers":[{"name":"app","resources":{"limits":{"memory":"512Mi"},"requests":{"memory":"256Mi"}}}]}}}}'
# 调整健康检查参数
kubectl patch deployment <name> --type=json -p='[{"op":"replace","path":"/spec/template/spec/containers/0/livenessProbe/initialDelaySeconds","value":30}]'
# 增加重启延迟
kubectl patch deployment <name> -p '{"spec":{"template":{"spec":{"containers":[{"name":"app","livenessProbe":{"failureThreshold":5,"periodSeconds":10}}]}}}}'17. Service 无法访问,如何排查?
故障现象: Pod 可以正常访问,但通过 Service 无法访问。
排查思路:
确认问题范围
bash# 查看 Service 列表 kubectl get svc -n <namespace> # 查看 Service 详情 kubectl describe svc <service-name> -n <namespace> # 查看 Service 关联的 Pod kubectl get endpoints <service-name> -n <namespace>检查 Endpoints
bash# 如果 endpoints 为空,说明没有 Pod 匹配 Service kubectl describe svc <service-name> | grep -A 5 "Endpoints" # 检查 Pod 是否 Running kubectl get pod -n <namespace> -o wide | grep <service-name>检查 Selector 匹配
bash# 查看 Service 的 selector kubectl get svc <service-name> -o jsonpath='{.spec.selector}' # 查看 Pod 的 labels kubectl get pod <pod-name> --show-labels # 测试 selector 匹配 kubectl get pods -l "app=nginx" -n <namespace>检查网络策略
bash# 查看网络策略 kubectl get networkpolicy -n <namespace> kubectl describe networkpolicy <policy-name> -n <namespace> # 临时禁用网络策略测试 # kubectl delete networkpolicy <policy-name>检查 CoreDNS
bash# 检查 CoreDNS 是否正常 kubectl get pod -n kube-system -l k8s-app=kube-dns # 测试 DNS 解析 kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup <service-name> # 查看 CoreDNS 日志 kubectl logs -n kube-system -l k8s-app=kube-dns直接测试连接
bash# 创建一个临时 Pod 测试 kubectl run -it --rm debug --image=busybox --restart=Never -- sh # 在 Pod 内测试 wget -qO- http://<service-name>:<port> telnet <service-name> <port> curl http://<service-name>:<port>/health
常见原因:
- Endpoints 为空(没有匹配的 Pod)
- Selector 不匹配(标签写错)
- 端口配置错误
- 网络策略阻止
- CoreDNS 故障
18. Pod 无法拉取镜像,如何处理?
故障现象: Pod 一直处于 ImagePullBackOff 状态。
排查思路:
查看拉取错误
bashkubectl describe pod <pod-name> | grep -A 10 "Events:" # 常见错误: # - "ImagePullBackOff" → 拉取失败 # - "ErrImageNeverPull" → 策略禁止拉取 # - "ImagePull error" → 认证失败常见错误及解决方案
镜像名称错误:
bash# 确认镜像名称 docker images gcr.io/project/image:tag # 修正镜像名称 kubectl set image deployment/<name> <container>=correct-image:tag私有仓库认证问题:
bash# 创建 Secret kubectl create secret docker-registry my-registry-key \ --docker-server=registry.example.com \ --docker-username=admin \ --docker-password=password \ --docker-email=you@example.com # 在 Pod 中引用 # vim pod.yaml spec: imagePullSecrets: - name: my-registry-key证书问题:
bash# 编辑 daemon.json 信任证书 # vim /etc/docker/daemon.json { "insecure-registries": ["registry.example.com"] } systemctl restart docker测试手动拉取
bash# 在节点上手动拉取测试 docker pull <image_name> # 如果是私有镜像,先登录 docker login registry.example.com
19. PVC 一直处于 Pending 状态如何排查?
故障现象: Pod 无法启动,PVC 一直处于 Pending。
排查思路:
查看 PVC 状态
bashkubectl get pvc -n <namespace> kubectl describe pvc <pvc-name> -n <namespace>检查 StorageClass
bash# 查看可用的 StorageClass kubectl get storageclass # 查看 PVC 使用的 StorageClass kubectl get pvc <pvc-name> -o jsonpath='{.spec.storageClassName}' # 检查默认 StorageClass kubectl get storageclass -o jsonpath='{.items[?(@.metadata.annotations.storageclass.kubernetes.io/is-default-class=="true")].metadata.name}'检查 Provisioner
bash# 查看 StorageClass 的 provisioner kubectl get storageclass <storage-class> -o jsonpath='{.provisioner}' # 检查 provisioner Pod 是否运行 kubectl get pod -n kube-system | grep -i provisioner常见问题及解决方案
NFS/共享存储问题:
bash# 检查 NFS 服务 showmount -e <nfs-server> # 测试挂载 mount -t nfs <nfs-server>:/path /mnt云盘/块存储问题:
bash# 检查云平台控制台 # 确认云盘是否已创建 # 确认节点是否在可用区权限问题:
bash# 检查 StorageClass 的 reclaimPolicy kubectl get storageclass <storage-class> -o jsonpath='{.reclaimPolicy}' # 修改为 Retain 防止误删 kubectl patch storageclass <storage-class> -p '{"reclaimPolicy":"Retain"}'
20. Kubernetes 节点 NotReady 如何处理?
故障现象: 节点状态变为 NotReady,Pod 无法调度到该节点。
排查思路:
查看节点状态
bashkubectl get nodes kubectl describe node <node-name> # 查看节点条件 kubectl get node <node-name> -o jsonpath='{.status.conditions}'登录节点检查
bash# SSH 到问题节点 ssh <node-ip> # 检查 kubelet 状态 systemctl status kubelet journalctl -u kubelet -n 100 # 检查 kubelet 日志 journalctl -u kubelet --no-pager -n 200检查节点资源
bash# 检查磁盘空间 df -h # 检查内存 free -h # 检查 CPU top # 检查 inode df -i检查网络
bash# 检查节点网络 ip addr ip route # 检查 DNS cat /etc/resolv.conf # 测试 API Server 连通性 curl -k https://<api-server>:6443/healthz常见原因及处理
kubelet 未启动:
bashsystemctl start kubelet systemctl enable kubelet磁盘空间不足:
bash# 清理 Docker docker system prune -a journalctl --vacuum-time=7d证书过期:
bash# 检查证书过期时间 kubeadm alpha certs check-expiration # 更新证书 kubeadm alpha certs renew all
综合故障排查
21. 系统 load average 突然升高,如何快速定位?
故障现象: 监控告警 load average 飙升,系统响应变慢。
排查思路:
确认 load 情况
bash# 查看 load uptime top w # 查看运行队列 vmstat 1 5找出高负载原因
bash# 查看哪些进程占用 CPU 高 top -b -n 1 | head -20 ps aux --sort=-%cpu | head -10 # 查看哪些进程在等待 I/O iotop如果是 CPU 密集型
bash# 查看进程详情 top -p $(pgrep -f java) # 查看线程 ps -T -p <pid> # 查看系统调用 strace -c -p <pid>如果是 I/O 密集型
bash# 查看 I/O 统计 iostat -x 1 5 # 找出大量 I/O 的进程 iotop -o如果是可中断等待
bash# 查看 D 状态进程(不可中断等待) ps aux | grep -E " D " | head cat /proc/$(pgrep -f java)/wchan
常见原因:
- 大量计算任务突然启动
- 磁盘 I/O 过高
- 内存不足导致 swap
- 网络 I/O 等待
- 定时任务同时执行
22. 服务器被入侵了如何处理?
故障现象: 安全扫描发现服务器有异常行为,疑似被入侵。
排查思路:
隔离服务器
bash# 立即断开网络(防止继续扩散) # 在云平台安全组中禁用该服务器的所有出站流量 # 或使用 iptables 限制 iptables -I OUTPUT -j DROP保留现场
bash# 导出进程列表 ps aux > /tmp/ps.txt ps -ef > /tmp/ps-ef.txt # 导出网络连接 netstat -anp > /tmp/netstat.txt ss -anp > /tmp/ss.txt # 导出定时任务 crontab -l > /tmp/crontab.txt ls -la /var/spool/cron/ > /tmp/cron-list.txt # 导出登录日志 last > /tmp/last.txt lastlog > /tmp/lastlog.txt检查可疑进程
bash# 查看隐藏进程 ps -ef | awk '{print $2}' | sort > /tmp/ps-pids.txt ls /proc | grep "^[0-9]" | sort > /tmp/proc-pids.txt diff /tmp/ps-pids.txt /tmp/proc-pids.txt # 检查可疑进程 ps aux | grep -v "^\(USER\|root\)" | grep -v "ps aux" # 检查进程树 pstree -ap检查网络连接
bash# 检查异常连接 netstat -antp | grep ESTABLISHED | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn # 检查监听端口 netstat -tlnp | grep -v "127.0.0.1" # 检查 DNS 隧道特征 cat /etc/resolv.conf检查启动项和定时任务
bash# 检查 rc.local cat /etc/rc.local ls -la /etc/rc.d/ # 检查 init.d ls -la /etc/init.d/ # 检查 systemd 服务 systemctl list-unit-files | grep enabled # 检查 crontab crontab -l cat /var/spool/cron/crontabs/root检查可疑文件
bash# 检查 SUID 文件 find / -perm -4000 -type f 2>/dev/null > /tmp/suid-files.txt # 检查最近修改的文件 find / -mtime -1 -type f 2>/dev/null # 检查可疑脚本 find /tmp /var/tmp /dev/shm -type f -name "*.sh" 2>/dev/null # 检查 SSH authorized_keys cat ~/.ssh/authorized_keys
后续处理:
# 1. 备份数据(注意:可能已包含恶意代码)
tar -czvf /backup/important-data.tar.gz /data
# 2. 重装系统(强烈建议)
# 3. 从零开始部署
# 4. 恢复数据时仔细检查
# 5. 修改所有相关密码23. 如何预防和处理循环重启?
故障现象: 服务器进入循环重启,无法正常启动。
排查思路:
进入救援模式
bash# 在 GRUB 菜单选择 recovery mode # 或使用 Live CD 启动检查日志
bash# 查看上次启动日志 journalctl -b -1 # 查看 syslog cat /var/log/syslog | tail -100 # 查看 auth.log cat /var/log/auth.log | tail -100常见原因
磁盘满导致启动失败:
bash# 在救援模式下清理磁盘 mount /dev/sda1 /mnt rm -rf /mnt/var/log/*.gz rm -rf /mnt/tmp/* umount /mnt配置文件错误导致服务启动失败:
bash# 检查启动失败的服务 systemctl --failed # 修复配置文件 # 如 nginx 配置错误 nginx -t内核更新失败:
bash# 选择旧内核启动 # 在 GRUB 菜单选择 "Advanced options" # 选择之前的内核版本防止自动重启
bash# 临时禁用自动重启 sysctl kernel.panic=0 # 修改 GRUB 配置禁用自动重启 # vim /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT="panic=0" update-grub
24. 应用程序假死后如何快速恢复?
故障现象: 应用进程还在,但不再响应请求。
排查思路:
确认进程状态
bash# 查看进程状态 ps aux | grep <app_name> # 查看进程系统调用 strace -p <pid> # 查看进程文件描述符 lsof -p <pid>检查线程状态
bash# 查看线程 ps -T -p <pid> # 查看线程堆栈 pstack <pid> # 使用 gdb 查看 Java 线程 jstack <pid>检查资源占用
bash# 检查内存 cat /proc/<pid>/status | grep -E "VmRSS|VmPeak" # 检查打开的文件描述符 ls /proc/<pid>/fd | wc -l # 检查网络连接 cat /proc/<pid>/net/tcp常见原因
- 线程死锁
- 连接池耗尽
- 内存泄漏导致 GC 不停
- 磁盘空间不足无法写日志
快速恢复方案:
# 如果是容器内应用
docker restart <container_id>
# 如果是物理机上的进程
# 1. 先保留现场
kill -STOP <pid> # 暂停进程
# 2. 导出堆栈等信息
# 3. 重启
kill -TERM <pid>
# 4. 如果无法优雅退出
kill -9 <pid>故障排查思路总结
快速定位口诀
1. "先问人,后看表" - 确认故障影响范围
2. "先外部,后内部" - 先排除网络/硬件问题
3. "先日志,后代码" - 查看日志再分析代码
4. "先止血,后根治" - 先恢复服务再找原因
5. "先备份,后操作" - 关键操作前先备份常用排查命令速查
# 系统状态
top, htop, vmstat, mpstat, iostat, free, df -h, du -sh /*
# 网络
netstat, ss, ping, traceroute, mtr, tcpdump, iptables -L -n
# 进程
ps aux, pgrep, pstack, strace, lsof
# Docker
docker ps, docker logs, docker inspect, docker stats
# Kubernetes
kubectl get pods, kubectl describe, kubectl logs, kubectl exec日志位置速查
# 系统日志
/var/log/messages # RedHat/CentOS
/var/log/syslog # Debian/Ubuntu
/var/log/dmesg # 启动日志
/var/log/secure # 安全日志
# 应用日志
/var/log/nginx/ # Nginx
/var/log/mysql/ # MySQL
~/.pm2/logs/ # PM2
/var/log/docker.log # Docker
# Kubernetes
kubectl logs <pod>
kubectl describe pod <pod>