集群故障排除
本文档介绍集群故障排除;我们假设你已排除应用程序是导致你所遇到问题的根本原因。有关应用程序调试的提示,请参阅应用程序故障排除指南。你也可以访问故障排除概述文档以获取更多信息。
有关 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
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:
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
的日志,负责将流量导向服务端点
集群故障模式
这是一份不完整的可能出错的事情列表,以及如何调整集群设置以缓解这些问题。
促成因素
- 虚拟机(VM)关闭
- 集群内部或集群与用户之间的网络分区
- Kubernetes 软件崩溃
- 持久化存储的数据丢失或不可用(例如 GCE PD 或 AWS EBS 卷)
- 操作员错误,例如,Kubernetes 软件或应用程序软件配置错误
特定场景
- API 服务器 VM 关闭或 apiserver 崩溃
- 结果
- 无法停止、更新或启动新的 Pod、Service、Replication Controller
- 现有的 Pod 和 Service 应继续正常工作,除非它们依赖于 Kubernetes API
- 结果
- API 服务器后端存储丢失
- 结果
- kube-apiserver 组件无法成功启动并变得健康
- kubelet 将无法访问它,但将继续运行相同的 Pod 并提供相同的服务代理
- 在 apiserver 重新启动之前需要手动恢复或重新创建 apiserver 状态
- 结果
- 支持服务(节点控制器、复制控制器管理器、调度器等)VM 关闭或崩溃
- 目前这些服务与 apiserver 共存,它们的不可用性与 apiserver 类似
- 将来,这些也将被复制,并且可能不会共存
- 它们没有自己的持久状态
- 单个节点(VM 或物理机)关闭
- 结果
- 该节点上的 Pod 停止运行
- 结果
- 网络分区
- 结果
- 分区 A 认为分区 B 中的节点已宕机;分区 B 认为 apiserver 已宕机。(假设主节点 VM 最终在分区 A 中。)
- 结果
- Kubelet 软件故障
- 结果
- 崩溃的 kubelet 无法在节点上启动新的 Pod
- kubelet 可能会或可能不会删除 Pod
- 节点被标记为不健康
- Replication Controller 在其他地方启动新的 Pod
- 结果
- 集群操作员错误
- 结果
- Pod、Service 等丢失
- apiserver 后端存储丢失
- 用户无法读取 API
- 等等。
- 结果
缓解措施
行动:对于 IaaS 虚拟机,使用 IaaS 提供商的自动虚拟机重启功能
- 缓解:Apiserver VM 关闭或 apiserver 崩溃
- 缓解:支持服务 VM 关闭或崩溃
行动:对于带有 apiserver+etcd 的 VM,使用 IaaS 提供商的可靠存储(例如 GCE PD 或 AWS EBS 卷)
- 缓解:API 服务器后端存储丢失
行动:使用高可用性配置
- 缓解:控制平面节点关闭或控制平面组件(调度器、API 服务器、控制器管理器)崩溃
- 将容忍一个或多个同时发生的节点或组件故障
- 缓解:API 服务器后端存储(即 etcd 的数据目录)丢失
- 假设采用高可用性(HA)etcd 配置
- 缓解:控制平面节点关闭或控制平面组件(调度器、API 服务器、控制器管理器)崩溃
行动:定期快照 apiserver PD/EBS 卷
- 缓解:API 服务器后端存储丢失
- 缓解:某些操作员错误情况
- 缓解:某些 Kubernetes 软件故障情况
行动:在 Pod 之前使用 Replication Controller 和 Service
- 缓解:节点关闭
- 缓解:Kubelet 软件故障
行动:设计应用程序(容器)以容忍意外重启
- 缓解:节点关闭
- 缓解:Kubelet 软件故障
下一步
- 了解资源指标管道中可用的指标
- 发现用于监控资源使用情况的其他工具
- 使用 Node Problem Detector 监控节点健康状况
- 使用
kubectl debug node
调试 Kubernetes 节点 - 使用
crictl
调试 Kubernetes 节点 - 获取有关Kubernetes 审计的更多信息
- 使用
telepresence
在本地开发和调试服务