Kubernetes Deployment故障排除图解指南

here's a diagram to help you debug your deployments in Kubernetes (and you can download it in the PDF version here).

原文:https://learnk8s.io/troubleshooting-deployments

Kubernetes Deployment故障排除图解指南

K8s pod生命周期:

Pod 的完整生命周期过程,包含 Init Container、Pod Hook、健康检查 三个主要部分。

Kubernetes Deployment故障排除图解指南

K8s pod创建流程:

Kubernetes Deployment故障排除图解指南

在 Kubernetes 中创建 Pod 的流程包含多个步骤,涉及多个组件协同工作。5

  1. 创建 Pod 定义文件: 开发者首先需要编写 Pod 的 YAML 或者 JSON 定义文件,其中包含 Pod 的配置信息,例如容器镜像、端口、资源需求等。2

  2. 提交到 API Server: 使用 kubectl apply 命令将 Pod 定义文件提交到 Kubernetes API Server。API Server 会验证该文件是否符合规范,并检查用户是否有权限创建 Pod。2

  3. 存储在 etcd 数据库: API Server 将 Pod 定义文件存储在 etcd 数据库中,etcd 是 Kubernetes 的核心数据存储组件。3

  4. 调度: API Server 会将 Pod 定义文件传递给 Scheduler,Scheduler 会根据 Pod 的资源需求、节点标签等信息,选择最合适的节点来运行 Pod。2 3

  5. 通知 Kubelet: Scheduler 将 Pod 的运行节点信息传递给 Kubelet,Kubelet 是运行在每个节点上的代理,负责管理 Pod 的生命周期。2

  6. 下载镜像: Kubelet 首先从镜像仓库中下载 Pod 定义文件中的容器镜像。2

  7. 创建容器: Kubelet 使用 Container Runtime Interface (CRI) 来创建容器,CRI 是一个标准的接口,允许 Kubelet 使用不同的容器运行时(例如 Docker、containerd 等)。3

  8. 网络配置: Kubelet 使用 Container Network Interface (CNI) 来为容器配置网络,CNI 负责为容器分配 IP 地址,并将容器连接到 Kubernetes 网络。3

  9. 存储卷挂载: 如果 Pod 定义文件中包含存储卷,Kubelet 会使用 Container Storage Interface (CSI) 来挂载存储卷到容器。3

  10. 启动容器: Kubelet 启动容器,并监控容器的运行状态。2

  11. 更新状态: Kubelet 将 Pod 的运行状态更新到 API Server,这样 API Server 就可以随时掌握 Pod 的运行情况。3

Kubernetes Deployment故障排除图解指南

kubernetes创建pod流程图

如果 Pod 属于某个Service,还会有相应的探测及流量调度的动作:

1.Kubelet 等待 Readiness 探针成功。

2.对所有相关的 Endpoint 对象更改进行通知。

3.Endpoint 将新 endpoint(IP 地址 + 端口)添加到列表中。

4.Kube-proxy 被通知 Endpoint 更改,然后 Kube-proxy 会更新每个节点上的 iptables 规则。

5.Ingress 控制器被通知 Endpoint 变化,然后控制器会将流量路由到新的 IP 地址。

6.CoreDNS 被通知 Endpoint 更改。如果服务的类型为 Headless,DNS 会进行更新。

7.云提供商被通知 Endpoint 更改。如果 Service 是 type: LoadBalancer,新的 endpoint 配置会是负载均衡池的一部分。

8.集群中安装的所有服务网格也会被通知 Endpoint 更改。

9.订阅 Endpoint 更改的其他运营商也会收到通知。

