集群故障排除
本文档介绍的是集群故障排除;我们假设您已排除了应用程序作为您遇到的问题的根本原因。有关应用程序调试的技巧,请参阅 应用程序故障排除指南。您也可以访问 故障排除概述文档 了解更多信息。
要排除 kubectl 的故障,请参阅 排查 kubectl 故障。
列出您的集群
集群调试的第一件事是检查您的节点是否都已正确注册。
运行以下命令
kubectl get nodes
并验证您期望看到的所有节点都存在,并且它们都处于 Ready
状态。
要获取有关集群整体运行状况的详细信息,您可以运行
kubectl cluster-info dump
示例:调试关闭/不可达的节点
有时在调试时查看节点状态会很有用,例如,因为您注意到运行在节点上的 Pod 的奇怪行为,或者为了找出为什么 Pod 不会调度到该节点。与 Pod 一样,您可以使用 kubectl describe node
和 kubectl get node -o yaml
来检索有关节点的详细信息。例如,以下是当节点关闭时(与网络断开连接,或者 kubelet 死亡且不会重启等)您将看到的内容。请注意,显示节点处于 NotReady 状态的事件,以及注意 Pod 不再运行(它们在处于 NotReady 状态五分钟后被逐出)。
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-worker-1 NotReady <none> 1h v1.23.3
kubernetes-node-bols Ready <none> 1h v1.23.3
kubernetes-node-st6x Ready <none> 1h v1.23.3
kubernetes-node-unaj Ready <none> 1h v1.23.3
kubectl describe node kube-worker-1
Name: kube-worker-1
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=kube-worker-1
kubernetes.io/os=linux
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /run/containerd/containerd.sock
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 17 Feb 2022 16:46:30 -0500
Taints: node.kubernetes.io/unreachable:NoExecute
node.kubernetes.io/unreachable:NoSchedule
Unschedulable: false
Lease:
HolderIdentity: kube-worker-1
AcquireTime: <unset>
RenewTime: Thu, 17 Feb 2022 17:13:09 -0500
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Thu, 17 Feb 2022 17:09:13 -0500 Thu, 17 Feb 2022 17:09:13 -0500 WeaveIsUp Weave pod has set this
MemoryPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
DiskPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
PIDPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
Ready Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
Addresses:
InternalIP: 192.168.0.113
Hostname: kube-worker-1
Capacity:
cpu: 2
ephemeral-storage: 15372232Ki
hugepages-2Mi: 0
memory: 2025188Ki
pods: 110
Allocatable:
cpu: 2
ephemeral-storage: 14167048988
hugepages-2Mi: 0
memory: 1922788Ki
pods: 110
System Info:
Machine ID: 9384e2927f544209b5d7b67474bbf92b
System UUID: aa829ca9-73d7-064d-9019-df07404ad448
Boot ID: 5a295a03-aaca-4340-af20-1327fa5dab5c
Kernel Version: 5.13.0-28-generic
OS Image: Ubuntu 21.10
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.5.9
Kubelet Version: v1.23.3
Kube-Proxy Version: v1.23.3
Non-terminated Pods: (4 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx-deployment-67d4bdd6f5-cx2nz 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
default nginx-deployment-67d4bdd6f5-w6kd7 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
kube-system kube-proxy-dnxbz 0 (0%) 0 (0%) 0 (0%) 0 (0%) 28m
kube-system weave-net-gjxxp 100m (5%) 0 (0%) 200Mi (10%) 0 (0%) 28m
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1100m (55%) 1 (50%)
memory 456Mi (24%) 256Mi (13%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events:
...
kubectl get node kube-worker-1 -o yaml
apiVersion: v1
kind: Node
metadata:
annotations:
kubeadm.alpha.kubernetes.io/cri-socket: /run/containerd/containerd.sock
node.alpha.kubernetes.io/ttl: "0"
volumes.kubernetes.io/controller-managed-attach-detach: "true"
creationTimestamp: "2022-02-17T21:46:30Z"
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/arch: amd64
kubernetes.io/hostname: kube-worker-1
kubernetes.io/os: linux
name: kube-worker-1
resourceVersion: "4026"
uid: 98efe7cb-2978-4a0b-842a-1a7bf12c05f8
spec: {}
status:
addresses:
- address: 192.168.0.113
type: InternalIP
- address: kube-worker-1
type: Hostname
allocatable:
cpu: "2"
ephemeral-storage: "14167048988"
hugepages-2Mi: "0"
memory: 1922788Ki
pods: "110"
capacity:
cpu: "2"
ephemeral-storage: 15372232Ki
hugepages-2Mi: "0"
memory: 2025188Ki
pods: "110"
conditions:
- lastHeartbeatTime: "2022-02-17T22:20:32Z"
lastTransitionTime: "2022-02-17T22:20:32Z"
message: Weave pod has set this
reason: WeaveIsUp
status: "False"
type: NetworkUnavailable
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has sufficient memory available
reason: KubeletHasSufficientMemory
status: "False"
type: MemoryPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has no disk pressure
reason: KubeletHasNoDiskPressure
status: "False"
type: DiskPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has sufficient PID available
reason: KubeletHasSufficientPID
status: "False"
type: PIDPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:15:15Z"
message: kubelet is posting ready status
reason: KubeletReady
status: "True"
type: Ready
daemonEndpoints:
kubeletEndpoint:
Port: 10250
nodeInfo:
architecture: amd64
bootID: 22333234-7a6b-44d4-9ce1-67e31dc7e369
containerRuntimeVersion: containerd://1.5.9
kernelVersion: 5.13.0-28-generic
kubeProxyVersion: v1.23.3
kubeletVersion: v1.23.3
machineID: 9384e2927f544209b5d7b67474bbf92b
operatingSystem: linux
osImage: Ubuntu 21.10
systemUUID: aa829ca9-73d7-064d-9019-df07404ad448
查看日志
目前,更深入地挖掘集群需要登录到相关机器。以下是相关日志文件的位置。在基于 systemd 的系统上,您可能需要使用 journalctl
而不是检查日志文件。
控制平面节点
/var/log/kube-apiserver.log
- API 服务器,负责提供 API/var/log/kube-scheduler.log
- 调度程序,负责做出调度决策/var/log/kube-controller-manager.log
- 运行大多数 Kubernetes 内置 控制器 的组件,调度(kube-scheduler 处理调度)是一个值得注意的例外。
工作节点
/var/log/kubelet.log
- 来自 kubelet 的日志,负责在节点上运行容器/var/log/kube-proxy.log
- 来自kube-proxy
的日志,kube-proxy
负责将流量定向到服务端点
集群故障模式
以下是一些可能出现的问题以及如何调整您的集群设置以减轻这些问题的列表。
导致因素
- VM(s) 关闭
- 集群内或集群与用户之间的网络分区
- Kubernetes 软件崩溃
- 持久性存储的数据丢失或不可用(例如 GCE PD 或 AWS EBS 卷)
- 操作员错误,例如,Kubernetes 软件或应用程序软件配置错误
特定场景
- API 服务器 VM 关闭或 API 服务器崩溃
- 结果
- 无法停止、更新或启动新的 Pod、服务、复制控制器
- 现有 Pod 和服务应继续正常工作,除非它们依赖于 Kubernetes API
- 结果
- API 服务器备份存储丢失
- 结果
- kube-apiserver 组件无法成功启动并变为健康状态
- kubelet 将无法访问它,但将继续运行相同的 Pod 并提供相同服务代理
- 在重新启动 API 服务器之前,需要手动恢复或重新创建 API 服务器状态
- 结果
- 支持服务(节点控制器、复制控制器管理器、调度程序等)VM 关闭或崩溃
- 目前,这些与 API 服务器位于同一位置,它们的不可用与 API 服务器的不可用具有相似的后果
- 将来,这些也会被复制,并且可能不会位于同一位置
- 它们没有自己的持久状态
- 单个节点(VM 或物理机)关闭
- 结果
- 该节点上的 Pod 停止运行
- 结果
- 网络分区
- 结果
- 分区 A 认为分区 B 中的节点已关闭;分区 B 认为 API 服务器已关闭。(假设主 VM 最终位于分区 A 中。)
- 结果
- Kubelet 软件故障
- 结果
- 崩溃的 kubelet 无法在节点上启动新的 Pod
- kubelet 可能会删除 Pod 或不删除
- 节点标记为不健康
- 复制控制器在其他地方启动新的 Pod
- 结果
- 集群操作员错误
- 结果
- Pod、服务等丢失
- API 服务器备份存储丢失
- 用户无法读取 API
- 等等。
- 结果
缓解措施
操作:对 IaaS VM 使用 IaaS 提供商的自动 VM 重新启动功能
- 缓解:API 服务器 VM 关闭或 API 服务器崩溃
- 缓解:支持服务 VM 关闭或崩溃
操作:对具有 apiserver+etcd 的 VM 使用 IaaS 提供商的可靠存储(例如 GCE PD 或 AWS EBS 卷)
- 缓解:API 服务器备份存储丢失
操作:使用 高可用性 配置
- 缓解:控制平面节点关闭或控制平面组件(调度程序、API 服务器、控制器管理器)崩溃
- 将容忍一个或多个同时发生的节点或组件故障
- 缓解:API 服务器备份存储(即 etcd 的数据目录)丢失
- 假设 HA(高可用性)etcd 配置
- 缓解:控制平面节点关闭或控制平面组件(调度程序、API 服务器、控制器管理器)崩溃
操作:定期快照 API 服务器 PD/EBS 卷
- 缓解:API 服务器备份存储丢失
- 缓解:某些操作员错误情况
- 缓解:某些 Kubernetes 软件故障情况
操作:在 Pod 前面使用复制控制器和服务
- 缓解:节点关闭
- 缓解:Kubelet 软件故障
操作:设计为容忍意外重启的应用程序(容器)
- 缓解:节点关闭
- 缓解:Kubelet 软件故障
下一步
- 了解 资源指标管道 中可用的指标
- 发现用于 监控资源使用情况 的其他工具
- 使用节点问题检测器来 监控节点运行状况
- 使用
kubectl debug node
来 调试 Kubernetes 节点 - 使用
crictl
来 调试 Kubernetes 节点 - 获取有关 Kubernetes 审计 的更多信息
- 使用
telepresence
来 在本地开发和调试服务