Kubernetes常见问题异常集锦

网友投稿 932 2022-11-03

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

Kubernetes常见问题异常集锦

排查集群状态异常问题通常从 Node 和 Kubernetes 服务 的状态出发,常见的有:

A .kube-apiserver 无法启动会导致

集群不可访问,已有的 Pod 和服务正常运行(依赖于 Kubernetes API 的除外)

B. etcd 集群异常会导致

kube-apiserver 无法正常读写集群状态,进而导致 Kubernetes API 访问出错,kubelet 无法周期性更新状态

C. controller-manager/scheduler 异常会导致

复制控制器、节点控制器、云服务控制器等无法工作,从而导致 Deployment、Service 等无法工作,也无法注册新的 Node 到集群中来

新创建的 Pod 无法调度(总是 Pending 状态)

D. Node 本身宕机或者 Kubelet 无法启动会导致

Node 上面的 Pod 无法正常运行

已在运行的 Pod 无法正常终止

网络分区会导致 Kubelet 等与控制平面通信异常以及 Pod 之间通信异常

E. 查看 Node 状态

一般来说,可以首先查看 Node 的状态,确认 Node 本身是不是 Ready 状态

kubectl get nodeskubectl describe node 

如果是 NotReady 状态,则可以执行 kubectl describe node 命令来查看当前 Node 的事件。这些事件通常都会有助于排查 Node 发生的问题。

SSH 登录 Node

在排查 Kubernetes 问题时,通常需要 SSH 登录到具体的 Node 上面查看 kubelet、docker、iptables 等的状态和日志。在使用云平台时,可以给相应的 VM 绑定一个公网 IP;而在物理机部署时,可以通过路由器上的端口映射来访问。但更简单的方法是使用 SSH Pod (不要忘记替换成你自己的 nodeName):

# cat ssh.yamlapiVersion: v1kind: Servicemetadata:name: sshspec:selector:app: sshtype: LoadBalancerports:- protocol: TCPport: 22targetPort: 22---apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: sshlabels:app: sshspec:replicas: 1selector:matchLabels:app: sshtemplate:metadata:labels:app: sshspec:containers:- name: alpineimage: alpineports:- containerPort: 22stdin: truetty: truehostNetwork: truenodeName: $ kubectl create -f ssh.yaml$ kubectl get svc sshNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEssh LoadBalancer 10.0.99.149 52.52.52.52 22:32008/TCP 5m

接着,就可以通过 ssh 服务的外网 IP 来登录 Node,如 ssh root@100.100.0.108

在使用完后, 不要忘记删除 SSH 服务 kubectl delete -f ssh.yaml。

查看日志

一般来说,Kubernetes 的主要组件有两种部署方法

直接使用 systemd 等启动控制节点的各个服务

使用 Static Pod 来管理和启动控制节点的各个服务

使用 systemd 等管理控制节点服务时,查看日志必须要首先 SSH 登录到机器上,然后查看具体的日志文件。如

journalctl -l -u kube-apiserverjournalctl -l -u kube-controller-managerjournalctl -l -u kube-schedulerjournalctl -l -u kubeletjournalctl -l -u kube-proxy

或者直接查看日志文件

/var/log/kube-apiserver.log/var/log/kube-scheduler.log/var/log/kube-controller-manager.log/var/log/kubelet.log/var/log/kube-proxy.log

而对于使用 Static Pod 部署集群控制平面服务的场景,可以参考下面这些查看日志的方法。

kube-apiserver 日志

PODNAME=$(kubectl -n kube-system get pod -l component=kube-apiserver -o jsonpath='{.items[0].metadata.name}')kubectl -n kube-system logs $PODNAME --tail 100

kube-controller-manager 日志

PODNAME=$(kubectl -n kube-system get pod -l component=kube-controller-manager -o jsonpath='{.items[0].metadata.name}')kubectl -n kube-system logs $PODNAME --tail 100

kube-scheduler 日志

PODNAME=$(kubectl -n kube-system get pod -l component=kube-scheduler -o jsonpath='{.items[0].metadata.name}')kubectl -n kube-system logs $PODNAME --tail 100

