Kubernetes故障排查实战手册

Kubernetes故障排查实战手册

本文档适用于生产环境下Kubernetes集群常见故障的排查与优化,涵盖APIServer接口延时、etcd性能、Token失效、cacher超时、资源竞争等典型问题。建议结合实际监控与日志,按步骤定位和解决。 持续更新ing


1. APIServer接口请求延时排查

1.1 现象

  • kubectl、API调用响应慢,监控显示apiserver延时高。
  • 日志中出现 Listing from storage done xxxms,耗时较高。

1.2 排查步骤

  1. 查看apiserver trace日志
    1
    
    grep "Listing from storage done" /var/log/kube-apiserver.log | sort -k6 -n | tail -20
  2. 分析慢点
    • 如果大部分耗时集中在Listing from storage done,说明etcd存储阶段慢。
    • 关注total time,如大于300ms需重点关注。
  3. 结合Prometheus监控
    • 关注apiserver_request_duration_secondsetcd_request_duration_seconds等指标。
    • 示例PromQL:
      1
      
      histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket[5m])) by (le, verb, resource))

1.3 日志示例

1
2
3
I0625 16:09:02.406986    6468 trace.go:205] Trace[816016811]: "List" url:/api/v1/pods,user-agent:kubectl/v1.20.10,client:127.0.0.1 (25-Jun-2025 16:09:01.186) (total time: 1220ms):
Trace[816016811]: ---"Listing from storage done" 1220ms (16:09:00.406)
Trace[816016811]: [1.220921602s] [1.220921602s] END

2. etcd性能与健康排查

2.1 现象

  • apiserver与etcd连接频繁切换,日志中有transport is closing
  • etcd响应慢,apiserver接口延时高。

2.2 排查步骤

  1. 检查etcd健康
    1
    2
    
    ETCDCTL_API=3 etcdctl --endpoints=<etcd-endpoints> endpoint health
    ETCDCTL_API=3 etcdctl --endpoints=<etcd-endpoints> endpoint status --write-out=table
  2. 检查etcd资源
    • 重点关注磁盘IO、延迟、CPU、内存。
    • 检查etcd节点是否与apiserver共用宿主机和磁盘(不推荐)。
  3. 查看etcd慢日志
    • 检查etcd日志中snapshotapplyfsync等关键字。

2.3 日志示例

1
2
3
4
5
6
I0625 16:09:09.842736   60187 client.go:360] parsed scheme: "passthrough"
I0625 16:09:09.842757   60187 passthrough.go:48] ccResolverWrapper: sending update to cc: {[{https://<etcd-x>.com:2379  <nil> 0 <nil>}] <nil> <nil>}
I0625 16:09:09.842764   60187 clientconn.go:948] ClientConn switching balancer to "pick_first"
I0625 16:09:09.842858   60187 balancer_conn_wrappers.go:78] pickfirstBalancer: HandleSubConnStateChange: ..., {CONNECTING <nil>}
I0625 16:09:09.847558   60187 balancer_conn_wrappers.go:78] pickfirstBalancer: HandleSubConnStateChange: ..., {READY <nil>}
I0625 16:09:09.848203   60187 controlbuf.go:508] transport: loopyWriter.run returning. connection error: desc = "transport is closing"

3. Token失效与认证失败

3.1 现象

  • 日志中出现Unable to authenticate the request due to an error: [invalid bearer token, Token has been invalidated]
  • 业务组件、kubectl等频繁认证失败。

3.2 排查步骤

  1. 检查token是否过期或被撤销
  2. 检查kubeconfig配置,确保使用最新token。
  3. 如为ServiceAccount,尝试重建secret并分发。

3.3 日志示例

1
E0625 18:10:07.332983   60187 authentication.go:53] Unable to authenticate the request due to an error: [invalid bearer token, Token has been invalidated]

4. cacher超时与watcher异常

4.1 现象

  • 日志中出现Forcing watcher close due to unresponsiveness
  • 业务组件watch接口断流、重连频繁。

4.2 排查步骤

  1. 检查下游watcher处理能力,如自定义controller、kubectl watch等。
  2. 检查apiserver资源利用率,如CPU、内存、磁盘。
  3. 关注网络链路是否异常。

4.3 日志示例

1
I0625 18:10:25.677715   60187 cacher.go:1238] Forcing watcher close due to unresponsiveness: *unstructured.Unstructured

5. 资源竞争与部署建议

5.1 现象

  • apiserver与etcd共用宿主机和磁盘,性能互相影响。
  • etcd写入延迟高,apiserver接口延时高。

