Pod概念
Pod是k8s集群中部署运行应用服务的最小工作单元,可简单理解为容器集,每个Pod拥有独立的IP地址和端口,一个pod中可以运行一个或多个容器,多个容器共享Pod的网络和存储资源(Volume)。 通常建议一个Pod运行一个容器,如果一个Pod运行多个容器,那么这些容器一定是紧密关联(耦合)的。
如下图所示,一个包含多个容器的 Pod 中包含一个用来拉取文件的程序和一个 Web 服务器, 均使用持久卷作为容器间共享的存储。
Pod生命周期
Pod生命周期各阶段状态说明:
| 取值 | 描述 |
|---|---|
Pending | Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 |
Running | Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 |
Succeeded | Pod 中的所有容器都已成功终止,并且不会再重启。 |
Failed | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 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状况列表:
容器探针
探针是由 kubelet 对容器执行的定期诊断。kubelet 既可以在容器内执行代码,也可以发出一个网络请求。
探测机制:
exec在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。grpc使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC健康检查。 如果响应的状态是 "SERVING",则认为诊断成功。 gRPC 探针是一个 Alpha 特性,只有在你启用了 "GRPCContainerProbe" 特性门控时才能使用。httpGet对容器的 IP 地址上指定端口和路径执行 HTTPGET请求。如果响应的状态码大于等于 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