Kubernetes 中的“Not Ready”错误表示 Kubernetes 集群中的节点处于一个非健康状态,无法接受 pod 执行。此状态对于集群管理员来说是一个至关重要的指标,因为它表明 Kubernetes 调度程序不会将新的 pod 分配给受影响的节点,直到它返回到ready状态。
运行以下 kubectl 命令检查是否有任何节点遇到“Not Reay”错误:
kubectl get nodes
此输出将列出集群中的所有节点及其状态。例如,在以下输出中,可以看到 node2 有节点not ready误:
kubeuser@k8smaster:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8smaster.pci.co.id Ready control-plane 31d v1.28.8
k8sworker1.pci.co.id Ready <none> 31d v1.28.8
k8sworker2.pci.co.id NotReady <none> 31d v1.28.8
节点可能因多种原因进入“Not Ready”状态,包括网络问题、资源耗尽、配置错误或底层硬件问题。了解并解决此错误的根本原因对于维持 Kubernetes 集群的运行效率和可靠性至关重要。
在 Kubernetes 中,节点状态对于管理集群的运行状况和工作负载分配至关重要。节点可以处于多种状态之一,反映其当前状态和接受工作负载的能力:
要确定节点是否遇到节点"Not Ready"错误并获取解决问题所需的信息,执行以下步骤:
第一步是检查集群中节点的状态。这可以使用 kubectl get nodes 命令来完成,该命令列出了所有节点及其状态。标记为“Not Ready”的节点需要进一步调查以了解根本问题。
kubectl describe node 命令提供了关于节点的详细信息,包括其状态、事件和配置。此信息对于诊断节点处于 “Not Ready” 状态的根本原因非常有用,可以提供节点可能遇到的任何错误或警告的见解。分析此命令的输出有助于找出具体问题,从而指导故障排除和解决过程。
以下是一个节点遇到问题时输出的简化示例:
Name: node2
Roles: <none>
Labels: beta.kubernetes.io/os=linux
Annotations: node.alpha.kubernetes.io/ttl=0
CreationTimestamp: Thu, 12 May 2024 12:00:00 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Thu, 12 May 2024 12:30:00 +0000 Thu, 12 May 2024 12:00:00 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Thu, 12 May 2024 12:30:00 +0000 Thu, 12 May 2024 12:00:00 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Thu, 12 May 2024 12:30:00 +0000 Thu, 12 May 2024 12:00:00 +0000 KubeletHasSufficientPID kubelet has sufficient PID available
Ready False Thu, 12 May 2024 12:30:00 +0000 Thu, 12 May 2024 12:20:00 +0000 KubeletNotReady PLEG is not healthy: pleg was last seen active 3m0s ago; threshold is 3m0s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Starting 12m kubelet, k8sworker2 Starting kubelet.
Warning NodeNotReady 3m kubelet, k8sworker2 Node node2 status is now: NodeNotReady
Warning ContainerdStartFail 2m kubelet, k8sworker2 Failed to start container runtime: Error
以下是输出中需要注意的几点,这些可能表明问题的原因:
每个节点上运行的主要组件 kubelet 与 Kubernetes master进行通信,其日志可以提供有关它遇到的任何错误或问题的见解。
可以使用 journalctl 或其他日志工具来访问 kubelet 日志,具体取决于节点的操作系统:
journalctl -b 0 --since today --unit=kubelet
May 31 10:22:00 k8sworker2.pci.co.id systemd[1]: Stopped kubelet: The Kubernetes Node Agent.
May 31 10:22:00 k8sworker2.pci.co.id systemd[1]: Started kubelet: The Kubernetes Node Agent.
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: Flag --container-runtime-endpoint has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/>
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: Flag --pod-infra-container-image has been deprecated, will be removed in a future release. Image garbage collector will get sandbox image information from CRI.
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: I0531 10:22:00.652172 18803 server.go:203] "--pod-infra-container-image will not be pruned by the image garbage collector in kubelet and should also be set in the remote runtime"
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: I0531 10:22:00.660748 18803 server.go:467] "Kubelet version" kubeletVersion="v1.28.8"
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: I0531 10:22:00.660971 18803 server.go:469] "Golang settings" GOGC="" GOMAXPROCS="" GOTRACEBACK=""
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: I0531 10:22:00.661272 18803 server.go:895] "Client rotation is on, will bootstrap in background"
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: I0531 10:22:00.662296 18803 certificate_store.go:130] Loading cert/key pair from "/var/lib/kubelet/pki/kubelet-client-current.pem".
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: I0531 10:22:00.663154 18803 dynamic_cafile_content.go:157] "Starting controller" name="client-ca-bundle::/etc/kubernetes/pki/ca.crt"
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: I0531 10:22:00.669608 18803 server.go:725] "--cgroups-per-qos enabled, but --cgroup-root was not specified. defaulting to /"
May 31 10:22:00 k8sworker2.pci.co.id kubelet[18803]: E0531 10:22:00.669881 18803 run.go:74] "command failed" err="failed to run Kubelet: running with swap on is not supported, please disable swap! or set --fail-swap-on flag to false. >
May 31 10:22:00 k8sworker2.pci.co.id systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE
May 31 10:22:00 k8sworker2.pci.co.id systemd[1]: kubelet.service: Failed with result 'exit-code'.
查看这些日志可以揭示与资源限制、网络问题或 kubelet 本身错误相关的问题,为节点处于 “Not Ready” 状态的根本原因提供线索。
有多种情况可能导致节点处于“Not Ready”状态
节点Not Ready 错误的一个常见原因是资源短缺,例如 CPU 或内存耗尽。监控资源使用情况可以帮助确定是否是这个原因。以下命令可用于检查节点上的资源分配和使用情况:
kubectl describe node k8sworker2.pci.co.id|grep -i allocated -A 5
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 350m (35%) 0 (0%)
memory 70Mi (2%) 170Mi (5%)
此命令显示节点上运行的 Pod 所分配和使用的 CPU 和内存资源量。如果节点资源分配过多,考虑缩减工作负载或向集群中添加更多节点。
以下是另一个命令,可以用来显示节点当前的 CPU 和内存使用情况,帮助识别资源短缺是否影响了节点的就绪状态:
kubectl top node <node-name>
检查网络设置和连接对于调查节点“Not Reay"错误至关重要。
例如,此命令检查与 Kubernetes Master节点的连通性,确保受影响的节点能够与集群的其余部分进行通信:
ping <master-node-ip>
kubeuser@k8smaster:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8smaster.pci.co.id Ready control-plane 32d v1.28.8
k8sworker1.pci.co.id Ready <none> 31d v1.28.8
k8sworker2.pci.co.id NotReady <none> 31d v1.28.8
kubeuser@k8smaster:~$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8smaster.pci.co.id Ready control-plane 32d v1.28.8 172.19.6.5 <none> Ubuntu 22.04.4 LTS 5.15.0-101-generic containerd://1.6.12
k8sworker1.pci.co.id Ready <none> 31d v1.28.8 172.19.6.8 <none> Ubuntu 22.04.4 LTS 5.15.0-107-generic containerd://1.6.28
k8sworker2.pci.co.id NotReady <none> 31d v1.28.8 172.19.6.9 <none> Ubuntu 22.04.4 LTS 5.15.0-107-generic containerd://1.6.28
kubeuser@k8smaster:~$ ping 172.19.6.9
PING 172.19.6.9 (172.19.6.9) 56(84) bytes of data.
64 bytes from 172.19.6.9: icmp_seq=1 ttl=64 time=2.25 ms
64 bytes from 172.19.6.9: icmp_seq=2 ttl=64 time=0.823 ms
64 bytes from 172.19.6.9: icmp_seq=3 ttl=64 time=1.01 ms
64 bytes from 172.19.6.9: icmp_seq=4 ttl=64 time=0.898 ms
此命令跟踪数据包到达主控节点的路径,有助于识别可能导致延迟或连接问题的任何网络跳跃。
traceroute to 172.19.6.9 (172.19.6.9), 30 hops max, 60 byte packets
1 k8sworker2.pci.co.id (172.19.6.9) 0.798 ms 1.355 ms 0.752 ms
重新启动 kubelet 可能会解决 kubelet 进程中的一些问题。重启 kubelet 的命令根据所使用的系统管理器而有所不同。在Linux系统中,命令通常是:
root@k8sworker2:~# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: activating (auto-restart) (Result: exit-code) since Fri 2024-05-31 11:10:51 WIB; 3s ago
Docs: https://kubernetes.io/docs/
Process: 20991 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS (code=exited, status=1/FAILURE)
Main PID: 20991 (code=exited, status=1/FAILURE)
CPU: 65ms
May 31 11:10:51 k8sworker2.pci.co.id systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE
May 31 11:10:51 k8sworker2.pci.co.id systemd[1]: kubelet.service: Failed with result 'exit-code'.
重启kubelet:
sudo systemctl restart kubelet
此命令重新启动 kubelet 服务,可能解决阻止节点达到”Ready"状态的问题。
每个节点上运行的网络代理 kube-proxy 出现问题也会影响节点就绪状态。检查 kube-proxy 的状态并在必要时重新启动它可能会有所帮助:
sudo systemctl status kube-proxy
重新启动 kube-proxy 可以解决影响节点与集群通信能力的网络相关问题,从而有可能解决“Not Ready”错误