-
1.1 Pod生命周期
1.1.1 过程及状态
Pod 的生命周期管理是 Kubernetes 集群中非常重要的一部分,它涉及到 Pod 从创建到销毁的整个过程。下面是 Pod 生命周期中各个阶段的简要说明:
-
Pod 创建过程:当一个 Pod 被创建时,Kubernetes 会为它分配资源并开始调度过程。
-
运行初始化容器(Init Container):在 Pod 的主容器启动之前,可以定义一个或多个初始化容器。这些容器会先于主容器运行,通常用于执行一些初始化操作,比如设置配置文件或等待其他服务就绪。
-
运行主容器(Main Container):初始化容器完成后,Pod 中的主容器会启动。主容器是 Pod 的核心部分,它负责执行应用程序的主要逻辑。
-
容器启动后钩子(Post Start Hook):这是 Kubernetes 提供的一种回调机制,当容器创建并启动后,会调用这个钩子。可以在这个钩子中执行一些容器启动后需要立即进行的操作。
-
容器终止前钩子(Pre Stop Hook):当容器即将被终止时,Kubernetes 会调用这个钩子。这允许容器进行一些清理工作,比如保存状态、释放资源等。
-
容器的存活性探测(Liveness Probe):Kubernetes 会定期检查容器的存活性,以确保容器仍在正常运行。如果探测失败,Kubernetes 会重启该容器。
-
就绪性探测(Readiness Probe):与存活性探测类似,就绪性探测用于确定容器是否已经准备好接收流量。如果探测失败,Kubernetes 会将该容器从服务的端点列表中移除,直到它再次就绪。
-
Pod 终止过程:当 Pod 被标记为需要终止时,Kubernetes 会停止所有的容器,并进行清理工作。在 Pod 被完全终止之前,可能会执行一些终止前的操作,比如保存状态或执行其他必要的清理任务。
Pod 的状态确实可以反映其当前的生命周期阶段。以下是 Pod 的五种状态(相位)的详细解释:
-
挂起(Pending):这个阶段表示 Pod 已经被 Kubernetes API 服务器创建,但尚未被调度到任何节点上。这可能是因为没有合适的节点可供调度,或者因为 Pod 正在等待某些依赖的资源(如 ConfigMaps、Secrets 或者容器镜像)。
-
运行中(Running):在这个状态中,Pod 已经被调度到节点上,并且所有的容器都已经被创建。至少有一个容器正在运行,或者正在启动或重启。
-
成功(Succeeded):当 Pod 中的所有容器都正常运行并成功退出(返回了退出代码 0),并且不会被重启时,Pod 就会进入成功状态。这通常用于表示批处理任务已经完成。
-
失败(Failed):如果 Pod 中的所有容器都终止了,但至少有一个容器是因为失败而终止的(即返回了非零的退出代码),Pod 就会进入失败状态。这表明 Pod 没有成功完成任务。
-
未知(Unknown):当 Kubernetes 控制平面无法获取到 Pod 的状态信息时,Pod 就会进入未知状态。这通常是由于与 Pod 所在节点的通信失败导致的。如果节点长时间无法与控制平面通信,可能会认为节点及其上的 Pods 处于未知状态。
1.1.2 创建和终止
1.1.2.1 Pod创建过程
Pod 的创建过程可以简写为以下几个步骤:
-
提交请求:用户通过
kubectl
或 API 客户端向 API 服务器提交创建 Pod 的请求。 -
创建对象:API 服务器创建 Pod 对象并存储到 etcd,然后向客户端确认创建成功。
-
监听变化:其他组件通过 watch 机制监听 API 服务器上的 Pod 对象变化。
-
调度决策:调度器为 Pod 选择节点,并将调度结果更新到 API 服务器。
-
启动容器:节点上的 kubelet 启动容器,并将状态回传给 API 服务器。
-
状态更新:API 服务器更新 etcd 中的 Pod 状态信息。
1.1.2.2 Pod终止过程
-
发送删除命令:用户通过
kubectl
或 API 客户端向 API 服务器发送删除 Pod 对象的命令。 -
宽限期:API 服务器开始等待宽限期(默认为 30 秒),在此期间 Pod 被视为 "dead",但尚未被立即删除。
-
标记为终止:Pod 被标记为
terminating
状态,告知系统它正在被删除。 -
Kubelet 启动关闭过程:节点上的 kubelet 监控到 Pod 状态变为
terminating
,开始关闭 Pod。 -
端点控制器移除:端点控制器发现 Pod 正在关闭,将其从所有相关服务的端点列表中移除。
-
PreStop 钩子:如果 Pod 定义了
preStop
钩子,这些钩子会被触发并同步执行,以进行清理操作。 -
停止容器:Pod 中的容器进程收到停止信号,开始正常关闭。
-
强制终止:如果宽限期结束,仍有进程在运行,kubelet 会发送信号强制终止这些进程。
-
完成删除:Kubelet 请求 API 服务器将 Pod 的宽限期设置为 0,完成删除操作,此时 Pod 对用户不可见。
1.1.3 初始化容器
初始化容器(Init Container)在 Kubernetes 中用于执行 Pod 中主容器启动前的一些初始化任务。
-
必须成功完成:每个初始化容器必须运行成功直至结束。如果某个初始化容器失败,Kubernetes 会尝试重启该容器,直到它成功完成。这确保了在主容器启动之前,所有的初始化工作都已经正确执行。
-
顺序执行:初始化容器按照在 Pod 定义中出现的顺序执行。只有当前一个初始化容器成功完成后,下一个才会开始执行。这允许复杂的初始化逻辑被分解成有序的步骤。
1.1.3.1 应用场景
-
环境检查:初始化容器可以用于检查外部服务是否可用,例如数据库或配置服务器,然后才启动应用容器。
-
数据加载:在启动应用之前,可能需要从外部源加载数据或配置文件到 Pod 中。
-
权限设置:有时需要在启动主容器之前设置文件权限或创建必要的目录结构。
-
依赖安装:安装主容器运行所需的依赖库或工具,特别是当这些依赖不包含在主容器镜像中时。
-
资源等待:等待某些资源(如 PersistentVolume 卷)准备就绪。
-
健康检查:对系统进行健康检查,确保所有依赖服务都处于健康状态,然后才启动应用。
-
自定义脚本执行:运行自定义脚本,执行如数据库迁移或缓存预热等操作。
1.1.3.2 测试
-
创建一个包含两个初始化容器的 Pod,其中一个初始化容器用于检查 MySQL 服务是否可达,另一个用于检查 Redis 服务是否可达。只有在两个服务都可达的情况下,主容器(Nginx)才会启动。
[root@K8s-master ~]# vim pod-initcontainer.yaml --- apiVersion: v1 kind: Pod metadata: name: pod-initcontainer namespace: test spec: containers: - name: main-container image: nginx:1.17.1 ports: - name: nginx-port containerPort: 80 initContainers: - name: test-mysql image: busybox command: ['sh', '-c', 'until ping -c 1 192.168.110.100; do echo waiting for mysql...; sleep 2; done;'] - name: test-redis image: busybox command: ['sh', '-c', 'until ping -c 1 192.168.110.200; do echo waiting for redis...; sleep 2; done;'] - 根据 Kubernetes 的行为,initContainers 中的容器将按照它们在配置中出现的顺序依次执行。 - 只有当 test-mysql 成功完成后,test-redis 才会开始执行。 - 只有当所有的初始化容器都成功完成后,Kubernetes 才会启动主容器 main-container。 [root@K8s-master ~]# kubectl apply -f pod-initcontainer.yaml pod/pod-initcontainer created [root@K8s-master ~]# kubectl get pod pod-initcontainer -n test #处于初始化过程,因为两台服务器不可达 NAME READY STATUS RESTARTS AGE pod-initcontainer 0/1 Init:0/2 0 2m51s [root@K8s-master ~]# nmcli connection modify ens33 +ipv4.addresses 192.168.110.100/24 #增加两台主机地址 [root@K8s-master ~]# nmcli connection modify ens33 +ipv4.addresses 192.168.110.200/24 [root@K8s-master ~]# nmcli connection up ens33 [root@K8s-master ~]# kubectl get pod pod-initcontainer -n test #主容器正常运行 NAME READY STATUS RESTARTS AGE pod-initcontainer 1/1 Running 0 33s [root@K8s-master ~]# kubectl describe pod pod-initcontainer -n test Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 4m49s default-scheduler Successfully assigned test/pod-initcontainer to k8s-node-02 Normal Pulling 4m48s kubelet Pulling image "busybox" Normal Pulled 4m45s kubelet Successfully pulled image "busybox" in 2.488707224s Normal Created 4m45s kubelet Created container test-mysql Normal Started 4m45s kubelet Started container test-mysql Normal Pulling 4m44s kubelet Pulling image "busybox" Normal Pulled 4m42s kubelet Successfully pulled image "busybox" in 2.403816887s Normal Created 4m42s kubelet Created container test-redis Normal Started 4m41s kubelet Started container test-redis Normal Pulled 4m41s kubelet Container image "nginx:1.17.1" already present on machine Normal Created 4m41s kubelet Created container main-container Normal Started 4m41s kubelet Started container main-container #可以看到把mysql和redis都搞定Nginx才能起来,主容器才能起来
1.1.4 钩子函数
-
Kubernetes 中的容器生命周期钩子(lifecycle hooks)些钩子允许开发者在容器的生命周期中的特定时刻执行自定义操作。kubernetes在主容器的启动之后和停止之前提供了两个钩子函数:
-
Post Start Hook:
-
这个钩子在容器创建并成功运行之后立即执行。它可以用来执行容器启动后需要立即进行的任务,比如发送信号给其他服务,或者执行某些初始化逻辑。
-
如果 Post Start 钩子失败,即执行的命令返回非零退出码,Kubernetes 会认为容器启动失败,并根据容器的重启策略决定是否重启容器。
-
-
Pre Stop Hook:
-
这个钩子在容器即将终止之前执行。它通常用于执行清理工作,如保存状态、优雅地关闭服务、释放资源等。
-
Pre Stop 钩子提供了一种优雅关闭容器的方式。如果容器在 Pre Stop 钩子执行期间没有停止,Kubernetes 将等待一段时间(默认为 30 秒)之后,发送 SIGKILL 信号强制终止容器。
-
-
Kubernetes 中容器生命周期钩子处理器支持的三种动作类型:
Exec
、TCPSocket
和HTTPGet
。-
Exec 命令:
-
这个动作类型允许在容器内执行一个命令行命令。
-
如果命令执行成功(退出状态码为0),钩子继续执行;如果失败(非零退出状态码),则容器将被重启。
lifecycle: postStart: exec: command: ["cat", "/tmp/healthy"]
-
-
TCPSocket:
-
这个动作类型尝试在容器内访问指定的 TCP 端口。
-
如果能够建立连接,则钩子动作成功;否则,容器将被重启。
lifecycle: postStart: tcpSocket: port: 8080
-
-
HTTPGet:
-
这个动作类型在容器内向指定的 URL 发起 HTTP GET 请求。
-
如果请求成功(HTTP 状态码为 200-399),钩子动作成功;如果失败,则容器将被重启。
lifecycle: postStart: httpGet: path: /healthz # URI地址 port: 80 # 端口号 host: 192.168.110.100 # 主机地址 scheme: HTTP # 支持的协议,可以是 HTTP 或 HTTPS
-
1.1.4.1 钩子函数使用实例(Exec为例)
[root@K8s-master ~]# vim pod-hook-exec.yaml --- apiVersion: v1 kind: Pod metadata: name: pod-hook-exec namespace: test spec: containers: - name: main-container image: nginx:1.17.1 ports: - name: nginx-port containerPort: 80 lifecycle: postStart: exec: command: ["/bin/bash", "-c", "echo 'postStart...' > /usr/share/nginx/html/index.html"] preStop: exec: command: ["/usr/sbin/nginx", "-s", "quit"] [root@K8s-master ~]# kubectl apply -f pod-hook-exec.yaml pod/pod-hook-exec created [root@K8s-master ~]# kubectl get pod -n test -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-hook-exec 1/1 Running 0 3m17s 10.244.2.11 k8s-node-02 <none> <none> [root@K8s-master ~]# curl 10.244.2.11 postStart...
1.1.5 容器探测
在Kubernetes中,确实存在两种类型的探针,用于确保容器实例的健康和可用性:
-
Liveness Probe(存活性探针):这种探针用于判断容器是否仍然处于“存活”状态。如果一个容器的存活性探针失败,Kubernetes会认为这个容器无法正常工作,因此会重启这个容器。存活性探针的典型用途是检测应用程序是否已经崩溃或者变得无响应。
-
Readiness Probe(就绪性探针):这种探针用于判断容器是否已经准备好接受流量。如果一个容器的就绪性探针失败,Kubernetes会从服务的负载均衡池中将该容器摘除,直到该容器再次报告它已经准备好。就绪性探针常用于确保新启动的容器在开始接收流量之前已经完成了初始化过程。
这两种探针都可以通过HTTP请求、TCP连接尝试或者执行容器内命令等方式来实现。它们可以配置为定期执行,并且可以设置初始延迟、超时时间以及探测间隔。
在配置时,可以为每个探针设置以下参数:
-
InitialDelaySeconds:在容器启动后等待多少秒才开始执行探针检查。
-
TimeoutSeconds:探针检查超时的时间。
-
PeriodSeconds:探针检查的执行频率。
-
SuccessThreshold:探测成功后,需要连续成功多少次才认为容器健康。
-
FailureThreshold:探测失败后,需要连续失败多少次才认为容器不健康。
Kubernetes 中存活性探针(Liveness Probe)和就绪性探针(Readiness Probe)支持的三种探测方式。以下是对这三种方式的简要说明:
-
Exec 命令探针:通过在容器内部执行一个命令来检查容器的健康状况。如果命令执行成功(即退出码为0),则认为容器是健康的。例如:
livenessProbe: exec: command: - cat - /tmp/healthy
这个例子中,如果容器内
/tmp/healthy
文件存在,cat
命令将成功执行,探针将返回健康状态。-
TCP Socket 探针:通过尝试与容器内部的某个端口建立 TCP 连接来检查容器的健康状况。如果连接成功建立,探针认为容器是健康的。例如:
livenessProbe: tcpSocket: port: 8080
在这个例子中,Kubernetes 将尝试连接到容器的 8080 端口,如果连接成功,容器被认为是健康的。
-
HTTP GET 探针:通过向容器内部的 Web 应用发送 HTTP GET 请求来检查容器的健康状况。如果 HTTP 响应的状态码在 200 到 399 之间,探针认为容器是健康的。例如:
livenessProbe: httpGet: path: /healthz # 这里是健康检查的URI路径 port: 80 # 这里是容器内部的端口号 host: 127.0.0.1 # 这里是主机地址,通常设置为localhost或127.0.0.1 scheme: HTTP # 这里指定使用的是HTTP协议
1.1.5.1 Exec命令探针
[root@K8s-master ~]# vim pod-liveness-exec.yaml --- apiVersion: v1 kind: Pod metadata: name: pod-liveness-exec namespace: test spec: containers: - name: nginx image: nginx:1.17.1 ports: - name: nginx-port containerPort: 80 livenessProbe: exec: command: ["/bin/cat", "/tmp/hello.txt"] [root@K8s-master ~]# kubectl apply -f pod-liveness-exec.yaml pod/pod-liveness-exec created [root@K8s-master ~]# kubectl describe pods pod-liveness-exec -n test Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 52s default-scheduler Successfully assigned test/pod-liveness-exec to k8s-node-02 Normal Pulled 21s (x2 over 51s) kubelet Container image "nginx:1.17.1" already present on machine Normal Created 21s (x2 over 51s) kubelet Created container nginx Normal Killing 21s kubelet Container nginx failed liveness probe, will be restarted Normal Started 20s (x2 over 50s) kubelet Started container nginx Warning Unhealthy 1s (x5 over 41s) kubelet Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory # 观察上面的信息就会发现nginx容器启动之后就进行了健康检查 # 检查失败之后,容器被kill掉,然后尝试进行重启(这是重启策略的作用,后面讲解) # 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长 [root@K8s-master ~]# kubectl get pods pod-liveness-exec -n test #启动后进行健康检测 NAME READY STATUS RESTARTS AGE pod-liveness-exec 1/1 Running 3 (24s ago) 115s [root@K8s-master ~]# kubectl get pods pod-liveness-exec -n test #稍等会被杀掉 NAME READY STATUS RESTARTS AGE pod-liveness-exec 0/1 CrashLoopBackOff 4 (17s ago) 2m48s # 可以修改成一个存在的文件,就正常了 [root@K8s-master ~]# kubectl exec pod-liveness-exec -n test -it -c nginx /bin/sh # echo hello > /tmp/hello.txt [root@K8s-master ~]# kubectl get pod pod-liveness-exec -n test NAME READY STATUS RESTARTS AGE pod-liveness-exec 1/1 Running 20 (39s ago) 46m
1.1.5.2 TCP Socket 探针
[root@K8s-master ~]# vim pod-liveness-tcpsocket.yaml --- apiVersion: v1 kind: Pod metadata: name: pod-liveness-tcpsocket namespace: test spec: containers: - name: nginx image: nginx:1.17.1 ports: - name: nginx-port containerPort: 80 livenessProbe: tcpSocket: port: 8080 [root@K8s-master ~]# kubectl apply -f pod-liveness-tcpsocket.yaml pod/pod-liveness-tcpsocket created [root@K8s-master ~]# kubectl describe pod pod-liveness-tcpsocket -n test Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m14s default-scheduler Successfully assigned test/pod-liveness-tcpsocket to k8s-node-02 Normal Pulled 44s (x4 over 2m13s) kubelet Container image "nginx:1.17.1" already present on machine Normal Created 44s (x4 over 2m13s) kubelet Created container nginx Normal Killing 44s (x3 over 104s) kubelet Container nginx failed liveness probe, will be restarted Normal Started 43s (x4 over 2m13s) kubelet Started container nginx Warning Unhealthy 34s (x10 over 2m4s) kubelet Liveness probe failed: dial tcp 10.244.2.18:8080: connect: connection refused # 观察上面的信息,发现尝试访问8080端口,但是失败了 # 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长 [root@K8s-master ~]# kubectl get pod pod-liveness-tcpsocket -n test NAME READY STATUS RESTARTS AGE pod-liveness-tcpsocket 1/1 Running 5 (46s ago) 3m16s [root@K8s-master ~]# kubectl get pod pod-liveness-tcpsocket -n test NAME READY STATUS RESTARTS AGE pod-liveness-tcpsocket 0/1 CrashLoopBackOff 5 (33s ago) 4m13s #可以修改成一个可以访问的端口,比如80,再试,结果就正常了 [root@K8s-master ~]# sed -i 's/8080/80/' pod-liveness-tcpsocket.yaml [root@K8s-master ~]# kubectl delete -f pod-liveness-tcpsocket.yaml pod "pod-liveness-tcpsocket" deleted [root@K8s-master ~]# kubectl apply -f pod-liveness-tcpsocket.yaml pod/pod-liveness-tcpsocket created [root@K8s-master ~]# kubectl get pod pod-liveness-tcpsocket -n test NAME READY STATUS RESTARTS AGE pod-liveness-tcpsocket 1/1 Running 0 12s
1.1.5.3 HTTP GET 探针
[root@K8s-master ~]# vim pod-liveness-httpget.yaml --- apiVersion: v1 kind: Pod metadata: name: pod-liveness-httpget namespace: test spec: containers: - name: nginx image: nginx:1.17.1 ports: - name: nginx-port containerPort: 80 livenessProbe: httpGet: scheme: HTTP port: 80 path: /hello [root@K8s-master ~]# kubectl apply -f pod-liveness-httpget.yaml pod/pod-liveness-httpget created [root@K8s-master ~]# kubectl describe pod pod-liveness-httpget -n test Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 66s default-scheduler Successfully assigned test/pod-liveness-httpget to k8s-node-01 Normal Pulled 5s (x3 over 65s) kubelet Container image "nginx:1.17.1" already present on machine Normal Created 5s (x3 over 65s) kubelet Created container nginx Warning Unhealthy 5s (x6 over 55s) kubelet Liveness probe failed: Get "http://10.244.1.6:80/hello": context deadline exceeded (Client.Timeout exceeded while awaiting headers) Normal Killing 5s (x2 over 35s) kubelet Container nginx failed liveness probe, will be restarted Normal Started 4s (x3 over 65s) kubelet Started container nginx [root@K8s-master ~]# kubectl get pod pod-liveness-httpget -n test NAME READY STATUS RESTARTS AGE pod-liveness-httpget 0/1 CrashLoopBackOff 4 (16s ago) 2m47s # 观察上面信息,尝试访问路径,但是未找到,出现404错误 # 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长 #修改一个可以访问的路径 [root@K8s-master ~]# sed -i 's#/hello#/#' pod-liveness-httpget.yaml [root@K8s-master ~]# kubectl delete -f pod-liveness-httpget.yaml pod "pod-liveness-httpget" deleted [root@K8s-master ~]# kubectl apply -f pod-liveness-httpget.yaml pod/pod-liveness-httpget created [root@K8s-master ~]# kubectl get pod pod-liveness-httpget -n test NAME READY STATUS RESTARTS AGE pod-liveness-httpget 1/1 Running 0 3s
1.1.5.4 livenessProbe的子属性
[root@K8s-master ~]# kubectl explain pod.spec.containers.livenessProbe livenessProbe: exec: <Object> # 在容器内执行的命令 tcpSocket: <Object> # 用于探测的TCP端口和IP httpGet: <Object> # 用于探测的HTTP GET请求 initialDelaySeconds: <integer> # 容器启动后等待多少秒执行第一次探测 timeoutSeconds: <integer> # 探测超时时间,默认为1秒,最小1秒 periodSeconds: <integer> # 执行探测的频率,默认为10秒,最小1秒 failureThreshold: <integer> # 连续探测失败多少次才被认定为失败,默认为3,最小1 successThreshold: <integer> # 连续探测成功多少次才被认定为成功,默认为1
-
配置实例
[root@K8s-master ~]# vim pod-liveness-httpget.yaml apiVersion: v1 kind: Pod metadata: name: pod-liveness-httpget namespace: dev spec: containers: - name: nginx image: nginx:1.17.1 ports: - name: nginx-port containerPort: 80 livenessProbe: httpGet: scheme: HTTP port: 80 path: / initialDelaySeconds: 30 # 容器启动后30秒开始探测 timeoutSeconds: 5 # 探测超时时间为5秒
1.1.6 重启策略
1.1.6.1 三种策略
Kubernetes 中的 Pod 支持以下三种重启策略:
-
Always:
-
描述:无论容器退出的原因是什么,都会自动重启容器。
-
默认值:如果未指定重启策略,Kubernetes 默认使用 Always。
-
-
OnFailure:
-
描述:仅当容器以非零退出码终止时,才会重启容器。
-
条件:需要指定退出码来触发重启。
-
-
Never:
-
描述:不论容器退出的原因是什么,都不会重启容器。
-
1.1.6.2 重启延迟
-
首次重启:首次需要重启的容器将立即进行重启。
-
后续重启:随后如果再次需要重启,kubelet 将会引入延迟,延迟时长从 10 秒开始,并呈指数增长。
-
延迟时长序列:10s、20s、40s、80s、160s,之后达到最大延迟时长。
-
最大延迟时长:300s,这是后续重启操作的最大延迟时长。
[root@K8s-master ~]# vim pod-restartpolicy.yaml --- apiVersion: v1 kind: Pod metadata: name: pod-restartpolicy namespace: test spec: restartPolicy: Never #论容器退出的原因是什么,都不会重启容器 containers: - name: nginx image: nginx:1.17.1 ports: - containerPort: 80 name: nginx-port livenessProbe: httpGet: scheme: HTTP port: 80 path: /hello [root@K8s-master ~]# kubectl apply -f pod-restartpolicy.yaml pod/pod-restartpolicy created [root@K8s-master ~]# kubectl describe pod pod-restartpolicy -n test # 查看Pod详情,发现nginx容器失败 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 94s default-scheduler Successfully assigned test/pod-restartpolicy to k8s-node-02 Normal Pulled 92s kubelet Container image "nginx:1.17.1" already present on machine Normal Created 92s kubelet Created container nginx Normal Started 92s kubelet Started container nginx Warning Unhealthy 63s (x3 over 83s) kubelet Liveness probe failed: HTTP probe failed with statuscode: 404 Normal Killing 63s kubelet Stopping container nginx [root@K8s-master ~]# kubectl get pod pod-restartpolicy -n test # 再观察pod的重启次数,发现一直是0,并未重启 NAME READY STATUS RESTARTS AGE pod-restartpolicy 0/1 Completed 0 2m3s
1.1.7 Pod常见状态转换场景
Pod中的容器数 Pod状态 发生事件 Always OnFailure Never 包含一个容器 Running 容器成功退出 Running Succeeded Succeeded 包含一个容器 Running 容器失败退出 Running Running Failed 包含两个容器 Running 1个容器失败退出 Running Running Running 包含两个容器 Running 容器内存溢出挂掉 Running Running Failed 注释:
-
对于
Always
重启策略,容器将立即重启。 -
对于
OnFailure
和Never
重启策略,如果容器成功退出且退出码为0,Pod状态将变为Succeeded。 -
对于
Always
重启策略,容器将立即重启。 -
对于
OnFailure
重启策略,容器将以非零退出码退出,因此会重启。 -
对于
Never
重启策略,容器将不会重启,Pod状态将变为Failed。 -
对于
Always
重启策略,由于内存溢出导致的容器终止将重启容器。 -
对于
OnFailure
重启策略,内存溢出导致的容器终止会触发重启,因为退出码是非零的。 -
对于
Never
重启策略,容器将不会重启,Pod中其他容器继续运行,但失败的容器状态将为Terminated
-