5.2 优化建议

  • 物理隔离:apiserver与etcd分开部署,etcd独享高性能SSD。
  • 磁盘隔离:如必须同机,保证etcd使用独立物理磁盘。
  • 资源限制:通过cgroup、systemd、K8s requests/limits限制资源。
  • 监控与告警:重点监控磁盘延迟、IOPS、etcd fsync延迟等。

6. 常用排查命令与工具

  • 查看apiserver慢请求:
    1
    
    grep "Listing from storage done" /var/log/kube-apiserver.log | sort -k6 -n | tail -20
  • 检查etcd健康:
    1
    
    ETCDCTL_API=3 etcdctl --endpoints=<etcd-endpoints> endpoint health
  • 检查etcd慢日志:
    1
    
    grep slow /var/log/etcd.log
  • 查看apiserver、etcd资源:
    1
    
    top, iostat, vmstat, sar 等
  • Prometheus监控指标:
    • apiserver_request_duration_seconds
    • etcd_request_duration_seconds

7. 优化建议与最佳实践

  • apiserver与etcd物理隔离,etcd独享SSD。
  • 定期检查token有效性,及时轮换。
  • 监控慢请求,及时扩容或优化。
  • 业务watcher合理限流,避免拖垮apiserver。
  • 生产环境建议etcd节点奇数、独立部署、定期备份。

8. etcd快照备份导致的性能问题排查与优化

8.1 现象

  • etcd集群在整点或固定时间段出现请求延时高峰,表现为apiserver接口响应变慢,监控中etcd相关请求延时(如etcd_request_duration_seconds_bucket)突增。
  • 业务组件、Kubernetes控制面等依赖etcd的操作在高峰时段出现卡顿。
  • etcd磁盘写入延时(fsync/commit)指标正常,但整体请求处理延时大。

8.2 排查步骤

  1. 监控分析
    • 通过Prometheus等监控系统,重点关注etcd_request_duration_seconds_bucket,按instance、type维度分析延时高的节点和操作类型。
    • 观察延时高峰是否有明显的时间规律(如整点),结合业务和系统定时任务排查。
  2. 定时任务排查
    • 检查etcd节点本地crontab、Kubernetes CronJob、外部自动化脚本等,确认是否有定时执行etcd快照(snapshot)备份任务。
    • 常见备份命令示例:
      1
      
      etcdctl snapshot save /backup/etcd-$(date +%Y%m%d%H%M%S).db
  3. etcd慢日志分析
    • 启用etcd慢日志(如--experimental-warning-apply-duration=500ms),在高峰时段查看慢日志,定位慢请求内容和来源,3.6版本引入的实验性特性。
    • 日志关键字:snapshot savetook too long
  4. 节点角色与备份影响分析
    • 通过etcdctl endpoint status或监控etcd_server_is_leader,识别leader和follower节点,分析备份任务对不同节点的影响。

8.3 日志与监控分析示例

  • 监控中etcd请求延时在整点出现规律性高峰: etcd延时高峰示意图
  • etcd慢日志示例:
    1
    2
    
    apply request took too long [1200.123ms] to execute
    snapshot save /backup/etcd-20240626100000.db
  • Prometheus查询示例:
    1
    
    histogram_quantile(0.99, sum(rate(etcd_request_duration_seconds_bucket[5m])) by (le, instance, type))

8.4 优化建议

  1. 备份节点选择
    • 优先在follower节点执行快照,避免影响leader写入性能。
    • 备份前自动判断节点角色,仅在follower上执行snapshot save
  2. 备份方式优化
    • 可将本地crontab备份调整为Kubernetes CronJob远程备份,减少etcd节点本地IO压力,但需关注网络带宽消耗和安全性。
  3. 备份限速
    • 使用ionicenice降低备份进程的IO和CPU优先级:
      1
      
      ionice -c2 -n7 nice -n 19 etcdctl snapshot save ...
    • 使用pvtrickle等工具限制备份速率:
      1
      
      etcdctl snapshot save /dev/stdout | pv -L 10m > /backup/etcd.db
  4. 错峰与频率调整
    • 多节点集群备份任务错开时间,避免同时高IO。
    • 合理设置备份频率,避免过于频繁。
  5. 备份存储优化
    • 备份文件优先存储到独立磁盘或远程存储,避免与etcd数据盘争抢IO。
    • 备份后异步上传到对象存储,定期清理本地旧快照。
  6. 监控与告警
    • 备份期间重点监控etcd延时、QPS、磁盘IO、网络带宽等指标。
    • 设置延时、磁盘空间等告警,及时发现异常。
  7. 安全与一致性
    • 远程备份需做好etcd访问权限和证书管理,防止泄露。
    • 备份完成后校验快照文件完整性。

