作者:郑增权
爱可生南区数据库工程师,爱可生 DBA 团队成员,负责数据库相干技术支持。喜好:桌球、羽毛球、咖啡、电影
本文起源:原创投稿
*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。
一、本文概述及次要术语
1.1概述
本文基于 Pod 、Service 和 Ingress 三大模块进行划分,对于 Kubernetes 日常可能呈现的故障问题,提供了较为具体的排查步骤,并附上相干解决办法或参考文献。
1.2 次要术语
- Pod: Kubernetes 中创立和治理的、最小的可部署的计算单元。是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎么运行这些容器的申明。
- Port-forward: 通过端口转发映射本地端口到指定的利用端口。
- Service: 一个 Kubernetes 的 Service 是一种形象,它定义了一组 Pods 的逻辑汇合和一个用于拜访它们的策略 - 有时被称为微服务。
- Ingress: 提供了集群内部到外部 HTTP 和 HTTPS 服务的路由通信,流量路由通过 Ingress 资源上定义的规定管制。
二、故障诊断流程
2.1 Pods 模块查看
- 以下流程若胜利则持续往下进行,若失败则依据提醒进行跳转。
2.1.1 查看是否有pod处于PENDING状态
- kubectl get pods: 如果有 pod 处于 PENDING 状态则往下看,否则返回2.1.5 。
[root@10-186-65-37 ~]# kubectl get podsNAME READY STATUS RESTARTS AGEmyapp-deploy-55b54d55b8-5msx8 0/1 Pending 0 5m
- kubectl describe pod <pod-name>: 若正确输入指定的一个或多个资源的详细信息,则判断是否集群资源有余,若有余则进行拓展,否则返回 2.1.2 。
2.1.2 查看是否触发 ResourceQuota limit
- kubectl describe resourcequota -n <namespace>:
[root@10-186-65-37 ~]# kubectl describe quota compute-resources --namespace=myspaceName: compute-resourcesNamespace: myspaceResource Used Hard-------- ---- ----limits.cpu 0 2limits.memory 0 2Gipods 0 4requests.cpu 0 1requests.memory 0 1Gi
- 如有限度则进行相应资源开释或拓展,参考:
https://kubernetes.io/zh/docs... - 否则返回 2.1.3
2.1.3查看是否有 PVC 处于 PENDING 状态
- 长久卷(PersistentVolume,PV)是集群中的一块存储,能够由管理员当时供给,或者应用存储类(Storage Class)来动静供给;长久卷申领(PersistentVolumeClaim, PVC)表白的是用户对存储的申请。
kubectl describe pvc <pvc-name>:
若 STATUS 为 Pending[root@10-186-65-37 k8s-file]# kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGElocal-device-pvc Pending local-device 72s
则参考如下链接进行解决:
https://kubernetes.io/zh/docs...
- 否则返回 2.1.4
2.1.4 查看 pod 是否被调配至 node
- kubectl get pods -o wide:
若已被调配至 node
[root@10-186-65-37 ~]# kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESmyapp-deploy-55b54d55b8-5msx8 1/1 Running 0 14d 10.244.4.9 10-186-65-122 <none> <none>myapp-deploy-55b54d55b8-7ldj4 1/1 Running 0 14d 10.244.2.10 10-186-65-126 <none> <none>myapp-deploy-55b54d55b8-cwdwt 1/1 Running 0 14d 10.244.3.9 10-186-65-126 <none> <none>myapp-deploy-55b54d55b8-gvmb9 1/1 Running 0 14d 10.244.4.10 10-186-65-122 <none> <none>myapp-deploy-55b54d55b8-xbqb6 1/1 Running 0 14d 10.244.5.9 10-186-65-118 <none> <none>
则是 Scheduler 方面的问题,参考如下链接进行解决:
https://kubernetes.io/zh/docs...
- 否则为 Kubectl 的问题。
2.1.5 查看是否有 pods 处于 RUNNING 状态
- kubectl get pods -o wide:
如果 pods 处于 RUNNING 状态则返回 2.1.10 ,否则返回 2.1.6 。
2.1.6 查看 pod 日志
- kubectl logs <pod-name>:
若能正确获取日志则依据日志修复相干问题。
[root@10-186-65-37 ~]# kubectl logs myapp-deploy-55b54d55b8-5msx8127.0.0.1 - - [30/Sep/2021:06:53:16 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"127.0.0.1 - - [30/Sep/2021:07:49:44 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"127.0.0.1 - - [30/Sep/2021:07:51:09 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"127.0.0.1 - - [30/Sep/2021:07:57:00 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"127.0.0.1 - - [30/Sep/2021:08:03:56 +0000] "GET / HTTP/1.1" 200 65 "-" "curl/7.29.0" "-"
- 若无奈获取日志则判断容器是否疾速进行运行,若疾速进行则执行:
kubectl logs <pod-name> --previous - 无奈获取日志,且容器并非疾速进行运行,则返回 2.1.7 。
2.1.7 Pod 状态是否处于 ImagePullBackOff
- kubectl describe pod <pod-name>:
查看 status 是否为 ImagePullBackOff ?不为 ImagePullBackOff 则返回 2.1.8 . - 查看 image 名称是否正确,谬误则修改。
- 查看 image tag 是否存在并通过验证。
- 是否从 private registry 拉取镜像?若是则确认配置信息正确。
- 若并非从 private registry 拉取镜像,问题可能出在 CRI(容器运行时接口) 或 kubectl 。
2.1.8 Pod 状态是否处于 CrashLoopBackOff
- kubectl describe pod <pod-name>:
查看 status 是否为 CrashLoopBackOff ?否则返回 2.1.9 。 - 若是则查看日志并修复应用程序解体。
- 确认是否脱漏了 Dockerfile 中的 CMD 指令?
Docker history <image-id> (后可加 --no-trunc 显示残缺输入)
[root@10-186-65-37 ~]# docker history fb4cca6b4e4c IMAGE CREATED CREATED BY SIZE COMMENTfb4cca6b4e4c 22 months ago /bin/sh -c #(nop) COPY file:957630e64c05c549… 121MB <missing> 2 years ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 2 years ago /bin/sh -c #(nop) ADD file:1d711f09b1bbc7c8d… 42.3MB
- Pod 状态是否频繁重启且状态处于 Running 和 CrashLoopBackOff 之间切换?若是则需修复 liveness probe(存活探测器)的问题,请参考如下链接:
https://kubernetes.io/zh/docs...
2.1.9 Pod 状态是否处于 RunContainerError
- kubectl describe pod <pod-name>:
查看 status 是否为 RunContainerError 。 - 若状态为 RunContainerError 问题可能因为挂载卷 (volume) 导致,请参考如下链接:
https://kubernetes.io/zh/docs... - 否则请在 StackOverflow 等网站寻求帮忙。
2.1.10 查看是否有 pods 处于 READY 状态
若处于 READY 状态,则持续往下执行进行映射设置
[root@10-186-65-37 ~]# kubectl get podsNAME READY STATUS RESTARTS AGEmyapp-deploy-55b54d55b8-5msx8 1/1 Running 0 14dmyapp-deploy-55b54d55b8-7ldj4 1/1 Running 0 14d
若无处于 READY 状态的 pods 则返回 2.1.11 。
- kubectl port-forward <pod-name> 8080:<pod-port>
- 映射胜利返回2.2
a)进行映射
[root@10-186-65-37 ~]# kubectl port-forward myapp-deploy-55b54d55b8-5msx8 8080:80Forwarding from 127.0.0.1:8080 -> 80Forwarding from [::1]:8080 -> 80
b)验证映射胜利
[root@10-186-65-37 ~]# curl localhost:8080Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
- 失败则需确认程序可被所有地址监听,设置语句如下:
kubectl port-forward --address 0.0.0.0 <pod-name> 8080:<pod-port>
若无奈被所有地址监听则为未知状态(Unknown state)。
2.1.11 查看 Readiness(就绪探测器)
- kubectl describe pod <pod-name>
- 失常输入则依据日志和参考如下链接修复相应问题
https://kubernetes.io/zh/docs... - 失败则为未知状态(Unknown state)。
2.2 Service 模块查看
2.2.1 Service 以后状态查看
- kubectl describe service <service-name>
胜利输入如下:
[root@10-186-65-37 ~]# kubectl describe service myapp\Name: myappNamespace: defaultLabels: <none>Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"myapp","namespace":"default"},"spec":{"ports":[{"name":"http","po...Selector: app=myapp,release=canaryType: ClusterIPIP: 10.96.109.76Port: http 80/TCPTargetPort: 80/TCPEndpoints: 10.244.2.10:80,10.244.3.9:80,10.244.4.10:80 + 2 more...Session Affinity: NoneEvents: <none>
- 是否能看到 Endpoints 列且有失常输入?非正常输入则返回 2.2.2 。
kubectl port-forward service/<service-name> 8080:<service-port>
胜利输入如下:[root@10-186-65-37 ~]# kubectl port-forward service/myapp 8080:80 Forwarding from 127.0.0.1:8080 -> 80Forwarding from [::1]:8080 -> 80
- 胜利则返回 2.3 ,失败则返回 2.2.4 。
2.2.2 Selector 与 Pod label 比对
- 查看 pod 的 label 信息
kubectl describe pod <pod-name>
[root@10-186-65-37 ~]# kubectl describe pod myapp-deploy-55b54d55b8-5msx8 | grep -i label -A 2Labels: app=myapp pod-template-hash=55b54d55b8 release=canary
查看 service 的 selector 信息
kubectl describe service <service-name>[root@10-186-65-37 ~]# kubectl describe service myapp | grep -i selector Selector: app=myapp,release=canary
- 比对两者是否正确匹配,谬误则进行修改,正确则返回 2.2.3 。
2.2.3 查看 Pod 是否已调配 IP
- 查看 pod 的 ip 信息
kubectl describe pod <pod-name> 已正确调配 ip ,则问题是因为 kubectl 导致。
[root@10-186-65-37 ~]# kubectl describe pod myapp-deploy-55b54d55b8-5msx8 | grep -i 'ip'IP: 10.244.4.9IPs: IP: 10.244.4.9
- 未调配 ip ,则问题是因为 Controller manager 导致。
2.2.4 查看 Service TargetPort 与 Pod ContainerPort
- 查看 service 的 TargetPort 信息:
kubectl describe service <service-name>
[root@10-186-65-37 ~]# kubectl describe service myapp | grep -i targetportTargetPort: 80/TCP
查看 pod 的 ContainerPort 信息:
kubectl describe pod < pod-name >[root@10-186-65-37 ~]# kubectl describe pod myapp-deploy-55b54d55b8-5msx8 | grep -i port Port: 80/TCP Host Port: 0/TCP
- 上方两者统一则问题是因为 kube-proxy 导致,不统一则进行信息修改。
2.3 Ingress 模块查看
2.3.1 Ingress 以后状态查看
kubectl describe ingress <ingress-name>
胜利输入如下:[root@10-186-65-37 ~]# kubectl describe ingress ingress-tomcat-tlsName: ingress-tomcat-tlsNamespace: defaultAddress: Default backend: default-http-backend:80 (<none>)TLS: tomcat-ingress-secret terminates tomcat.quan.comRules: Host Path Backends ---- ---- -------- tomcat.quan.com tomcat:8080 (10.244.2.11:8080,10.244.4.11:8080,10.244.5.10:8080)Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernets.io/ingress.class":"nginx"},"name":"ingress-tomcat-tls","namespace":"default"},"spec":{"rules":[{"host":"tomcat.quan.com","http":{"paths":[{"backend":{"serviceName":"tomcat","servicePort":8080},"path":null}]}}],"tls":[{"hosts":["tomcat.quan.com"],"secretName":"tomcat-ingress-secret"}]}} kubernets.io/ingress.class: nginxEvents: <none>
- 是否能看到 backends 列且有失常输入?失常输入返回 2.3.4 ,否则返回 2.3.2 。
2.3.2 查看 ServiceName 和 ServicePort
- kubectl describe ingress <ingress-name>
- kubectl describe service <service-name>
[root@10-186-65-37 ~]# kubectl describe ingress ingress-tomcat-tls | grep -E 'serviceName|servicePort' kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernets.io/ingress.class":"nginx"},"name":"ingress-tomcat-tls","namespace":"default"},"spec":{"rules":[{"host":"tomcat.quan.com","http":{"paths":[{"backend":{"serviceName":"tomcat","servicePort":8080},"path":null}]}}],"tls":[{"hosts":["tomcat.quan.com"],"secretName":"tomcat-ingress-secret"}]}}
- 查看前两者的 ServiceName 和 ServicePort 书写是否正确,若正确则返回2.3.3,谬误请修改。
2.3.3 Ingress controller 文档
- 问题是因为 Ingress controller 导致,请查阅文档寻找解决办法:
https://kubernetes.io/docs/co...
2.3.4 查看 port-forward ingress
1.kubectl port-forward <ingress-pod-name> 8080:<ingress-port>
测试是否能失常拜访:curl localhost:8080
可失常拜访返回 2.3.5 ,否则返回 2.3.3 。
2.3.5 查看是否在外网通过 Ingress 进行拜访
- 可从外网胜利拜访,故障排查完结。
- 若无奈从外网拜访,则问题是因为基础设施(infrastructure)或集群裸露(exposed)形式导致,请排查。