mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
501 字
1 分钟
Kubernetes 故障排查与性能优化
2024-03-24

一、Pod 调度问题#

1.1 常见调度失败原因#

graph TB subgraph "调度失败原因" A["资源不足"] --> E["Pending Pod"] B["亲和性/反亲和性"] --> E C["污点未容忍"] --> E D["拓扑约束"] --> E end
问题现象解决方法
资源不足Pod 一直 Pending扩容节点或减少请求
亲和性冲突Pod 一直 Pending调整亲和性规则
污点不匹配Pod 一直 Pending添加容忍
拓扑分布约束Pod 一直 Pending调整拓扑策略

1.2 调度问题排查#

# 查看 Pod 调度状态
kubectl describe pod <pod-name> | grep -A 10 "Events:"
# 常见事件解读
# FailedScheduling: 调度失败
# NetworkNotReady: 网络未就绪
# FailedMount: 挂载失败
# 查看调度器日志
journalctl -u kube-scheduler -n 100
# 模拟调度
kubectl debug node/<node-name> -it --image=busybox

1.3 资源调度策略#

# 优先级调度
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 100000
globalDefault: false
description: "高优先级任务"
---
apiVersion: v1
kind: Pod
metadata:
name: high-priority-app
spec:
priorityClassName: high-priority
containers:
- name: app
image: my-app

二、网络问题排查#

2.1 网络诊断流程#

graph LR A["Pod 内"] --> B["Service"] B --> C["外部"] B --> D["Endpoints 检查"] B --> E["DNS 解析"] C --> F["NetworkPolicy"]
# 1. 进入 Pod 网络空间
kubectl exec -it <pod-name> -- sh
# 2. 检查网络接口
ip addr
ip route
# 3. 测试连通性
ping <target-ip>
curl -v <service-name>
# 4. 检查 DNS 解析
nslookup <service-name>
cat /etc/resolv.conf
# 5. 检查 iptables 规则
iptables -L -n -t nat | grep <service-name>

2.2 Service 问题#

# 检查 Endpoints
kubectl get endpoints <service-name>
# 检查 Selector 匹配的 Pod
kubectl get pods -l app=<selector> --show-labels
# 查看 Service 详细信息
kubectl describe svc <service-name>
# 测试 Service 连通性
kubectl run curl --image=curlimages/curl -it --rm -- \
curl -v http://<service-name>:<port>

2.3 NetworkPolicy 问题#

# 检查 NetworkPolicy 状态
kubectl get networkpolicy
# 查看策略详情
kubectl describe networkpolicy <policy-name>
# 测试策略是否生效
kubectl exec -it frontend -- sh
# 在 frontend Pod 内测试到 backend 的连接
curl -v http://backend:80
# 如果连接失败,检查策略是否正确

三、存储问题排查#

3.1 PVC 问题#

# 查看 PVC 状态
kubectl get pvc
# 查看 PVC 详情
kubectl describe pvc <pvc-name>
# 常见问题
# Pending: StorageClass 不存在或 PV 不足
# Lost: PV 被意外删除
# Bound: PVC 已绑定但 Pod 无法挂载

3.2 存储类问题#

# 查看 StorageClass
kubectl get storageclass
# 查看 PV
kubectl get pv
# 检查 CSI 驱动状态
kubectl get csidriver
# 查看 CSI 日志
kubectl logs -n kube-system -l app=csi-driver

四、性能分析#

4.1 资源分析#

# 查看资源使用 TOP
kubectl top nodes
kubectl top pods
# 按命名空间查看
kubectl top pods -n <namespace>
# 查看详细资源分配
kubectl describe node <node-name> | grep -A 10 "Allocated resources"

4.2 性能瓶颈定位#

graph TB subgraph "性能瓶颈" A["CPU 瓶颈"] --> D["应用层"] B["内存瓶颈"] --> D C["I/O 瓶颈"] --> D D --> E["网络延迟"] end
瓶颈类型指标优化方向
CPUcpu throttling增加 CPU 限制/请求
内存OOMKilled增加内存限制/请求
I/Odisk latency使用 SSD/本地存储
网络packet drops优化网络策略

4.3 调度优化#

# 资源请求与限制优化
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m" # 限制不能过高
memory: "2Gi"
---
apiVersion: v1
kind: Pod
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: "node-type"
operator: In
values:
- "compute-optimized"

