k8s学习-核心概念-Pod

227 阅读6分钟

Pod概念

Pod是k8s集群中部署运行应用服务的最小工作单元,可简单理解为容器集,每个Pod拥有独立的IP地址和端口,一个pod中可以运行一个或多个容器,多个容器共享Pod的网络和存储资源(Volume)。 通常建议一个Pod运行一个容器,如果一个Pod运行多个容器,那么这些容器一定是紧密关联(耦合)的。

如下图所示,一个包含多个容器的 Pod 中包含一个用来拉取文件的程序和一个 Web 服务器, 均使用持久卷作为容器间共享的存储。

image.png

Pod生命周期

image.png

Pod生命周期各阶段状态说明:

取值描述
PendingPod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。
RunningPod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
SucceededPod 中的所有容器都已成功终止,并且不会再重启。
FailedPod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
Unknown因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。

如果某节点死掉或者与集群中其他节点失联,K8s 会将失联的节点上运行的所有 Pod 的状态设置为 Failed

容器状态说明

取值描述
Waiting正在运行完成启动所需要的相关操作,如拉取镜像,读取配置等
Running正常运行
Terminated正常结束或者因为某些原因失败。

Pod 的 spec 中包含一个 restartPolicy 字段,表示容器退出后的重启策略,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。Always不管容器是否正常退出,都会重启。

Pod状况条件测试

k8s对Pod进行运行状况测试,包括以下Conditions:

  • PodScheduled:Pod 已经被调度到某节点;
  • PodHasNetwork:Pod 沙箱被成功创建并且配置了网络(Alpha 特性,必须被显式启用);
  • ContainersReady:Pod 中所有容器都已就绪;
  • Initialized:所有的 Init 容器都已成功完成;
  • Ready:Pod 可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中。

在dashboard中可以查看的pod状况列表:

image.png

容器探针

探针是由 kubelet 对容器执行的定期诊断。kubelet 既可以在容器内执行代码,也可以发出一个网络请求。

探测机制:

  • exec 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
  • grpc 使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC健康检查。 如果响应的状态是 "SERVING",则认为诊断成功。 gRPC 探针是一个 Alpha 特性,只有在你启用了 "GRPCContainerProbe" 特性门控时才能使用。
  • httpGet对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。
  • tcpSocket 对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。 如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的

探测类型

  • livenessProbe指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success

  • readinessProbe指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success

  • startupProbe 指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器, 而容器依其重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success

探测的结果分三种:Success(成功)、Failure(失败)、Unknown(未知)

什么场景需要使用探针

何时该使用存活态探针-livenessProbe?

如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活态探针; kubelet 将根据 Pod 的 restartPolicy 自动执行修复操作。

但实际很多场景下,程序可能存在假死状态。进程还存活,但是程序却无响应或者说无法提供正常服务,这种情况下如果希望容器在探测失败时被杀死并重新启动,就可以指定一个存活态探针, 并指定 restartPolicy 为 "Always" 或 "OnFailure"。

何时该使用就绪态探针-readinessProbe?

如果要仅在探测成功时才开始向 Pod 发送请求流量,可以指定就绪态探针。这意味着 Pod 将在启动阶段不接收任何请求,只有在探针探测成功后才开始接收请求。

何时该使用启动探针-startupProbe?

如果容器需要在启动期间加载大量数据、配置文件或执行迁移等耗时操作(容器启动时间超出存活态探针 initialDelaySeconds + failureThreshold × periodSeconds 总值),可以使用启动探针。启动探针和存活态探针所使用的同一端点执行检查,开启启动探针后,其它探针将被延迟执行。这些可以避免启动时长较久的程序启动时,被存活态探针反复探测失败而不断重启进入死循环。

livenessProbe:
  httpGet:
    path: /healthz
    port: liveness-port
  failureThreshold: 1
  periodSeconds: 10

startupProbe:
  httpGet:
    path: /healthz
    port: liveness-port
  failureThreshold: 30
  periodSeconds: 10

如上配置,应用程序将会有最多 5 分钟(30 * 10 = 300s)的时间来完成其启动过程。 一旦启动探测成功一次,存活探测任务就会接管对容器的探测,对容器存活状态作出快速响应。 如果启动探测一直没有成功,容器会在 300 秒后被杀死,并且根据 restartPolicy 来执行进一步处置。

SpringBoot应用程序探针配置

SpringBoot应用只要引入spring-boot-starter-actuator依赖,就可以用Maven-kubernetes-plugin插件生成探针配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
livenessProbe:
    failureThreshold: 3
    httpGet:
      path: /actuator/health
      port: 8080
      scheme: HTTP
    initialDelaySeconds: 180
    successThreshold: 1
    
readinessProbe:
    failureThreshold: 3
    httpGet:
      path: /actuator/health
      port: 8080
      scheme: HTTP
    initialDelaySeconds: 10
    successThreshold: 1