kube-dns 日志

PODNAME=$(kubectl -n kube-system get pod -l k8s-app=kube-dns -o jsonpath='{.items[0].metadata.name}')kubectl -n kube-system logs $PODNAME -c kubedns

Kubelet 日志

查看 Kubelet 日志需要首先 SSH 登录到 Node 上。

journalctl -l -u kubelet

Kube-proxy 日志,Kube-proxy 通常以 DaemonSet 的方式部署

$ kubectl -n kube-system get pod -l component=kube-proxyNAME READY STATUS RESTARTS AGEkube-proxy-42zpn 1/1 Running 0 1dkube-proxy-7gd4p 1/1 Running 0 3dkube-proxy-87dbs 1/1 Running 0 4d$ kubectl -n kube-system logs kube-proxy-42zpn Kube-dns/Dashboard CrashLoopBackOff

由于 Dashboard 依赖于 kube-dns,所以这个问题一般是由于 kube-dns 无法正常启动导致的。查看 kube-dns 的日志

$ kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns$ kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq$ kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c sidecar

可以发现如下的错误日志

Waiting for services and endpoints to be initialized from apiserver...skydns: failure to forward request "read udp 10.240.0.18:47848->168.63.129.16:53: i/o timeout"Timeout waiting for initialization

这说明 kube-dns pod无法转发 DNS 请求到上游 DNS 服务器。解决方法为:

如果使用的 Docker 版本大于 1.12,则在每个 Node 上面运行 iptables -P FORWARD ACCEPT 开启 Docker 容器的 IP 转发,等待一段时间,如果还未恢复,则检查 Node 网络是否正确配置,比如是否可以正常请求上游DNS服务器、是否开启了 IP 转发(包括 Node 内部和公有云上虚拟网卡等)、是否有安全组禁止了 DNS 请求等.

如果错误日志中不是转发 DNS 请求超时,而是访问 kube-apiserver 超时,比如:

E0122 06:56:04.774977 1 reflector.go:199] k8s.io/dns/vendor/k8s.io/client-go/tools/cache/reflector.go:94: Failed to list *v1.Endpoints: Get https://10.0.0.1:443/api/v1/endpoints?resourceVersion=0: dial tcp 10.0.0.1:443: i/o timeoutI0122 06:56:04.775358 1 dns.go:174] Waiting for services and endpoints to be initialized from apiserver...E0122 06:56:04.775574 1 reflector.go:199] k8s.io/dns/vendor/k8s.io/client-go/tools/cache/reflector.go:94: Failed to list *v1.Service: Get https://10.0.0.1:443/api/v1/services?resourceVersion=0: dial tcp 10.0.0.1:443: i/o timeoutI0122 06:56:05.275295 1 dns.go:174] Waiting for services and endpoints to be initialized from apiserver...I0122 06:56:05.775182 1 dns.go:174] Waiting for services and endpoints to be initialized from apiserver...I0122 06:56:06.275288 1 dns.go:174] Waiting for services and endpoints to be initialized from apiserver...

这说明 Pod 网络(一般是多主机之间)访问异常,包括 Pod->Node、Node->Pod 以及 Node-Node 等之间的往来通信异常。可能的原因比较多,具体的排错方法可以参考

Node NotReady

Node 处于 NotReady 状态,大部分是由于 PLEG(Pod Lifecycle Event Generator)问题导致的。社区 issue #45419 目前还处于未解决状态。

NotReady 的原因比较多,在排查时最重要的就是执行 kubectl describe node 并查看 Kubelet 日志中的错误信息。常见的问题及修复方法为:

Kubelet 未启动或者异常挂起:重新启动 Kubelet。

CNI 网络插件未部署:部署 CNI 插件。

Docker 僵死(API 不响应):重启 Docker。

磁盘空间不足:清理磁盘空间,比如镜像、临时文件等。

未完待续......

上一篇:软件测试培训之在接口测试中应对需求的频繁变化
下一篇:基于交易树的告警根因定位方法,告警根因定位怎么写
相关文章

 发表评论

暂时没有评论,来抢沙发吧~