K8s pod生命周期和容器状态:

  • Pod phase: Pod phase 是对 Pod 在其生命周期中所处位置的一个高层次的概括,包括 PendingRunningSucceededFailed 和 Unknown

    • Pending:Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未被创建。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。

    • Running:Pod 中的所有容器都已经被创建,并且至少有一个容器正在运行,或者正在启动或者重启。

    • Succeeded:Pod 中的所有容器都已经成功终止,并且不会再重启。比如执行Job,CronJob类任务的pod完成时可以看到这个状态。

    • Failed:Pod 中的所有容器都已经终止,但至少有一个容器是因为失败而终止。

    • Unknown:Pod 的状态无法被获取,通常是由于与 Pod 应该运行的节点通信失败导致的。比如节点上的kubelet本身故障了,apiserver连不上kubelet,也就得不到pod状态信息,就会看到Unknown。

  • Container states: 容器的状态,包括 WaitingRunning 和 Terminated

    • Waiting:容器正在等待某些条件满足,例如正在拉取镜像,或者应用 Secret 数据。

    • Running:容器正在运行中。

    • Terminated:容器已经终止,可能是正常结束或者因为某些原因失败。如果你使用 kubectl describe pod 或者 kubectl get pod 命令来查询包含 Terminated 状态的容器的 Pod 时, 你会看到容器进入此状态的原因、退出代码以及容器执行期间的起止时间。

  • Container Restart Policy: 容器重启策略,包括 AlwaysOnFailure 和 Never

    • Always:当容器失败时,由 kubelet 自动重启该容器。

    • OnFailure:当容器终止运行且退出码不为 0 时,即非正常退出时由 kubelet 自动重启该容器。

    • Never:不论容器运行状态如何,kubelet 都不会重启该容器。

  • Pod Status:在执行 kubectl get pod 命令时返回的 Pod 状态,该字段是 Pod 内所有容器状态的一个聚合,具体的源代码参见 printPod 函数.有以下几个常见的状态:

    • Init:N/M:Pod 包含 M 个 init 容器,其中 N 个已经运行完成。

    • Init:Error:Pod 中的某个 init 容器执行失败。

    • Init:CrashLoopBackOff:Pod 中的某个 init 容器多次失败。容器曾经启动了,但可能又异常退出了,这个时候需要看下pod容器内日志来排查问题。

    • Pending:Pod 尚未开始创建 init 容器。

    • PodInitializing:Pod 已经执行完所有 init 容器,在等待创建主容器。

    • ContainerCreating:当 Pod 中不包含 init 容器时,在等待创建主容器时会显示这个状态。

    • Running:Pod 中的所有容器都在运行中。

  • Pod Ready:以 Ready 的容器数量 / 所有容器的数量的形式展示。


K8s镜像状态及拉取策略:

在Kubernetes中,容器镜像策略(ImagePullPolicy)定义了容器在启动时如何拉取镜像的策略。常见的容器镜像策略状态包括:

  1. Always(始终):表示容器将始终尝试从镜像仓库拉取最新版本的镜像。即使本地已经存在相同的镜像,也会尝试拉取最新版本。

  2. IfNotPresent(如果不存在则拉取):表示容器仅在本地不存在所需镜像时才会尝试从镜像仓库拉取。如果本地已经存在相同的镜像,则不会拉取新的镜像。

  3. Never(从不拉取):表示容器不会尝试从镜像仓库拉取镜像。容器假定本地已经存在所需的镜像。

容器镜像下载的几种状态包括:

  1. Pulling(拉取中):表示容器正在从镜像仓库中下载镜像文件。

  2. Pulled(已拉取):表示容器已成功下载所需的镜像文件。

  3. ImagePullBackOff(镜像拉取失败):表示容器尝试拉取镜像但失败。

  4. ErrImagePull(镜像拉取错误):表示容器尝试拉取镜像时发生了错误。

  5. ImageInspectError(镜像检查错误):表示在尝试拉取镜像之前对镜像进行检查时出现了错误。


K8s容器探针:

