一、Pod生命周期
Pod的“status”字段是一个PodStatus对象,其中包含“phase”字段 (Pod.status.phase)
查看:kubectl get pod podName -o yaml | grep phase
[root@master study-demo]# kubectl get pod pod-hostport -o yaml | grep -n phase
136: phase: Running
Pod的阶段 | 描述 |
---|---|
Pending | Kubernetes已经开始创建Pod,但由于Pod中的容器还未创建成功,所以Pod还处于挂起的状态。这时Pod可能在等待被调度,或者在等待下载镜像 |
Runging | Pod已经被调度到某个节点上了,Pod中的所有容器都已被成功创建,并且至少有一个容器正处于启动、重启、运行这3个状态中的1个 |
Success | Pod中的所有容器都已成功执行完成,并且不会再重启 |
Failed | Pod所有容器都已经停止运行,并且至少有一个容器是因为失败而退出(即容器以非0状态退出或者被系统强制终止) |
Unknown | 因为某些原因导致无法取得Pod的状态。这种情况通常是由于网络的造成,例如,Pod所在主机通信失败等 |
二、Pod存活与就绪探针
2.1、背景
在Kubernetes中pod是最小的计算单元,而一个Pod由多个容器组成,相当于每个容器就是一个应用,应用在运行期间有可能因为某种原因而挂掉,那么如何监控这些容器的稳定性,保证服务在运行期间不会出现问题,发生问题后自动重启等问题,就成为了重中之重的事情,考虑到这点 kubernetes 推出了活性探针机制。
有了活性探针机制能够保证程序在运行过程中出现问题而重启,但是在kubernetes实际使用中,我们可能会经常出现这样一种问题。
比如说,pod显示启动成功,且能访问里面的端口,但是却返回错误信息,还有在滚动更新的时候,总会出现一段时间,Pod 对外提供网络访问,但是访问却发生 404,这两个原因,都是因为 Pod 已经成功启动,但是 Pod 的的容器中应用程序还在启动中导致,考虑到这点 Kubernetes 推出了就绪探针机制。
2.2、Pod三种探针
2.2.1、LivenessProbe (决定是否重启容器)
LivenessProbe(存活探针):用于探测容器是否运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其重启策略的影响决定是否重启。如果容器不提供存活探针,则默认状态为 Success。
2.2.2、ReadinessProbe (决定是否对外提供服务)
ReadinessProbe(就绪探针):一般用于探测容器内的程序是否健康,容器是否准备好服务请求。如果就绪探测失败,endpoint 将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址,让外界无法进行访问。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
2.2.3、StartupProbe
startupProbe(启动探针):用于检测pod内的容器是否已经启动成功并准备好接收流量。 与LivenessProbe不同的是,StartupProbe只会在容器启动时执行一次。如果三个探针同时存在,则先执行startupProbe探针,其他两个探针将会被暂时禁用,直到它成功为止。 如果启动探测失败,kubelet将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。 适用于需要较长启动时间的应用场景,比如应用程序需要大量预热或者需要等待外部依赖组件的应用程序。 适用于需要较长启动时间的应用场景,比如应用程序需要大量预热或者需要等待外部依赖组件的应用程序。
可以自定义在 pod 启动时是否执行这些检测,如果不设置,则检测结果均默认为通过,如果设置,则顺序为
startupProbe>readinessProbe>livenessProbe,如果一个yaml中定义了startupProbe探测和livenessProbe或者startupProbe和readinessProbe,则只有startupProbe探测成功后,才执行livenessProbe和readinessProbe探测。
2.3、Pod三种探测方式
目前LivenessProbe和ReadinessProbe两种探针都支持下面三种探测方法:
1、ExecAction:在容器中执行指定的命令,如果执行成功,退出码为 0 则探测成功。
2、TCPSocketAction:通过容器的 IP 地址和端口号执行 TCP 检 查,如果能够建立 TCP 连接,则表明容器健康。
3、HTTPGetAction:通过容器的IP地址、端口号及路径调用 HTTP Get方法,如果响应的状态码大于等于200且小于400,则认为容器健康
Success:表示通过检测
Failure:表示未通过检测
Unknow:表示检测没有正常进行
2.4、Pod探针属性
两种探针有许多字段可选,可以用来更加精确的控制LivenessProbe和ReadinessProbe两种探针的探测。
initialDelaySeconds:Pod启动后首次进行检查的等待时间,单位“秒”
periodSeconds:检查的间隔时间,默认为10s,单位“秒”
timeoutSeconds:探针执行检测请求后,等待响应的超时时间,默认为1s,单位“秒”
successThreshold:探针检测失败后认为成功的最小连接成功次数,默认为1s,在liveness探针中必须为1s,最小为1s
failureThreshold:探测失败的重试次数,重试一定次数后将认为失败,在readiness探针中,Pod会被标记为未就绪,默认3s,最小值1s
2.5、Pod两种探针的区别
Pod 的 ReadinessProbe 探针使用方式和 LivenessProbe 探针探测方法一样,也是支持三种,只是一个是用于探测应用的存活,一个是判断是否对外提供流量的条件。
总的来说 ReadinessProbe 和 LivenessProbe是使用相同探测的方式,只是探测后对Pod的处置方式不同。
存活性探针LivenessProbe:当检测失败后将容器杀死,并根据Pod的重启策略来决定对应措施
就绪性探针ReadinessProbe:当检测失败后,将Pod的IP:Port从对应Service关联的EndPoint地址列表中删除
三、探针使用示例
3.1、LivenessProbe探针使用示例
3.1.1、通过Exec方式做健康检测
vim liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec
labels:
app: liveness
spec:
containers:
- name: liveness
image: busybox
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- echo ok > /tmp/healthy; sleep 100; rm -rf /tmp/healthy; sleep 1000
livenessProbe:
initialDelaySeconds: 5 #Pod启动后首次进行检查的等待时间
periodSeconds: 5 #检查的间隔时间
exec:
command:
- cat
- /tmp/healthy
说明:通过执行 cat /tmp/healthy 来判断一个容器是否正常运行。在创建 /tmp/healthy文件100s后将其删除,而LivenessProbe健康检测的初始时间(initialDelaySeconds)为105s,探测结果为fail,将导致kubelet杀掉容器并重启它。
如下图所示:
等待一段时间,查看pod重启次数
3.1.2、通过HTTPGetAction方式做健康探测
vim liveness-http.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-http #定义pod名称
labels:
name: mynginx
spec:
restartPolicy: OnFailure #定义pod重启策略
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
livenessProbe: #定义探测机制
httpGet: #探测方式为httpGet
scheme: HTTP #指定协议
path: /healthy #指定路径下的文件,如果不存在,探测失败
port: 80
initialDelaySeconds: 10 #当容器运行多久之后开始探测(单位是s)
periodSeconds: 5 #探测频率(单位s),每隔5秒探测一次
---
apiVersion: v1 #关联一个service对象
kind: Service
metadata:
name: web-svc
spec:
selector:
name: mynginx
ports:
- protocol: TCP
port: 80
targetPort: 80
如下图所示:
探测结果的HTTP 状态码如果为200 ~400,则表示探测成功。如果探测失败,则会杀死Pod进行重启操作。
httpGet探测方法有如下可选的控制字段
scheme:用于测试连接的协议,默认为HTTP
host:要连接的主机名,默认为Pod IP
port:容器上要访问端口号或名称
path:HTTP 服务器上的访问URL
httpHeaders:自定义http请求Headers,http允许重复Headers
3.1.3、通过TCP方式做健康探测
vim liveness-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcp
labels:
app: liveness
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 80 #这里故意写错端口,为了验证探测失败后pod是否重启
initialDelaySeconds: 15
periodSeconds: 20
如下图所示:
说明:可以看到找不到该文件,表示探测失败,但是readiness机制与liveness机制不同,它并不会重启pod,而是连续探测3次失败后,则将容器设置为不可用的状态。
3.2、ReadinessProbe探针使用示例
3.2.1、通过Exec方式做健康检测
vim readiness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-exec
labels:
app: readiness
spec:
containers:
- name: readiness-exec
image: busybox
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- echo ok > /tmp/healthy; sleep 100; rm -rf /tmp/healthy; sleep 600
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
如下图所示:
说明:可以看到找不到该文件,表示探测失败,但是readiness机制与liveness机制不同,它并不会重启pod,而是连续探测3次失败后,则将容器设置为不可用的状态。
3.2、ReadinessProbe探针使用示例
3.2.1、通过Exec方式做健康检测
vim readiness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-exec
labels:
app: readiness
spec:
containers:
- name: readiness-exec
image: busybox
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- echo ok > /tmp/healthy; sleep 100; rm -rf /tmp/healthy; sleep 600
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
如下图所示:
3.2.2、通过HTTPGetAction方式做健康探测
vim readiness-http.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-http #定义pod名称
labels:
name: mynginx
spec:
restartPolicy: OnFailure #定义pod重启策略
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
readinessProbe: #定义探测机制
httpGet: #探测方式为httpGet
scheme: HTTP #指定协议
path: /healthy #指定路径下的文件,如果不存在,探测失败
port: 80
initialDelaySeconds: 10 #当容器运行多久之后开始探测(单位是s)
periodSeconds: 5 #探测频率(单位s),每隔5秒探测一次
---
apiVersion: v1 #关联一个service对象
kind: Service
metadata:
name: web-svc
spec:
selector:
name: mynginx
ports:
- protocol: TCP
port: 80
targetPort: 80
如下图所示:
说明:查看pod的Events信息,通过探测,可以知道pod是不健康的,且http访问失败。它并不会重启,而是直接将pod设置为不可用的状态。
3.2.3、通过TCP方式做健康探测
vim readiness-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
name: readiness-tcp
labels:
app: readiness
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 80 #这里故意写错端口,为了验证探测失败后pod是否重启
initialDelaySeconds: 15
periodSeconds: 20
3.3、StartupProbe探针使用示例
3.3.1、通过Exec方式做健康检测
vim startup-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: startup-exec
labels:
app: startup
spec:
containers:
- name: startup
image: busybox
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- echo ok > /tmp/healthy
startupProbe:
initialDelaySeconds: 5 #容器启动后多久开始探测
periodSeconds: 10 #检查的间隔时间
timeoutSeconds: 10 #探针执行检测请求后,等待响应的超时时间
successThreshold: 1 #探测成功多少次才算成功
failureThreshold: 3 #探测失败多少次才算失败
exec:
command:
- cat
- /tmp/healthy
说明:通过执行cat /tmp/healthy 来判断一个容器是否正常运行。在创建 /tmp/healthy文件100s后将其删除,而startupProbe健康检测的初始时间(initialDelaySeconds)为100s+5s,探测结果为fail,将导致kubelet杀掉容器并重启它。
如下图所示:
等待一段时间,查看pod重启次数
3.3.2、通过HTTPGetAction方式做健康探测
vim startup-http.yaml
apiVersion: v1
kind: Pod
metadata:
name: startup-http #定义pod名称
labels:
name: mynginx
spec:
restartPolicy: OnFailure #定义pod重启策略
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
startupProbe: #定义探测机制
httpGet: #探测方式为httpGet
scheme: HTTP #指定协议
path: /healthy #指定路径下的文件,如果不存在,探测失败
port: 80
initialDelaySeconds: 5 #容器启动后多久开始探测
periodSeconds: 10 #检查的间隔时间
timeoutSeconds: 10 #探针执行检测请求后,等待响应的超时时间
successThreshold: 1 #探测成功多少次才算成功
failureThreshold: 3 #探测失败多少次才算失败
---
apiVersion: v1 #关联一个service对象
kind: Service
metadata:
name: web-svc
spec:
selector:
name: mynginx
ports:
- protocol: TCP
port: 80
targetPort: 80
如下图所示:
说明:查看pod的Events信息,通过探测,可以知道pod是不健康的,且http访问失败。将导致kubelet杀掉容器并重启它,且将pod设置为不可用的状态。
3.3.3、通过TCP方式做健康探测
vim startup-tcp.yaml
apiVersion: v1
kind: Pod
metadata:
name: startup-tcp
labels:
app: startup
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
startupProbe:
tcpSocket:
port: 8080 #这里故意写错端口,为了验证探测失败后pod是否重启
initialDelaySeconds: 5 #容器启动后多久开始探测
periodSeconds: 10 #检查的间隔时间
timeoutSeconds: 10 #探针执行检测请求后,等待响应的超时时间
successThreshold: 1 #探测成功多少次才算成功
failureThreshold: 3 #探测失败多少次才算失败
说明:查看pod的Events信息,通过探测,可以知道pod是不健康的,且tcp访问失败。将导致kubelet杀掉容器并重启它,且将pod设置为不可用的状态
3.4、ReadinessProbe+LivenessProbe+StartupProbe混合使用
3.4.1、ReadinessProbe+LivenessProbe混合使用示例
vim liveness-readiness.yaml
apiVersion: v1
kind: Service
metadata:
name: rlprobe
labels:
app: rlprobe
spec:
type: NodePort
ports:
- name: server
port: 8080
targetPort: 8080
nodePort: 32280
- name: managerment
port: 8081
targetPort: 8081
nodePort: 32281
selector:
app: rlprobe
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rlprobe
labels:
app: rlprobe
spec:
replicas: 1
selector:
matchLabels:
app: rlprobe
template:
metadata:
name: rlprobe
labels:
app: rlprobe
spec:
containers:
- name: rl
image: mydlqclub/springboot-helloworld:0.0.1
imagePullPolicy: IfNotPresent
ports:
- name: server
containerPort: 8080
- name: managerment
containerPort: 8081
readinessProbe:
httpGet:
scheme: HTTP
port: 8081
path: /actuator/health
initialDelaySeconds: 20
periodSeconds: 5
timeoutSeconds: 10
livenessProbe:
httpGet:
scheme: HTTP
port: 8081
path: /actuator/health
initialDelaySeconds: 20
periodSeconds: 5
timeoutSeconds: 10
如下图所示:
说明:查看pod的Events信息,通过探测,可以知道pod是不健康的,且http访问失败。它会不断重启,而且会将pod设置为不可用的状态,直到重启之后探测成功会将pod状态设置为ready。