Skip to content

运维故障排查面试题

基础网络故障

1. 服务连接超时,现场如何一步步排查?

故障现象: 用户反馈系统突然无法访问,浏览器提示"连接超时"。

排查思路:

  1. 确认故障范围

    bash
    # 先确认是单机问题还是全网问题
    ping -c 5 api.example.com
    
    # 检查本机网络状态
    ip addr
    ip route
  2. 检查端口连通性

    bash
    # 测试目标端口是否可达
    telnet 192.168.1.100 80
    nc -zv 192.168.1.100 80
    
    # 检查端口监听状态
    netstat -tlnp | grep 80
    ss -tlnp | grep 80
  3. 追踪路由和延迟

    bash
    # 检查路由是否正确
    traceroute -m 10 api.example.com
    mtr -n api.example.com
    
    # 检查是否有丢包
    ping -c 100 api.example.com | grep -E 'loss|rtt'
  4. 检查防火墙

    bash
    # iptables 规则
    iptables -L -n
    iptables -L -n -t nat
    
    # 查看是否有 DROP/REJECT 规则
    iptables -L -n -v | grep DROP
  5. 检查云服务商安全组/网络ACL

    • 检查云平台安全组规则是否允许该端口
    • 检查网络ACL是否阻止了流量

常见原因:

  • 防火墙规则变更阻止了流量
  • 云平台安全组规则被修改
  • 端口服务未启动
  • 绑定IP不正确(监听127.0.0.1而非0.0.0.0)

2. DNS 解析故障如何排查?

故障现象: 用户反映某些域名解析失败,或者解析到错误的IP地址。

排查思路:

  1. 测试 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
  2. 检查系统 DNS 配置

    bash
    cat /etc/resolv.conf
    
    # 检查 hosts 文件
    cat /etc/hosts
  3. 测试 DNS 递归查询

    bash
    # 测试是否能访问外部DNS
    ping -c 2 8.8.8.8
    
    # 测试 DNS 53 端口
    nc -zv 8.8.8.8 53
  4. 检查 DNS 服务状态

    bash
    # 检查本地 DNS 缓存服务
    systemctl status systemd-resolved
    systemctl status named
    
    # 查看 DNS 查询日志
    journalctl -u named -f
  5. 验证解析结果

    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,用户访问变慢。

排查思路:

  1. 确认延迟情况

    bash
    # 多地探测延迟
    ping -c 20 api.example.com | tail -1
    
    # 检查带宽使用
    sar -n DEV 1 10
    ifstat -i eth0
  2. 检查网络设备状态

    bash
    # 检查交换机端口状态
    ethtool eth0
    ethtool -S eth0
    
    # 检查是否有大量丢包
    netstat -i
    ip -s link
  3. 检查是否有网络攻击

    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
  4. 检查 MTU 问题

    bash
    # 检查 MTU 设置
    ip link | grep mtu
    
    # 测试 MTU
    ping -M do -s 1400 api.example.com

常见原因:

  • 带宽被占满(大文件下载、备份等)
  • 遭受 DDoS 攻击
  • 网络设备(交换机/路由器)故障或配置变更
  • MTU 不匹配导致分片重传
  • 运营商网络抖动

内存故障

4. Java 进程被 OOM Killer 杀掉,如何排查?

故障现象: 凌晨 3 点收到告警,Java 应用突然重启,日志里没有任何错误输出。

排查思路:

  1. 确认是 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
  2. 分析进程内存使用

    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)
  3. 检查 JVM 堆外内存

    bash
    # 查看进程的内存映射
    pmap -x $(pgrep -f java) | sort -k3 -n -r | head -20
    
    # 查看 DirectBuffer
    jstat -gc $(pgrep -f java)  # 需要 jstat 工具
  4. 检查系统内存状态

    bash
    # 查看内存使用
    free -h
    
    # 查看内存分配详情
    cat /proc/meminfo
    
    # 查看哪些进程占用内存最多
    ps aux --sort=-%mem | head -10
  5. 分析内存泄漏

    bash
    # 生成堆Dump(需要先保留现场)
    jmap -dump:format=b,file=heap.hprof <pid>
    
    # 分析 Dump 文件
    jhat heap.hprof
    # 或使用 MAT (Memory Analyzer Tool)