Kubernetes中的容器探针(Probes)包括startupProbe、readinessProbe和livenessProbe,它们各自有不同的作用。

  • Startup,启动探针,用来检查应用是否已经启动成功,适合那些有大量初始化工作要做,启动很慢的应用。

  • Liveness,存活探针,用来检查应用是否正常运行,是否存在死锁、死循环。

  • Readiness,就绪探针,用来检查应用是否可以接收流量,是否能够对外提供服务。

需要注意这三种探针是递进的关系:应用程序先启动,加载完配置文件等基本的初始化数据就进入了Startup状态,之后如果没有什么异常就是Liveness存活状态,但可能有一些准备工作没有完成,还不一定能对外提供服务,只有到最后的Readiness状态才是一个容器最健康可用的状态。

Kubernetes Deployment故障排除图解指南

如果一个Pod里的容器配置了探针,Kubernetes在启动容器后就会不断地调用探针来检查容器的状态

  • 如果Startup探针失败,Kubernetes会认为容器没有正常启动,就会尝试反复重启,当然其后面的Liveness探针和Readiness探针也不会启动。

  • 如果Liveness探针失败,Kubernetes就会认为容器发生了异常,也会重启容器。

  • 如果Readiness探针失败,Kubernetes会认为容器虽然在运行,但内部有错误,不能正常提供服务,就会把容器从Service对象的负载均衡集合中排除,不会给它分配流量。

startupProbe:

Kubernetes Deployment故障排除图解指南

    • 作用:startupProbe用于验证容器内的应用程序是否已启动,如果提供了启动探测,则禁用所有其他探测,直到它成功为止,如果启动探针探测失败,则会禁用其他探针并杀死容器,容器将按其重启策略进行重启。

    • 用例:适用于需要在容器启动后立即发送流量的情况。

    • 最佳实践:如果容器启动时间较长,可以指定Startup Probe。Startup Probe和Liveness Probe可以使用相同的端点,但Startup Probe可以具有较宽松的失败阈值,以防止启动时的失败。

readinessProbe:

Kubernetes Deployment故障排除图解指南

    • 作用:readinessProbe用于确定容器是否准备好提供服务。如果readinessProbe返回失败状态,Kubernetes将从所有服务的端点中删除容器的IP地址。

    • 用例:适用于等待应用程序执行耗时初始任务的情况,如建立网络连接、加载文件和缓存预热。

    • 最佳实践:包括所有必要的检查,但检查不应耗时过长。始终指定Readiness Probe,以确保只有当容器能够正确处理传入请求时才接收流量。

livenessProbe:

Kubernetes Deployment故障排除图解指南

    • 作用:livenessProbe用于确定容器中运行的应用程序是否处于健康状态。如果livenessProbe检测到不健康状态,Kubernetes将杀死容器并尝试重新部署。

    • 用例:适用于检测应用程序是否处于可用状态的情况。

    • 最佳实践:只包含基本检查在livenessProbe中,不要包含对其他服务连接的检查。检查不应该耗时过长。

探针使用:

startupProbe、livenessProbe、readinessProbe这三种探针的配置方式都是一样的,关键字段有这么几个:

  • periodSeconds,执行探测动作的时间间隔,默认是10秒探测一次。

  • timeoutSeconds,探测动作的超时时间,如果超时就认为探测失败,默认是1秒。

  • successThreshold,连续几次探测成功才认为是正常,对于startupProbe和livenessProbe来说它只能是1。

  • failureThreshold,连续探测失败几次才认为是真正发生了异常,默认是3次。

至于探测方式,Kubernetes支持3种:Shell、TCP Socket、HTTP GET,它们也需要在探针里配置:

  • exec,执行一个Linux命令,比如ps、cat等等,和container的command字段很类似。

  • tcpSocket,使用TCP协议尝试连接容器的指定端口。

  • httpGet,连接端口并发送HTTP GET请求。


参考:


anzhihe 安志合个人博客,版权所有 丨 如未注明,均为原创 丨 转载请注明转自:https://chegva.com/4157.html | ☆★★每天进步一点点,加油!★★☆ | 

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注