五、应用层调试#

5.1 调试工具 Pod#

# 部署调试工具
kubectl run debug --image=busybox --rm -it -- sh
# 使用 nicolaka/netshoot
kubectl run netshoot --rm -it --image=nicolaka/netshoot -- bash
# 常用诊断命令
ip link # 网络接口
ip addr # IP 地址
ss -tulpn # 端口监听
conntrack -L # 连接跟踪
tcpdump # 抓包

5.2 性能剖析#

# 进入 Pod 进行 profiling
kubectl exec -it <pod-name> -- sh
# Go 应用性能剖析
# 1. 获取 profile
curl http://localhost:6060/debug/pprof/profile
# 2. 查看 goroutine
curl http://localhost:6060/debug/pprof/goroutine?debug=1
# Java 应用
jstack <pid> # 线程堆栈
jmap -heap <pid> # 内存映射

六、常见故障案例#

6.1 Case 1: Pod 无法调度#

# 问题:Pod 一直 Pending
kubectl describe pod my-app
# 输出:
# Events:
# Type Reason Age From Message
# ---- ------ ---- ---- -------
# 分析:节点资源不足或存在污点
# 解决:
# 1. 检查污点
kubectl get nodes -o json | jq '.items[].spec.taints'
# 2. 添加容忍
kubectl taint node <node> dedicated=special-user:NoSchedule-

6.2 Case 2: Service 无法访问#

# 问题:Service 无法连接
kubectl exec -it frontend -- curl backend:80
# 错误:curl: (7) Failed to connect to backend port 80: Connection timed out
# 排查步骤:
# 1. 检查 Endpoints
kubectl get endpoints backend
# 如果为空,说明没有 Pod 匹配 Selector
# 2. 检查 Pod 标签
kubectl get pods -l app=backend --show-labels
# 3. 检查网络策略
kubectl get networkpolicy

6.3 Case 3: Pod 被 OOMKilled#

# 问题:Pod 不断重启
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# my-app 0/1 OOMKilled 3 10m
# 排查内存使用
kubectl top pod my-app
# 分析:
# 可能是内存限制设置过低或应用内存泄漏
# 解决:
# 1. 临时增加内存限制
kubectl patch pod my-app -p '{"spec":{"containers":[{"name":"app","resources":{"limits":{"memory":"2Gi"}}}]}}'
# 2. 长期:优化应用或调整资源配额

七、故障排查与监控联动#

7.1 监控辅助诊断#

故障排查离不开完善的监控体系。通过 Prometheus 指标可以快速定位问题根源:

graph LR A["故障现象"] --> B["Prometheus 指标"] B --> C["Grafana Dashboard"] C --> D["问题定位"] D --> E["告警规则"] E --> F["快速响应"]

关键监控指标

故障类型关键指标排查方向
调度失败kube_pod_status_pending资源、污点、亲和性
OOMKilledcontainer_memory_working_set_bytes内存限制、泄漏
网络不通container_network_receive_bytesNetworkPolicy
存储问题kube_persistentvolumeclaim_statusStorageClass

提示:完整的监控配置和告警规则请参考 Kubernetes 监控与可观测性

八、总结#

graph TB A["故障排查"] --> B["Pod 问题"] A --> C["网络问题"] A --> D["存储问题"] A --> E["性能问题"] B --> B1["Pending"] B --> B2["CrashLoopBackOff"] B --> B3["OOMKilled"] C --> C1["连通性"] C --> C2["DNS 解析"] C --> C3["策略阻止"] D --> D1["挂载失败"] D --> D2["PVC 问题"] E --> E1["资源瓶颈"] E --> E2["调度延迟"] A --> F["监控联动"] F --> G["Prometheus"] F --> H["Grafana"] F --> I["告警体系"]

故障排查最佳实践

  1. 从症状到原因:先定位现象,再分析原因
  2. 从外部到内部:先检查网络/依赖,再检查应用
  3. 从基础设施到应用:先检查 K8s 组件,再检查业务 Pod
  4. 利用日志和事件:K8s 事件和 Pod 日志是主要线索
  5. 善用调试工具:netshoot、kubectl debug 等

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

Kubernetes 故障排查与性能优化
https://blog.souloss.com/posts/kubernetes/k8s-troubleshooting/
作者
Souloss
发布于
2024-03-24
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时