常见原因:

  • JVM 堆内存设置过大,超过了系统可用内存
  • 存在内存泄漏(大量对象未释放)
  • 使用了堆外内存(DirectByteBuffer、JNI、mmap)未控制
  • 系统其他进程占用了大量内存
  • 容器内存限制未配置或配置过小

解决方案:

bash
# 合理设置 JVM 内存参数
java -Xms512m -Xmx1024m \
     -XX:NativeMemoryTracking=summary \
     -XX:+HeapDumpOnOutOfMemoryError \
     -XX:HeapDumpPath=/var/log/java_oom.hprof \
     -jar app.jar

5. 内存使用率过高但找不到进程,如何处理?

故障现象:free -h 显示内存使用率 95%,但 ps 看到的进程内存相加远不到这个数。

排查思路:

  1. 确认内存确实被占用

    bash
    # 详细查看内存使用
    free -h
    cat /proc/meminfo
    
    # 查看实际可用内存
    available=$(cat /proc/meminfo | grep MemAvailable | awk '{print $2}')
    echo "Available: $available KB"
  2. 检查 Slab 内存

    bash
    # 检查 Slab 占用(内核对象缓存)
    slabtop
    cat /proc/slabinfo
    
    # 常见的高内存 Slab
    # - dentry cache(目录项缓存)
    # - inode cache(inode缓存)
    # - ext4 inode cache
  3. 检查临时文件占用

    bash
    # 检查 /tmp 目录
    du -sh /tmp/*
    
    # 检查 /var/tmp
    du -sh /var/tmp/*
    
    # 检查是否有大文件被删除但仍被占用
    lsof +L1
  4. 检查共享内存

    bash
    # 查看共享内存
    ipcs -m
    
    # 检查 tmpfs
    df -h | grep tmpfs
    mount | grep tmpfs
  5. 检查内存碎片化

    bash
    # 检查 buddyinfo
    cat /proc/buddyinfo
    
    # 检查 vmstat
    vmstat -s
    vmstat -m

常见原因:

  • 内核 Slab 内存泄漏(rare,但真实存在)
  • 大文件被删除但有进程还在使用(deleted 文件)
  • 共享内存未释放
  • tmpfs 占用过高
  • 内存碎片化导致无法分配

解决方案:

bash
# 清理 pagecache
sync && echo 3 > /proc/sys/vm/drop_caches

# 清理 Slab(需要内核支持)
echo 2 > /proc/sys/vm/drop_caches

# 如果是 deleted 文件问题,重启相关进程

6. 交换分区(Swap)使用率过高如何处理?

故障现象: 监控告警 Swap 使用率超过 80%,系统变慢。

排查思路:

  1. 检查 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
  2. 检查 swappiness 参数

    bash
    # 查看 swappiness(默认60,太高会导致频繁使用swap)
    cat /proc/sys/vm/swappiness
    
    # 临时修改
    sysctl vm.swappiness=10
  3. 检查是否有内存泄漏

    bash
    # 观察内存使用趋势
    vmstat 5 10
    
    # 检查进程内存增长
    ps aux --sort=-%mem | head -10

解决方案:

bash
# 关闭并重新开启 Swap(清理 Swap 中的数据)
swapoff -a && swapon -a

# 永久修改 swappiness
echo "vm.swappiness=10" >> /etc/sysctl.conf
sysctl -p

磁盘故障

7. 磁盘空间满了如何快速定位?

故障现象: 应用报错 "No space left on device",磁盘空间不足。

排查思路:

  1. 快速定位占用最大的目录

    bash
    # 查看根目录占用
    du -sh /*
    
    # 查看各分区使用情况
    df -h
    
    # 快速找到大文件(>100M)
    find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null
  2. 按时间查找新文件

    bash
    # 查找最近24小时内修改过的大文件
    find / -type f -mtime -1 -size +50M 2>/dev/null
    
    # 查找指定目录下的大文件
    du -ah /var | sort -rh | head -20
  3. 检查日志文件

    bash
    # 查找大日志文件
    find /var -name "*.log" -exec ls -lh {} \; 2>/dev/null
    
    # 检查日志目录
    du -sh /var/log/*
    
    # 清理旧日志(根据实际情况)
    truncate -s 0 /var/log/xxx.log
  4. 检查临时文件

    bash
    # 检查 /tmp
    du -sh /tmp/*
    
    # 检查 /var/tmp
    du -sh /var/tmp/*
    
    # 清理 10 天前的临时文件
    find /tmp -type f -atime +10 -delete
  5. 检查隐藏文件

    bash
    # 检查 .trash 等隐藏目录
    du -sh /home/*/.* 2>/dev/null

