1.k8s集群的能力供应站(pod)的详解
Pod是k8s中的最小调度单元,当指派容器时,容器实际上并不会指派到物理硬件上,容器会被分配到一个pod里,pod代表集群上正在运行的一个进程,一个pod封装一个容器(也可以封装多个容器),pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。
2.k8s集群中的pod的用途
运行单个容器的pod:
Pod里封装单个容器,k8s直接管理pod,pod调度到哪个物理节点,pod里的容器就跟随pod调度到哪个节点。
运行多个协同工作的容器的pod:
Pod里可以运行多个容器,如初始化容器、业务容器,这些容器之间的互相作用,共享资源。
3.k8s集群中pod一般哪些方面容易出现问题
1).k8s资源配置错误
例如部署deployment和statefuset时,资源清单书写有问题,导致pod无法正常创建。
2).代码问题
应用程序代码在容器启动后失败,那就需要通过检查代码找错误。
3).网络问题
网络插件部署有问题,导致pod启动之后无法相互通信。
4).存储问题
Pod挂载存储,但是需要共享的存储连接不上导致pod启动异常。
4.pod的状态为ContainerCreating状态的故障
一般原因是:后面node节点故障不能工作或网络ip已被注册、也可能是没有挂载到pv的存储卷。
诊断方法流程:
#kubectl get pod -o wide |grep pod名 #查看pod在哪个节点
#kubectl describe pod pod名 #查看pod的详细事件信息
#kubectl logs pod pod名 [-c 容器名] #查看pod的日志或某个容器日志
#systemctl status kubelet #查看pod所在节点的kubelet服务状态
#tailf /…/kubelet.xx.log #查看pod所在节点的kubelet服务日志
1).后面node节点故障不能工作的处理:
创建一个别的新的pod,看能否运行在该node1节点上,如果其他pod能创建在node1节点,说明可能只是无法创建的pod本身有问题,如果所有其他pod都无法在node1节点创建(所有在node节点创建的pod状态都是:ContainerCreating),说明node1节点有问题。
如果已经确定某个node节点有问题不能使用时,需要将node节点重置后重新加入集群:
步骤如下:
(1).先将该node节点上正在运行的pod驱逐到其他node节点
(2).#kubeadm reset 在故障node节点上重置k8s集群,执行完相当于这个节点所有东西都清空了(操作需要慎重,将pod全部驱逐后再操作)
(3).#systemctl stop kueblet
(4).#systemctl stop docker
(5).#rm -rf /var/lib/kubelet/*
(6).#rm -rf /etc/cni/
(7).#ifconfig cni0 down
(8).#ifconfig flannel.1 down (如果安装的是flannel网络)
(9).#ip link delete cni0
(10).#ip link delete flannel.1
(11).#systemctl start docker
(12).#systemctl start kubelet
(13)#kubeadmin join … 把node节点重新加入加入k8s集群
2).也可能是没有挂载到pv的存储卷的处理:
查看pv绑定的情况和需求。
步骤如下:
#kubectl get pod -o wide |grep pod名 #查看pod所在node节点
#kubectl describe pod pod名 #查看pod的详细信息
若后台存储是ceph相关报错,可能是没有安装相关程序
#yum -y install ceph-common #再相应节点安装ceph相关程序
安装ceph-common程序后,删除pod: test-ceph后重新运行pod,再查看状态。
如后台存储是nfs或其他,则查看相关服务是否正常,是否能手动正常挂载。
安装ceph-common程序后,删除pod: test-ceph后重新运行pod,再查看状态。
处理思路总结:
查看日志时候也可 -c 容器名
5.pod的状态为pending状态的故障
Pending状态:是挂起状态。表示创建的pod找不到可以运行它的物理节点,不能调度到相应的节点上运行。
1).从两个层面分析问题:
(1).物理节点层面分析:
查看节点资源使用情况:
如free -m查看内存、top查看cpu使用率、df -h查看磁盘使用情况,这样可以定位节点资源情况,判断是不是节点有问题。也可直接通过监控查询资源使用情况。
查看节点污点:
#kubectl describe node node节点名字 ,如果节点定义了污点,那么pod不能容忍污点,就会调度失败,可以在yaml文件里定义容忍度,则可以试下调度。
(2).pod本身分析:
在定义pod时,如果指定了nodeName或nodeSelector选择器是不存在的,那么也会调度失败。
在定义pod时,如果定义的资源请求比较大,导致物理节点资源不够也是不会调度的。
2).查看node节点是否有污点的方法:
#kubectl describe node node名称 |grep Taints
Taints xxx (看有没有,没有就是空)
6.pod的状态为ImagePullBackOff状态的故障
1).ImagePullBackOff状态的原因:
(1).拉取镜像时间长导致超时.
(2).配置的镜像有错误:如镜像名字不存在等.
(3).配置的镜像无法访问:如网络限制无法访问hub上的镜像.
(4).配置的私有镜像仓库参数错误:如imagePullSecret没有配置或者配置错误.
(5).dockerfile打包的镜像不可用.
2).ImagePullBackOff状态的排查思路:
#kubectl get pod -o wide 查看pod在哪个节点
#kubectl describe pod pod名 查看pod的详细信息
查看到时镜像拉不下来问题时,可以手动拉一下看看
7.pod的状态为CrashLoopBackOff状态的故障
1).CrashLoopBackOff状态的原因:
pod里面的容器退出、多次重启或准备删除。
k8s中的pod正常运行,但是里面的容器可能退出或者多次重启或者准备删除,导致出现这个状态,这个状态具有偶发性,可能上一步还是running状态,但是突然就变成CrashLoopBackOff状态了。
2).CrashLoopBackOff状态的排查思路:
#kubectl logs pod名 [-c 容器名] 查看pod日志,代码或环境变量
查看日志,查看构建镜像用的代码是否有问题,如果代码没问题,再看环境变量是否有问题。
#kubectl describe pod pod名 查看pod的详细信息,limit资源限制
查看yaml文件里的limit资源限制,是否跟资源限制有关。
8.pod的状态为Error状态的故障
原因分析:
(1).依赖的configmap、secret、pv、storageClass等不存在.
(2).请求的资源超过了管理员设置的限制,比如超过了limits等.
(3).无法操作集群内的资源,比如:开启rbac后,需要为serviceAccount配置权限.
排查思路:
#kubectl describe pod pod名 #查看pod详细信息
#kubectl logs pod pod名 [-c 容器名] #查看pod或容器日志
#kubectl -f -u kubelet #查看kubelet服务日志
#tail -f /var/log/messages #查看主机日志
9.pod的状态为Terminating或Unknown状态的故障
原因分析:
Terminating故障是因为容器里的应用挂了或node节点失联。
从k8s1.5开始,k8s不会因为node失联而删除其上正在运行的pod,而是将其标记为Terminating或Unknown状态。
相应删除这些状态的pod有4种方法:
1).手动删除node节点(确定节点不能用再删) # kubectl delete node node节点名称
2).恢复正常可选择性删除
若node节点恢复正常,kubelet会重新跟kube-apiserver通信确认这些pod的期待状态,进而再决定删除或者继续运行这些pod,如果删除可以通过
# kubectl delete pod pod名 –grace-period=0 --force强制删除
3).使用参数重建容器
4).自动重建pod
注意:节点确实不能用了再删node节点。删除node节点前,先将部署的pod服务驱逐到其他node节点。
如果node节点已经删除了,但是使用命令kubectl get pod查看时该node节点上还显示有pod,呈现terminating状态,可以用命令:
# kubectl delete pod pod名 –grace-period --force 强制删除该pod。
解决思路:
1).# kubectl get node #查看节点状态和节点资源是否还充足,df -h free -m
2).# kubectl get pod -n kube-system |grep apiserver #查看apiserver是否异常
3).查看kubelet日志,查看相应node节点的kubelet错误日志
10.pod的健康检查(存活性探测和就绪性探测)
1).为什么需要探针?
如果没有探针,k8s无法知道应用是否还活着,只要pod还在运行,k8s则认为容器时健康的。但实际上,pod虽然运行了,但里面容器中的应用可能还没提供服务,那就需要做健康检查,健康检查就需要探针。
2).常见的探针有以下几种:
(1).httpGet
对容器的ip地址(指定的端口和路径)执行http get请求,如果探测器收到响应,并且响应码是2xx,则认为探测成功。如果服务器没有响应或者返回错误响应码则说明探测失败,容器将重启。
(2).tcpSocket
探针与容器指定端口建立tcp连接,如果连接建立则探测成功,否则探测失败容器重启。
(3).exec
在容器内执行任意命令,并检查命令退出状态码,如果状态码为0,则探测成功,否则探测失败容器重启。
3).健康检查的两种方式: (livenessProbe和ReadinessProbe)
(1).LivenessProbe(存活探测):
探测pod里的容器是否启动成功,如果pod里的容器启动成功那pod的状态就是Running.
(2).ReadinessProbe(就绪探测):
Pod是Running的前提下,看pod里容器部署的应用是否就绪,是否可以对外提供服务,如果应用正常,可以接受客户端的请求,则ready是就绪的。
4).LivenessProbe和ReadinessProbe区别:
LivenessProbe决定是否重启容器、ReadinessProbe主要来确定容器是否已经就绪,只有当pod里的容器部署的应用都处于就绪状态,才会将请求转发给容器。
11.token验证问题:(添加节点token过期)
默认kubeadm在安装集群后,会打印出join新节点的命令。不过只有24小时的有效期
kubeadm init --kubernetes-version=1.18.5 --apiserver-advertise-address=${ip} --pod-network-cidr=10.244.0.0/16 --image-repository=dockerhub.example.com
若期望新增节点,则需要重新生成token,默认是24小时有效期,这里可以通过设置ttl=0为永久有效
kubeadm token create --print-join-command --ttl=0
输出:
kubeadm join 172.16.10.10:6443 --token q4ge2n.rnwke6l5wmtaglrj --discovery-token-ca-cert-hash sha256:b64218fa30ae1ca5f8f7e336f935fc7bf84d561a7e29521800b12d5fe34c6819
查看token列表
kubeadm token list
查看--discovery-token-ca-cert-hash值
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
12.kubectl执行异常,无权限连接到k8s问题定位
kubectl执行异常的排查:
1) .安装k8s之后默认是没有权限操作k8s资源的,可用如下方式解决:
mkdir -p $HOME/.kube
sudo cp -rf /etc/kubernetes/admin.conf $HOME/.kube/config
2).也可能是kube-apiserver异常导致。