赞
踩
Pod 在整个生命周期中被系统定义为各种状态,熟悉 Pod 的各种状态对于理解如何设置 Pod 的调度策略、重启策
略是很有必要的,Pod 的状态如表所示。
Pod的重启策略(RestartPolicy)应用于 Pod 内的所有容器,并且仅在 Pod 所处的 Node 上由 kubelet 进行判断和
重启操作。当某个容器异常退出或者健康检查失败时,kubelet 将根据 RestartPolicy 的设置来进行相应的操作。
Pod的重启策略包括 Always
、OnFailure
和 Never
,默认值为 Always
。
Always
:当容器失效时,由 kubelet 自动重启该容器。
OnFailure
:当容器终止运行且退出码不为0时,由 kubelet 自动重启该容器。
Never
:不论容器运行状态如何,kubelet 都不会重启该容器。
kubelet 重启失效容器的时间间隔以 sync-frequency
乘以 2n 来计算,例如1、2、4、8倍等,最长延时 5min,
并且在成功重启后的 10min 后重置该时间。
Pod 的重启策略与控制方式息息相关,当前可用于管理 Pod 的控制器包括 ReplicationController、Job、
DaemonSet 及直接通过 kubelet 管理(静态Pod)。每种控制器对 Pod 的重启策略要求如下。
RC和DaemonSet
:必须设置为 Always,需要保证该容器持续运行。
Job
:OnFailure 或 Never,确保容器执行完成后不再重启。
kubelet
:在 Pod 失效时自动重启它,不论将 RestartPolicy 设置为什么值,也不会对 Pod 进行健康检查。
结合 Pod 的状态和重启策略,下表列出一些常见的状态转换场景。
Kubernetes 对 Pod 的健康状态可以通过两类探针来检查:LivenessProbe 和 ReadinessProbe,kubelet 定期
执行这两类探针来诊断容器的健康状况。
(1)LivenessProbe 探针:用于判断容器是否存活(Running
状态),如果 LivenessProbe 探针探测到容器不健
康,则 kubelet 将杀掉该容器,并根据容器的重启策略做相应的处理。如果一个容器不包含 LivenessProbe 探
针,那么 kubelet 认为该容器的 LivenessProbe 探针返回的值永远是 Success
。
(2)ReadinessProbe 探针:用于判断容器服务是否可用(Ready
状态),达到 Ready 状态的 Pod 才可以接收请
求。对于被 Service 管理的 Pod,Service 与 Pod Endpoint 的关联关系也将基于 Pod 是否 Ready 进行设置。如
果在运行过程中 Ready 状态变为 False,则系统自动将其从 Service 的后端 Endpoint 列表中隔离出去,后续再把
恢复到 Ready 状态的 Pod 加回后端 Endpoint 列表。这样就能保证客户端在访问 Service 时不会被转发到服务不
可用的 Pod 实例上。
LivenessProbe 和 ReadinessProbe 均可配置以下三种实现方式。
(1)ExecAction:在容器内部执行一个命令,如果该命令的返回码为0,则表明容器健康。
在下面的例子中,通过执行 cat /tmp/health
命令来判断一个容器运行是否正常。在该 Pod 运行后,将在创建
/tmp/health
文件 10s 后删除该文件,而 LivenessProbe 健康检查的初始探测时间(initialDelaySeconds
)为
15s,探测结果是 Fail,将导致 kubelet 杀掉该容器并重启它。
配置文件 013-livenessprobe-exec.yaml
的内容为:
# exec apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-exec spec: containers: - name: liveness image: busybox args: - /bin/sh - -c - echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600 livenessProbe: exec: command: - cat - /tmp/health initialDelaySeconds: 15 timeoutSeconds: 1
[root@master cha3]# kubectl create -f 013-livenessprobe-exec.yaml
pod/liveness-exec created
[root@master cha3]# kubectl get pod liveness-exec
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 0 28s
发现进行了重启,因为初始探测时健康检测文件已经被删除,所以检测到的状态是不正常的,所以会进行重启,再
次查看发现会不断进行重启:
[root@master cha3]# kubectl get pod liveness-exec
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 2m59s
[root@master cha3]# kubectl get pod liveness-exec
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 5 7m27s
(2)TCPSocketAction:通过容器的 IP 地址和端口号执行 TCP 检查,如果能够建立 TCP 连接,则表明容器健
康。
在下面的例子中,通过与容器内的 localhost:80
建立 TCP 连接进行健康检查。
配置文件 014-livenessprobe-tcpsocket.yaml
的文件内容为:
# tcpsocket apiVersion: v1 kind: Pod metadata: name: liveness-tcpsocket spec: containers: - name: nginx image: nginx ports: - containerPort: 80 livenessProbe: tcpSocket: port: 80 initialDelaySeconds: 30 timeoutSeconds: 1
[root@master cha3]# kubectl create -f 014-livenessprobe-tcpsocket.yaml
pod/liveness-tcpsocket created
[root@master cha3]# kubectl get pod liveness-tcpsocket
NAME READY STATUS RESTARTS AGE
liveness-tcpsocket 1/1 Running 0 23s
(3)HTTPGetAction:通过容器的 IP 地址、端口号及路径调用 HTTP Get 方法,如果响应的状态码大于等于200
且小于 400,则认为容器健康。
在下面的例子中,kubelet 定时发送 HTTP 请求到 localhost:80/_status/healthz
来进行容器应用的健康检
查。
配置文件 015-livenessprobe-http.yaml
的内容为:
# http apiVersion: v1 kind: Pod metadata: name: liveness-http spec: containers: - name: nginx image: nginx ports: - containerPort: 80 livenessProbe: httpGet: path: /_status/healthz port: 80 initialDelaySeconds: 30 timeoutSeconds: 1
[root@master cha3]# kubectl create -f 015-livenessprobe-http.yaml
pod/liveness-http created
[root@master cha3]# kubectl get pod liveness-http
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 0 19s
由于该 HTTP 请求返回有问题,所以 pod 也会一直重启:
[root@master cha3]# kubectl get pod liveness-http
NAME READY STATUS RESTARTS AGE
liveness-http 1/1 Running 3 4m21s
对于每种探测方式,都需要设置 initialDelaySeconds
和 timeoutSeconds
两个参数,它们的含义分别如下。
initialDelaySeconds
:启动容器后进行首次健康检查的等待时间,单位为s。
timeoutSeconds
:健康检查发送请求后等待响应的超时时间,单位为s。当超时发生时,kubelet 会认为容
器已经无法提供服务,将会重启该容器。
Kubernetes 的 ReadinessProbe 机制可能无法满足某些复杂应用对容器内服务可用状态的判断,所以
Kubernetes 从 1.11 版本开始,引入Pod Ready++
特性对 Readiness
探测机制进行扩展,在 1.14 版本时达到
GA稳定版,称其为 Pod Readiness Gates
。
通过Pod Readiness Gates
机制,用户可以将自定义的 ReadinessProbe
探测方式设置在 Pod 上,辅助
Kubernetes 设置 Pod 何时达到服务可用状态(Ready)。为了使自定义的 ReadinessProbe 生效,用户需要提供一
个外部的控制器(Controller)来设置相应的 Condition 状态。
Pod的 Readiness Gates
在 Pod 定义中的 ReadinessGate
字段进行设置。下面的例子设置了一个类型为
www.example.com/feature-1
的新 Readiness Gate
:
kind: Pod ...... spec: readinessGates: - conditionType: "www.example.com/feature-1" status: conditions: # Kubernetes系统内置的名为Ready的Condition - type: Ready status: "True" lastProbeTime: null lastTransitionTime: 2018-01-01T00:00:00Z # 用户自定义Condition - type: "www.example.com/feature-1" status: "False" lastProbeTime: null lastTransitionTime: 2019-03-01T00:00:00Z containerStatuses: - containerID: docker://abcd... ready: true ......
新增的自定义 Condition 的状态 status 将由用户自定义的外部控制器设置,默认值为 False。Kubernetes将在判
断全部 readinessGates 条件都为 True 时,才设置 Pod 为服务可用状态(Ready为True)。
用法示例:
如下设置了一个类型为 www.example.com/feature-1
的新 Readiness Gates
。
配置文件 016-readinessgates.yaml
的内容为:
apiVersion: v1 kind: Pod metadata: labels: run: centos name: centos namespace: default spec: containers: - args: - sleep - 10d image: centos imagePullPolicy: Always name: centos readinessGates: - conditionType: "www.example.com/feature-1"
[root@master cha3]# kubectl create -f 016-readinessgates.yaml
pod/centos created
# READINESS GATES 为 0/1
[root@master cha3]# kubectl get pods centos -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
centos 1/1 Running 0 21s 10.244.140.203 slave1 <none> 0/1
[root@master cha3]# kubectl get pod centos -o json | jq .status.conditions [ { "lastProbeTime": null, "lastTransitionTime": "2023-07-02T10:31:25Z", "status": "True", "type": "Initialized" }, # readinessGates { "lastProbeTime": null, "lastTransitionTime": "2023-07-02T10:31:25Z", "message": "corresponding condition of pod readiness gate \"www.example.com/feature-1\" does not exist.", "reason": "ReadinessGatesNotReady", "status": "False", "type": "Ready" }, { "lastProbeTime": null, "lastTransitionTime": "2023-07-02T10:31:43Z", "status": "True", "type": "ContainersReady" }, { "lastProbeTime": null, "lastTransitionTime": "2023-07-02T10:31:25Z", "status": "True", "type": "PodScheduled" } ]
apply 后查看 Ready condition 是 false,如果设置有 endpoint,也不会出现在 endpoint 列表里。如果要想容器
正常提供服务,就需要将对应的 conditionType 设置为 true。
通俗的来讲就是设置 readinessGates 字段,然后将对应的 condition 通过 patch 操作设置为 true。
注意 kubectl 是无法通过 patch 更改 status 里面的字段的。
由于状态字段不能通过 kubectl 命令进行修改,所以只能使用 API 的方式修改。
[root@master ~]# kubectl proxy
Starting to serve on 127.0.0.1:8001
# 或者
[root@master ~]# kubectl proxy --accept-hosts=".*" --address=0.0.0.0
Starting to serve on [::]:8001
# curl 直接调用
[root@master ~]# curl http://localhost:8001/api/v1/namespaces/default/pods/centos/status -X PATCH -H "Content-Type: application/json-patch+json" -d '[{"op": "add", "path": "/status/conditions/-", "value": {"type": "www.example.com/feature-1", "status": "True", "lastProbeTime": null}}]'
# 查看执行结果 kubectl get pods centos -o json | jq .status.conditions [ # readinessGates { "lastProbeTime": null, "lastTransitionTime": null, "status": "True", "type": "www.example.com/feature-1" }, { "lastProbeTime": null, "lastTransitionTime": "2023-07-02T10:31:25Z", "status": "True", "type": "Initialized" }, { "lastProbeTime": null, "lastTransitionTime": "2023-07-02T10:32:48Z", "status": "True", "type": "Ready" }, { "lastProbeTime": null, "lastTransitionTime": "2023-07-02T10:31:43Z", "status": "True", "type": "ContainersReady" }, { "lastProbeTime": null, "lastTransitionTime": "2023-07-02T10:31:25Z", "status": "True", "type": "PodScheduled" } ]
# READINESS GATES 为 1/1
[root@master cha3]# kubectl get pods centos -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
centos 1/1 Running 0 2m 10.244.140.203 slave1 <none> 1/1
可以看到此时容器状态已经正常了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。