9. Lease租约更新失败排查与解决

9.1 现象

  • 日志中出现Failed to update lease错误,提示the object has been modified; please apply your changes to the latest version and try again
  • API服务器或控制器组件出现租约竞争冲突
  • 集群中可能出现多个组件同时尝试更新同一个lease对象

9.2 错误分析

这个错误通常发生在Kubernetes的租约(lease)机制中,常见于:

  • API服务器高可用场景:多个API服务器实例竞争同一个lease
  • 控制器管理器:多个controller-manager实例的leader选举
  • 调度器:多个scheduler实例的leader选举
  • 自定义控制器:实现了leader选举的自定义组件

错误信息the object has been modified; please apply your changes to the latest version and try again表明存在并发修改冲突,即当前组件尝试更新lease时,该lease对象已被其他组件修改。

9.3 排查步骤

  1. 确认lease对象状态

    1
    2
    3
    4
    5
    6
    7
    8
    
    # 查看所有lease对象
    kubectl get leases -A
    
    # 查看特定lease详情
    kubectl describe lease <lease-name> -n <namespace>
    
    # 查看coordination.k8s.io API组下的lease
    kubectl get leases.coordination.k8s.io -A
  2. 检查竞争组件

    1
    2
    3
    4
    5
    6
    7
    8
    
    # 检查API服务器实例
    kubectl get pods -n kube-system | grep apiserver
    
    # 检查控制器管理器
    kubectl get pods -n kube-system | grep controller-manager
    
    # 检查调度器
    kubectl get pods -n kube-system | grep scheduler
  3. 分析lease持有者

    1
    2
    
    # 查看lease的holder信息
    kubectl get lease <lease-name> -n <namespace> -o yaml
  4. 检查组件日志

    1
    2
    3
    4
    5
    
    # 查看相关组件的详细日志
    kubectl logs -n kube-system <pod-name> | grep -i lease
    
    # 查看最近的lease相关错误
    kubectl logs -n kube-system <pod-name> | grep "Failed to update lease"

9.4 解决方案

9.4.1 临时解决方案

  1. 重启竞争组件

    1
    2
    
    # 重启相关的Pod(以controller-manager为例)
    kubectl delete pod -n kube-system <controller-manager-pod-name>
  2. 清理异常lease

    1
    2
    
    # 删除异常的lease对象(谨慎操作)
    kubectl delete lease <lease-name> -n <namespace>

9.4.2 根本解决方案

  1. 检查组件配置

    • 确认是否有多个相同组件实例配置了相同的lease名称
    • 检查--leader-elect-lease-duration--leader-elect-renew-deadline参数配置
  2. 优化lease参数

    1
    2
    3
    4
    5
    
    # 在组件配置中调整lease参数
    --leader-elect=true
    --leader-elect-lease-duration=15s
    --leader-elect-renew-deadline=10s
    --leader-elect-retry-period=2s
  3. 网络和时钟同步检查

    1
    2
    3
    4
    5
    
    # 检查节点间时钟同步
    chrony sources -v
    
    # 检查网络延迟
    ping <other-master-nodes>

9.5 预防措施

  1. 合理配置lease参数

    • lease-duration: 租约持有时间,建议15-30秒
    • renew-deadline: 续约截止时间,建议为lease-duration的2/3
    • retry-period: 重试间隔,建议2-5秒
  2. 监控lease健康状态

    1
    2
    
    # Prometheus监控lease更新失败
    increase(apiserver_audit_total{verb="update",objectRef_resource="leases",verb="update",code!~"2.."}[5m])
  3. 集群时钟同步

    • 确保所有master节点时钟同步
    • 使用NTP或chrony服务
  4. 网络稳定性

    • 确保master节点间网络稳定
    • 避免网络分区导致的lease竞争

9.6 日志示例

1
E0717 18:10:58.214426       1 controller.go:195] "Failed to update lease" err="Operation cannot be fulfilled on leases.coordination.k8s.io \"apiserver-ejk5u55e7knw3kwxkvlwjo2ole\": the object has been modified; please apply your changes to the latest version and try again"

9.7 相关监控指标

  • apiserver_audit_total: API审计日志,可监控lease操作
  • leader_election_master_status: leader选举状态
  • process_start_time_seconds: 组件启动时间,用于判断重启

0%