常见原因:

  • 日志文件未轮转,持续增长
  • 临时文件未清理
  • 数据库数据文件过大
  • 备份文件占用大量空间
  • 镜像文件、大文件误传

预防措施:

bash
# 配置 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"。

排查思路:

  1. 确认是 inode 问题

    bash
    # 检查 inode 使用情况
    df -i
    
    # 查看各分区的 inode 总数和已使用数
    df -i /dev/sda1
  2. 查找 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
  3. 常见的高 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

解决方案:

bash
# 清理不需要的文件
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 登录都困难。

排查思路:

  1. 确认是 I/O 问题

    bash
    # 查看 iowait
    top -b -n 1 | head
    # 或
    mpstat -P ALL 1 1
    
    # 查看 I/O 状态
    iostat -x 1 5
  2. 找出是哪个进程在大量 I/O

    bash
    # 查看进程 I/O
    iotop -o
    
    # 查看 I/O 统计
    pidstat -d 1 5
    
    # 查看具体进程的 I/O
    cat /proc/<pid>/io
  3. 检查磁盘健康状态

    bash
    # 检查磁盘使用率
    df -h
    
    # 检查磁盘读写速度
    hdparm -Tt /dev/sda
    
    # 检查 SMART 状态
    smartctl -a /dev/sda
  4. 检查是否有大量的写操作

    bash
    # 查看哪些文件在频繁写入
    inotifywait -m -r /var 2>/dev/null &
    
    # 查看打开的文件
    lsof +D / 2>/dev/null | head -20

常见原因:

  • 数据库大量写入(批量导入、夜间统计任务)
  • 日志写入过快(未配置 logrotate)
  • 磁盘本身故障(前兆)
  • 其他人正在备份/拷贝大文件
  • inode 重删等后台任务

解决方案:

bash
# 使用 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_device

10. 服务器突然变成只读文件系统,如何处理?

故障现象: 应用无法写入文件,报错 "Read-only file system"。

排查思路:

  1. 确认是否真的是只读

    bash
    # 测试写入
    touch /tmp/test_file
    mount | grep " / "
    
    # 查看当前挂载选项
    cat /proc/mounts | grep " / "
  2. 检查磁盘错误

    bash
    # 查看系统日志
    dmesg | grep -i error
    dmesg | grep -i "read-only"
    
    # 检查文件系统错误
    fsck -n /dev/sda1
  3. 检查硬件状态

    bash
    # 检查 RAID 状态(如果使用 RAID)
    cat /proc/mdstat
    mdadm --detail /dev/md0
    
    # 检查 SCSI/SSD 寿命
    smartctl -a /dev/sda

解决方案:

bash
# 重新挂载为读写(如果临时问题)
mount -o remount,rw /

# 如果是文件系统损坏,需要 fsck(需要先卸载)
umount /dev/sda1
fsck -y /dev/sda1
mount /dev/sda1

# 如果是 RAID 故障,需要修复 RAID
mdadm --manage /dev/md0 --add /dev/sdb1

Docker 故障

11. Docker 容器无法启动,一直处于 Restarting 状态

故障现象: 容器启动后立即退出,然后反复重启。

