searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

k8s之连接异常(集群故障)

2024-07-26 09:57:30
42
0

1.k8s集群的能力供应站(pod)的详解

Podk8s中的最小调度单元,当指派容器时,容器实际上并不会指派到物理硬件上,容器会被分配到一个pod里,pod代表集群上正在运行的一个进程,一个pod封装一个容器(也可以封装多个容器),pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。

2.k8s集群中的pod的用途

运行单个容器的pod:

Pod里封装单个容器,k8s直接管理podpod调度到哪个物理节点,pod里的容器就跟随pod调度到哪个节点。

运行多个协同工作的容器的pod:

Pod里可以运行多个容器,如初始化容器、业务容器,这些容器之间的互相作用,共享资源。

3.k8s集群中pod一般哪些方面容易出现问题

1).k8s资源配置错误

例如部署deploymentstatefuset,资源清单书写有问题,导致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时,如果指定了nodeNamenodeSelector选择器是不存在的,那么也会调度失败。

在定义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).依赖的configmapsecretpvstorageClass等不存在.

(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的状态为TerminatingUnknown状态的故障

原因分析:

Terminating故障是因为容器里的应用挂了或node节点失联。

k8s1.5开始,k8s不会因为node失联而删除其上正在运行的pod,而是将其标记为TerminatingUnknown状态。

相应删除这些状态的pod4种方法:

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).健康检查的两种方式: (livenessProbeReadinessProbe)

(1).LivenessProbe(存活探测):

探测pod里的容器是否启动成功,如果pod里的容器启动成功那pod的状态就是Running.

(2).ReadinessProbe(就绪探测):

PodRunning的前提下,看pod里容器部署的应用是否就绪,是否可以对外提供服务,如果应用正常,可以接受客户端的请求,则ready是就绪的。

4).LivenessProbeReadinessProbe区别:

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异常导致。

0条评论
0 / 1000
Liqingsen
6文章数
0粉丝数
Liqingsen
6 文章 | 0 粉丝
原创

k8s之连接异常(集群故障)

2024-07-26 09:57:30
42
0

1.k8s集群的能力供应站(pod)的详解

Podk8s中的最小调度单元,当指派容器时,容器实际上并不会指派到物理硬件上,容器会被分配到一个pod里,pod代表集群上正在运行的一个进程,一个pod封装一个容器(也可以封装多个容器),pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。

2.k8s集群中的pod的用途

运行单个容器的pod:

Pod里封装单个容器,k8s直接管理podpod调度到哪个物理节点,pod里的容器就跟随pod调度到哪个节点。

运行多个协同工作的容器的pod:

Pod里可以运行多个容器,如初始化容器、业务容器,这些容器之间的互相作用,共享资源。

3.k8s集群中pod一般哪些方面容易出现问题

1).k8s资源配置错误

例如部署deploymentstatefuset,资源清单书写有问题,导致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时,如果指定了nodeNamenodeSelector选择器是不存在的,那么也会调度失败。

在定义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).依赖的configmapsecretpvstorageClass等不存在.

(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的状态为TerminatingUnknown状态的故障

原因分析:

Terminating故障是因为容器里的应用挂了或node节点失联。

k8s1.5开始,k8s不会因为node失联而删除其上正在运行的pod,而是将其标记为TerminatingUnknown状态。

相应删除这些状态的pod4种方法:

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).健康检查的两种方式: (livenessProbeReadinessProbe)

(1).LivenessProbe(存活探测):

探测pod里的容器是否启动成功,如果pod里的容器启动成功那pod的状态就是Running.

(2).ReadinessProbe(就绪探测):

PodRunning的前提下,看pod里容器部署的应用是否就绪,是否可以对外提供服务,如果应用正常,可以接受客户端的请求,则ready是就绪的。

4).LivenessProbeReadinessProbe区别:

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异常导致。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0