美文网首页K8s
kubernetes常见故障处理-k8s之连接异常(集群故障)

kubernetes常见故障处理-k8s之连接异常(集群故障)

作者: Chris0Yang | 来源:发表于2022-08-07 10:39 被阅读0次

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

    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一般哪些方面容易出现问题 与 遇到pod各种状态以及排查思路的方法

    1)k8s资源配置错误
    例如部署deployment和statefuset时,资源清单书写有问题,导致pod无法正常创建。
    2)代码问题
    应用程序代码在容器启动后失败,那就需要通过检查代码找错误。
    3)网络问题
    网络插件部署有问题,导致pod启动之后无法相互通信。
    4)存储问题
    Pod挂载存储,但是需要共享的存储连接不上导致pod启动异常。
    

    pod的各种状态

    1)启动时的错误包括:
    ImagePullBackoff
    ImageInspectError
    ErrImagePull
    ErrImageNeverPull
    RegistryUnavailable
    InvalidImageName
    
    2)运行中的错误包括:
    CrashLoopBackOff
    RunContainerError
    KillContainerError
    VerifyNonRootError
    RunInitContainerError
    CreatePodSandboxError
    ConfigPodSandboxError
    KillPodSandboxError
    SetupNetworkError
    TeardownNetworkError
    
    3)常见pod状态
    Pending:
    #正在创建Pod但是Pod中的容器还没有全部被创建完成,处于此状态的Pod应该检查Pod依赖的存储是否有权限挂载、镜像是否可以下载、调度是否正常等
    Failed
    #Pod中有容器启动失败而导致pod工作异常。检查事件
    Unknown
    #由于某种原因无法获得pod的当前状态,通常是由于与pod所在的node节点通信错误
    Succeeded
    #Pod中的所有容器都被成功终止即pod里所有的containers均已terminated。
    Unschedulable:
    #Pod不能被调度,kube-scheduler没有匹配到合适的node节点
    PodScheduled
    #pod正处于调度中,在kube-scheduler刚开始调度的时候,还没有将pod分配到指定的node,在筛选出合适的
    节点后就会更新etcd数据,将pod分配到指定的node
    Initialized
    #所有pod中的初始化容器已经完成了
    ImagePullBackOff:
    #Pod所在的node节点下载镜像失败
    Running
    #Pod内部的容器已经被创建并且启动
    Ready
    #表示pod中的容器已经可以提供访问服务
    complete
    # 容器已创建完成
    
    4)其它状态
    Error:                      # pod 启动过程中发生错误
    NodeLost:                   # Pod 所在节点失联
    Unkown:                     # Pod 所在节点失联或其它未知异常 
    Waiting:                    # Pod 等待启动
    Pending:                    # Pod 等待被调度
    Terminating:                # Pod 正在被销毁
    CrashLoopBackOff:          # pod 但是kubelet正在将它重启
    InvalidImageName:          # node节点无法解析镜像名称导致的镜像无法下载
    ImageInspectError:         # 无法校验镜像 镜像不完整导致
    ErrImageNeverPull:         # 策略禁止拉取镜像 镜像中心权限是私有等
    ImagePullBackOff:          # 镜像拉取失败 但是正在重新拉取
    RegistryUnavailable:       # 镜像服务器不可用 网络原因或harbor宕机
    ErrImagePull:              # 镜像拉取出错 超时或下载被强制终止
    CreateContainerConfigError:# 不能创建kubelet使用的容器配置
    CreateContainerError:      # 创建容器失败
    PreStartContainer:         
    
    执行preStart hook报错,Pod hook(钩子)是由 Kubernetes 管理的 kubelet 发
    起的,当容器中的进程启动前或者容器中的进程终止之前运行,比如容器创建完成后里面的服务启动之前可以检查一下
    依赖的其它服务是否启动,或者容器退出之前可以把容器中的服务先通过命令停止。
    
    PostStartHookError:        # 执行 postStart hook 报错
    RunContainerError:         # pod运行失败,容器中没有初始化PID为1的守护进程等
    ContainersNotInitialized:  # pod没有初始化完毕
    ContainersNotReady:        # pod没有准备完毕
    ContainerCreating:         # pod正在创建中
    PodInitializing:           # pod正在初始化中
    DockerDaemonNotReady:      # node节点docker服务没有启动
    NetworkPluginNotReady:     # 网络插件还没有完全启动
    

    常见错误原因

    ImagePullBackOff  
    镜像拉取错误(无效的镜像,指定了不存在标签,registry凭据)
    
    CrashLoopBackOff  
    (应用程序中存在错误,容器配置错误,liveness探针失败)
    
    kubectl logs podname --previous  
    (如果容器启动太快,打印前一个容器信息)
    
    RunContainerError
    (1.查看是否有不存在的卷,如configmap,secret 2.将只读挂在为读写) ---> kubectl describe pod <pod-name> 命令检查和分析这个错误
    
    pending状态  
    (1.没有足够的资源调度失败 2.当前命名空间具有ResourceQuota 对象,创建 Pod 将使命名空间超过配额  3.绑定了一个处于pending状态的pvc)
    
    kubectl get events --sort-by=.metadata.creationTimestamp # 如果ResouceQuota不足
    
    pod处于未就绪状态(`就绪`探针失败时,则 Pod 未连接到服务,并且没有流量转发到该实例)
    

    查看pod是否正常

    kubectl get pods -n fronted
    

    常见pod排查命令

    kubectl logs <pod name> 有助于检索 Pod 中容器的日志
    kubectl describe pod <pod name>  对检索与 Pod 相关的事件列表很有用
    kubectl get pod <pod name>  -o yaml 可提取 Kubernetes 中存储的 Pod 的 YAML 定义;
    kubectl exec -ti <pod name> bash 可在 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服务状态
    journalctl -u kubelet  #使用systemd运行kubelet,则需要使用journalctl 方法查看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 kubelet
    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或其他,则查看相关服务是否正常,是否能手动正常挂载。

    部分节点无法启动Pod: ContainerCreating状态
    排查故障总结:
    kubectl get pods <pod name>   # 查看日志pod状态
    kubectl describe pods <pod name>    # 查看pod详细信息
    kubectl logs pods <pod name>   # 查看log日志
    systemctl status kubelet   # 查看kubelet状态
    

    查看日志时候也可以 -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 (看有没有,没有就是空)
    

    Pod状态异常排查问题集-pending状态排查思路

    Pending是挂起状态: 表示创建的Pod找不到可以运行它的物理节点,不能调度到相应的节点上运行,那么这种情况如何去接查呢?我们可以从两个层面分析问题:

    1)物理节点层面分析

    1.查看节点资源使用情况:如free -m查看内存、top查看CPU使用率、df -h查看磁盘使用情况,这样就可以快速定位节点资源情况,判断是不是节点有问题
    2.查看节点污点:  kubectl deseribe nodes master1 (控制节点名字),如果节点定义了污点,那么Pod不能容忍污点,就会导致调度失败,如下:
    3.Taints:  node-role.kubernetes.io/master:NoSchedule
    4.这个看到的是控制节点的污点,表示不允许Pod调度 (如果Pod定义容忍度,则可以实现调度)
    

    2)Pod本身分析

    1.在定又pod时,如果指定了nodeNamo是不存在的,那也会调度失败
    2.在定义Pod时,如果定义的资源请求比较大,导致物理节点资源不够也是不会调度的
    
    image.png
    image.png

    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的详细信息
    

    查看到时镜像拉不下来问题时,可以手动拉一下看看

    Pod状态异常排查问题集 ImagePulIBackOff状态

    1)问题分析

    拉取镜像时间长导致超时
    配置的镜像有错误:如镜像名字不存在等
    配置的镜像无法访问:如网络限制无法访问hub上的镜像
    配置的私有镜像仓库参数错误:  如imagePullSecret没有配置或者配置错误
    dockerfile打包的镜像不可用
    

    Pod状态异常排查问题集 ImagePullBackOff状态排查思路

    1)查看Pod

    kubectl get pods -o wide
    tomcat-pod          0/1            ImagePulIBackOff           0           105s
    
    通过上面可以看到镜像拉取有问题,那可以进一步再将查错误
    kubectl describe pods tomcat-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资源限制,是否跟资源限制有关。


    image.png

    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).systemctl status kubectl #查看kubectl状态
    2).kubectl get node #查看节点状态和节点资源是否还充足,df -h free -m
    3).kubectl get pod -n kube-system |grep apiserver #查看apiserver是否异常
    4).查看kubelet日志,查看相应node节点的kubelet错误日志
    

    从 v1.5 开始,Kubernetes 不会因为 Node 失联而删除其上正在运行的 Pod,而是将其标记为 Terminating 或 Unknown 状态。想要删除这些状态的 Pod 有三种方法:

    1)从集群中删除该 Node。使用公有云时,kube-controller-manager 会在 VM 删除后自动删除对应的 Node
    而在物理机部署的集群中,需要管理员手动删除 Node(如 kubectl delete node <node-name>)
    
    2)Node 恢复正常
    Kubelet 会重新跟 kube-apiserver 通信确认这些 Pod 的期待状态,进而再决定删除或者继续运行这些 Pod
    
    3)用户强制删除
    用户可以执行 kubectl delete pods <pod> --grace-period=0 --force 强制删除 Pod。
    除非明确知道 Pod 的确处于停止状态(比如 Node 所在 VM 或物理机已经关机),否则不建议使用该方法
    特别是 StatefulSet 管理的 Pod,强制删除容易导致脑裂或者数据丢失等问题
    

    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里的容器部署的应用都处于就绪状态,才会将请求转发给容器。
    

    pod定义的存活性探测如下:

    livenessProbe:
      httpGet:
        path: /
        port: 8080
    

    常见问题:

    Killing container with id docker://xxxxx: Container failed probe.. Container wilIbe killed and reoreated.Iivenessพก
    

    如果在pod启动时遇到这种情况,一般是没有设置initialDeIaySeconds导致的
    设置初始化延迟initialDeIaySeconds

    livenessProbe:
      httpGet:
        path: /
        port: 8080
      initialDeIaySeconds: 15s    # pod启动过15s开始探测
    

    容器启动后再探测,否认容器还没起来呢就探测,肯定是探测失败的。

    11.token验证问题:(添加节点token过期)

    token过期的处理
    Kubeadm初始化k8s的时候生成的token有效期只有1天,当过期之后token就不可以用了,在node节点kubeadm join的时候在使用这个token就会报错,可用如下方法重新生成:
    1.kubeadm token create

    kubeadm token list 列出生成的token
    

    2.生成一个永不过期的token

    kubeadm token create --ttl 0
    

    3.获取ca证书的hash值加入集群除了需要token外,还需要Master 节点的ca证书 sha256编码hash值,这个可以通过如下命令获取:

    openssI x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
    

    4.把节点添加到集群:

    kubeadm join master_IP:6443 --token XXXXXX --discovery-token-ca-cert-hash sha256:XXXX
    

    12.kubectl执行异常,无权限连接到k8s问题定位

    kubectl执行异常的排查
    1.安装之后执行如下命令:

    kubeotl get nodes
    

    2.报错信息:

    The connection to the server loca I host: 8080 was refused - did you specify the right host or port?
    

    3.这是因为安装k8s之后,双认是没有权限操作k8s资源的,可用如下方法解决:

    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    

    相关文章

      网友评论

        本文标题:kubernetes常见故障处理-k8s之连接异常(集群故障)

        本文链接:https://www.haomeiwen.com/subject/rbsbwrtx.html