排查思路:

  1. 查看容器状态

    bash
    # 查看容器状态
    docker ps -a
    
    # 查看容器日志
    docker logs <container_id>
    docker logs --tail 100 <container_id>
    docker logs --since "2024-01-01" <container_id>
  2. 检查容器配置

    bash
    # 查看容器详细信息
    docker inspect <container_id>
    
    # 查看启动命令
    docker inspect --format '{{.Config.Cmd}}' <container_id>
    docker inspect --format '{{.Config.Entrypoint}}' <container_id>
  3. 检查镜像是否正常

    bash
    # 检查镜像是否存在
    docker images
    
    # 拉取最新镜像
    docker pull <image_name>
    
    # 手动测试运行镜像
    docker run --rm <image_name> /bin/sh
  4. 检查资源限制

    bash
    # 检查内存限制
    docker inspect --format '{{.HostConfig.Memory}}' <container_id>
    
    # 检查用户限制
    docker inspect --format '{{.Config.User}}' <container_id>
  5. 常见错误排查

    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 未启动)
  • 健康检查失败导致重启

解决方案:

bash
# 以交互模式启动排查
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 /app

12. Docker 容器无法访问外网

故障现象: 容器内无法 ping 通外网,也无法 curl 访问外部服务。

排查思路:

  1. 检查宿主机网络

    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
  2. 检查容器网络

    bash
    # 进入容器检查
    docker exec -it <container_id> /bin/sh
    
    # 在容器内检查
    cat /etc/resolv.conf
    ip addr
    ip route
    ping -c 3 8.8.8.8
  3. 检查 DNS 配置

    bash
    # 检查 DNS 解析
    docker exec -it <container_id> nslookup google.com
    docker exec -it <container_id> cat /etc/resolv.conf
  4. 检查 iptables 规则

    bash
    # 查看 Docker 的 iptables 规则
    iptables -L -n -t nat | grep -i docker
    iptables -L FORWARD -n -v
    
    # 检查 FORWARD 链是否被阻止
    iptables -L FORWARD -n | grep DROP
  5. 检查网络驱动

    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 网桥流量

解决方案:

bash
# 重启 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 挂载后容器内无法写入

故障现象: 将宿主机目录挂载到容器,容器内应用无法写入该目录。

排查思路:

  1. 检查挂载情况

    bash
    # 查看容器挂载信息
    docker inspect --format '{{.Mounts}}' <container_id>
    
    # 查看容器内目录权限
    docker exec -it <container_id> ls -la /app
    docker exec -it <container_id> id
  2. 检查宿主机目录权限

    bash
    # 查看宿主机目录权限
    ls -la /data
    ls -ld /data
    
    # 检查 SELinux 状态
    getenforce
  3. 常见权限问题

    bash
    # 检查是否是 SELinux 问题
    ls -Z /data
    docker exec -it <container_id> ls -laZ /app
    
    # 检查 AppArmor 状态
    apparmor_status

解决方案:

bash
# 方案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 0

14. Docker 镜像拉取失败,如何处理?

故障现象:docker pull 报错 "manifest unknown" 或 "connection timeout"。

排查思路:

  1. 确认镜像名称

    bash
    # 检查镜像标签是否正确
    docker images
    docker search <image_name>
    
    # 确认官方镜像路径
    docker pull library/nginx:latest
    docker pull mysql:8.0
  2. 网络问题排查

    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
  3. 登录认证问题

    bash
    # 登录 Docker Hub
    docker login
    
    # 登录私有仓库
    docker login registry.example.com
    
    # 检查认证信息
    cat ~/.docker/config.json
  4. 镜像仓库问题

    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。

排查思路:

  1. 查看 Pod 详情

    bash
    # 查看 Pod 状态和事件
    kubectl describe pod <pod-name> -n <namespace>
    
    # 查看所有 Pod 状态
    kubectl get pod -n <namespace> -o wide
  2. 检查调度相关事件

    bash
    # 查找调度失败原因
    kubectl describe pod <pod-name> | grep -A 10 "Events:"
    
    # 常见关键词:
    # - "No nodes available" → 资源不足
    # - "node(s) had taints" → 节点有污点
    # - "didn't match Pod's node affinity" → 亲和性不匹配
  3. 检查资源配额

    bash
    # 检查命名空间资源配额
    kubectl get resourcequota -n <namespace>
    kubectl describe resourcequota -n <namespace>
    
    # 检查 LimitRange
    kubectl get limitrange -n <namespace>
    kubectl describe limitrange -n <namespace>
  4. 检查节点资源

    bash
    # 查看节点状态
    kubectl get nodes
    
    # 查看节点资源使用
    kubectl describe node <node-name>
    
    # 查看资源不足的节点
    kubectl top nodes
  5. 检查污点和亲和性

    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 启动后立即崩溃,然后反复重启。

