排查集群故障

调试常见的集群问题。

本文档介绍了集群故障排除;我们假设您已经排除了应用程序作为您遇到的问题的根本原因。有关应用程序调试的提示,请参阅 应用程序故障排除指南。您也可以访问 故障排除概述文档 以了解更多信息。

有关故障排除 kubectl,请参阅 kubectl 故障排除

列出您的集群

在您的集群中调试的第一件事是检查您的节点是否都已正确注册。

运行以下命令

kubectl get nodes

并验证您期望看到的所有节点都存在,并且它们都处于 Ready 状态。

要获取有关集群整体运行状况的详细信息,您可以运行

kubectl cluster-info dump

示例:调试停机/不可达节点

有时在调试时,查看节点的状态可能很有用——例如,因为您注意到在节点上运行的 Pod 的奇怪行为,或者要找出为什么 Pod 不会调度到该节点。与 Pod 一样,您可以使用 kubectl describe nodekubectl 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 的日志,它负责将流量定向到服务端点

集群故障模式

这是一个不完整的列表,列出了可能出现的问题以及如何调整您的集群设置以减轻这些问题。

导致原因

  • 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 关闭或崩溃
  • 操作:对具有 API 服务器+etcd 的 VM 使用 IaaS 提供商的可靠存储(例如 GCE PD 或 AWS EBS 卷)

    • 缓解:API 服务器备份存储丢失
  • 操作:使用 高可用性 配置

    • 缓解:控制平面节点关闭或控制平面组件(调度程序、API 服务器、控制器管理器)崩溃
      • 将容忍一个或多个同时发生的节点或组件故障
    • 缓解:API 服务器备份存储(即 etcd 的数据目录)丢失
      • 假设 HA(高可用性)etcd 配置
  • 操作:定期快照 API 服务器 PD/EBS 卷

    • 缓解:API 服务器备份存储丢失
    • 缓解:某些操作员错误情况
    • 缓解:某些 Kubernetes 软件故障情况
  • 操作:在 Pod 前面使用复制控制器和服务

    • 缓解:节点关闭
    • 缓解:Kubelet 软件故障
  • 操作:应用程序(容器)设计为容忍意外重启

    • 缓解:节点关闭
    • 缓解:Kubelet 软件故障

下一步

上次修改时间:2024 年 3 月 7 日下午 4:54 PST:AppArmor v1.30 文档更新 (4f11f83a45)