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