排查思路:

  1. 查看容器状态

    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
  2. 进入容器调试

    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
  3. 检查健康检查

    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}]}}'
  4. 检查资源限制

    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}'
  5. 常见错误类型

    bash
    # "Exit code 1" → 应用本身退出
    # "Exit code 137" → OOMKilled (内存超限)
    # "Exit code 143" → 被 SIGTERM 终止
    # "Error" → 启动命令执行失败

解决方案:

bash
# 增加资源限制
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 无法访问。

排查思路:

  1. 确认问题范围

    bash
    # 查看 Service 列表
    kubectl get svc -n <namespace>
    
    # 查看 Service 详情
    kubectl describe svc <service-name> -n <namespace>
    
    # 查看 Service 关联的 Pod
    kubectl get endpoints <service-name> -n <namespace>
  2. 检查 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>
  3. 检查 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>
  4. 检查网络策略

    bash
    # 查看网络策略
    kubectl get networkpolicy -n <namespace>
    kubectl describe networkpolicy <policy-name> -n <namespace>
    
    # 临时禁用网络策略测试
    # kubectl delete networkpolicy <policy-name>
  5. 检查 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
  6. 直接测试连接

    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 状态。

排查思路:

  1. 查看拉取错误

    bash
    kubectl describe pod <pod-name> | grep -A 10 "Events:"
    
    # 常见错误:
    # - "ImagePullBackOff" → 拉取失败
    # - "ErrImageNeverPull" → 策略禁止拉取
    # - "ImagePull error" → 认证失败
  2. 常见错误及解决方案

    镜像名称错误:

    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
  3. 测试手动拉取

    bash
    # 在节点上手动拉取测试
    docker pull <image_name>
    
    # 如果是私有镜像,先登录
    docker login registry.example.com

19. PVC 一直处于 Pending 状态如何排查?

故障现象: Pod 无法启动,PVC 一直处于 Pending。

排查思路:

  1. 查看 PVC 状态

    bash
    kubectl get pvc -n <namespace>
    kubectl describe pvc <pvc-name> -n <namespace>
  2. 检查 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}'
  3. 检查 Provisioner

    bash
    # 查看 StorageClass 的 provisioner
    kubectl get storageclass <storage-class> -o jsonpath='{.provisioner}'
    
    # 检查 provisioner Pod 是否运行
    kubectl get pod -n kube-system | grep -i provisioner
  4. 常见问题及解决方案

    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 无法调度到该节点。

排查思路:

  1. 查看节点状态

    bash
    kubectl get nodes
    kubectl describe node <node-name>
    
    # 查看节点条件
    kubectl get node <node-name> -o jsonpath='{.status.conditions}'
  2. 登录节点检查

    bash
    # SSH 到问题节点
    ssh <node-ip>
    
    # 检查 kubelet 状态
    systemctl status kubelet
    journalctl -u kubelet -n 100
    
    # 检查 kubelet 日志
    journalctl -u kubelet --no-pager -n 200
  3. 检查节点资源

    bash
    # 检查磁盘空间
    df -h
    
    # 检查内存
    free -h
    
    # 检查 CPU
    top
    
    # 检查 inode
    df -i
  4. 检查网络

    bash
    # 检查节点网络
    ip addr
    ip route
    
    # 检查 DNS
    cat /etc/resolv.conf
    
    # 测试 API Server 连通性
    curl -k https://<api-server>:6443/healthz
  5. 常见原因及处理

    kubelet 未启动:

    bash
    systemctl 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 飙升,系统响应变慢。

排查思路:

  1. 确认 load 情况

    bash
    # 查看 load
    uptime
    top
    w
    
    # 查看运行队列
    vmstat 1 5
  2. 找出高负载原因

    bash
    # 查看哪些进程占用 CPU 高
    top -b -n 1 | head -20
    ps aux --sort=-%cpu | head -10
    
    # 查看哪些进程在等待 I/O
    iotop
  3. 如果是 CPU 密集型

    bash
    # 查看进程详情
    top -p $(pgrep -f java)
    
    # 查看线程
    ps -T -p <pid>
    
    # 查看系统调用
    strace -c -p <pid>
  4. 如果是 I/O 密集型

    bash
    # 查看 I/O 统计
    iostat -x 1 5
    
    # 找出大量 I/O 的进程
    iotop -o
  5. 如果是可中断等待

    bash
    # 查看 D 状态进程(不可中断等待)
    ps aux | grep -E " D " | head
    cat /proc/$(pgrep -f java)/wchan

常见原因:

  • 大量计算任务突然启动
  • 磁盘 I/O 过高
  • 内存不足导致 swap
  • 网络 I/O 等待
  • 定时任务同时执行

22. 服务器被入侵了如何处理?

故障现象: 安全扫描发现服务器有异常行为,疑似被入侵。

排查思路:

  1. 隔离服务器

    bash
    # 立即断开网络(防止继续扩散)
    # 在云平台安全组中禁用该服务器的所有出站流量
    # 或使用 iptables 限制
    iptables -I OUTPUT -j DROP
  2. 保留现场

    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
  3. 检查可疑进程

    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
  4. 检查网络连接

    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
  5. 检查启动项和定时任务

    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
  6. 检查可疑文件

    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

后续处理:

bash
# 1. 备份数据(注意:可能已包含恶意代码)
tar -czvf /backup/important-data.tar.gz /data

# 2. 重装系统(强烈建议)
# 3. 从零开始部署
# 4. 恢复数据时仔细检查
# 5. 修改所有相关密码

23. 如何预防和处理循环重启?

故障现象: 服务器进入循环重启,无法正常启动。

排查思路:

  1. 进入救援模式

    bash
    # 在 GRUB 菜单选择 recovery mode
    # 或使用 Live CD 启动
  2. 检查日志

    bash
    # 查看上次启动日志
    journalctl -b -1
    
    # 查看 syslog
    cat /var/log/syslog | tail -100
    
    # 查看 auth.log
    cat /var/log/auth.log | tail -100
  3. 常见原因

    磁盘满导致启动失败:

    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"
    # 选择之前的内核版本
  4. 防止自动重启

    bash
    # 临时禁用自动重启
    sysctl kernel.panic=0
    
    # 修改 GRUB 配置禁用自动重启
    # vim /etc/default/grub
    GRUB_CMDLINE_LINUX_DEFAULT="panic=0"
    update-grub

24. 应用程序假死后如何快速恢复?

故障现象: 应用进程还在,但不再响应请求。

排查思路:

  1. 确认进程状态

    bash
    # 查看进程状态
    ps aux | grep <app_name>
    
    # 查看进程系统调用
    strace -p <pid>
    
    # 查看进程文件描述符
    lsof -p <pid>
  2. 检查线程状态

    bash
    # 查看线程
    ps -T -p <pid>
    
    # 查看线程堆栈
    pstack <pid>
    
    # 使用 gdb 查看 Java 线程
    jstack <pid>
  3. 检查资源占用

    bash
    # 检查内存
    cat /proc/<pid>/status | grep -E "VmRSS|VmPeak"
    
    # 检查打开的文件描述符
    ls /proc/<pid>/fd | wc -l
    
    # 检查网络连接
    cat /proc/<pid>/net/tcp
  4. 常见原因

    • 线程死锁
    • 连接池耗尽
    • 内存泄漏导致 GC 不停
    • 磁盘空间不足无法写日志

快速恢复方案:

bash
# 如果是容器内应用
docker restart <container_id>

# 如果是物理机上的进程
# 1. 先保留现场
kill -STOP <pid>  # 暂停进程
# 2. 导出堆栈等信息
# 3. 重启
kill -TERM <pid>
# 4. 如果无法优雅退出
kill -9 <pid>

故障排查思路总结

快速定位口诀

1. "先问人,后看表" - 确认故障影响范围
2. "先外部,后内部" - 先排除网络/硬件问题
3. "先日志,后代码" - 查看日志再分析代码
4. "先止血,后根治" - 先恢复服务再找原因
5. "先备份,后操作" - 关键操作前先备份

常用排查命令速查

bash
# 系统状态
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

日志位置速查

bash
# 系统日志
/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>