目录
简介
在Pod的生命周期中,可以执行多种操作如下图:
- 初始化容器:主容器启动前,可以先运行一个或多个初始化容器。初始化容器是串行执行的,必须全部成功完成后才会启动主容器。初始化容器运行结束后即退出,不再占用资源。
- Post Start钩子:主容器启动后,可以指定一个Post Start钩子,用于在主容器启动后执行一些额外的操作。
- Pre Stop钩子:在主容器终止之前,可以指定一个Pre Stop钩子,用于在主容器结束前执行必要的清理或其他操作。
- 健康探针:Pod启动后,其健康状态由以下几类探针进行检测:
- Startup Probe(启动探针):用于确保容器成功启动,在启动完成前其他探针不会干扰容器的启动过程。
- Liveness Probe(存活探针):用于检测容器是否存活。如果探测失败,Kubernetes会重启该容器。
- Readiness Probe(就绪探针):用于检测容器是否已准备好接收流量。如果探测失败,该Pod将暂时从服务端点中移除,直到其恢复就绪状态。
什么是探针
在Kubernetes中,探针(Probe)用于管理容器的生命周期,主要包括以下三种类型:
Liveness Probe(存活探针)
- 作用:判断容器是否处于运行状态(即容器是否存活)。
- 行为:
- 如果Liveness Probe探测到容器处于非健康状态,kubelet会杀掉该容器,并根据容器的重启策略进行处理。
- 如果未配置Liveness Probe,kubelet会默认认为容器始终处于“成功”状态。
- 场景:Liveness Probe用于捕捉容器死锁等问题。例如,当应用程序虽然运行但无法处理请求时,探针会检测到这个问题,并重启容器,使应用在存在bug的情况下依然能够继续运行。
Readiness Probe(就绪探针)
- 作用:判断容器是否已启动完成并准备好接受请求。
- 行为:
- 如果Readiness Probe探测失败,Pod的状态会被修改,Endpoint Controller会将该Pod从Service的Endpoint中移除。
- 如果未配置Readiness Probe,kubelet会默认认为容器处于“成功”状态。
- 场景:Readiness Probe用于控制哪些Pod可以作为Service的后端。如果Pod处于非就绪状态,它将被从Service的负载均衡中移除。
Startup Probe(启动探针)
- 作用:检测应用程序是否已完全启动。
- 行为:
- 在Startup Probe成功之前,其他探针(Liveness和Readiness)将被禁用。
- 如果Startup Probe探测失败,kubelet将终止容器并根据重启策略重启它。
- 如果未配置Startup Probe,kubelet会默认认为容器已成功启动。
- 场景:Startup Probe适用于启动时间较长的应用程序,确保应用完全启动后再启用其他探针。
通过合理配置这三类探针,可以确保Kubernetes中的容器在生命周期的各个阶段都处于健康状态,并能够及时处理异常情况。
什么时候使用探针?
何时使用存活探针(Liveness Probe)
- 容器可能卡死或无响应:如果你的应用程序在遇到问题时可能卡死或进入无响应状态,而不会自行崩溃,那么就应该使用存活探针。Liveness Probe 可以检测到这些状态,并触发 kubelet 终止并重启容器。
- 确保自动重启:如果你希望容器在探测失败时被杀死并重新启动,以确保应用的持续可用性,那么应配置存活探针。此时,可以将
restartPolicy
设置为Always
或OnFailure
,以确保在探针检测到问题时容器能够自动重启。
何时使用就绪探针(Read iness Probe)
- 控制流量路由:如果你希望只有在探测成功时才开始向 Pod 发送请求流量,就需要指定就绪探针。就绪探针常与存活探针相同,但它确保 Pod 在启动阶段不会接收任何数据,只有探测成功后才开始接收流量。
- 维护状态:如果希望容器能自行进入维护状态,可以使用就绪探针,检查与存活探针不同的特定端点。对于依赖于后端服务的应用程序,可以同时使用存活探针和就绪探针。存活探针检测容器本身的健康状况,而就绪探针则确保所需的后端服务可用,避免将流量导向出错的 Pod。
- Pod 删除:注意,如果只是想在 Pod 被删除时排空请求,通常不需要使用就绪探针。Pod 在删除时会自动进入未就绪状态,无论是否有就绪探针,直到容器停止为止。
何时使用启动探针(Startup Probe)
- 应用启动慢:如果容器在启动期间需要加载大型数据或配置文件,可以使用启动探针。它确保在启动完成前不会触发其他探针。
容器探测方法
exec
执行一段命令,根据返回值判断执行结果。
返回值为0, 非0两种结果,可以理解为"echo $?"。
httpGet
通过发起HTTTP协议的GET请求检测某个http请求的返回状态码,从而判断服务是否正常。
常见的状态码分为很多类,比如: "2xx,3xx"正常, "4xx,5xx"错误。
200: 返回状态码成功。
301: 永久跳转,会将跳转信息缓存到浏览器本地。
302: 临时跳转,并不会将本次跳转缓存到本地。
401: 验证失败。
403: 权限被拒绝。
404: 文件找不到。
413: 文件上传过大。
500: 服务器内部错误。
502: 无效的请求。
504: 后端应用网关相应超时。
tcpSocket
测试某个TCP端口是否能够连接,类似于telnet这样的工具。
每次探测都将获得以下三种结果之一:
- Success(成功):容器通过了诊断。
- Failure(失败):容器未通过诊断。
- Unknown(未知):诊断失败,因此不会采取任何行动。
容器探测使用
livenessProbe使用
exec使用
apiVersion: v1
kind: Pod
metadata:
name: livenessprobe-exec
spec:
containers:
- name: nginx
image: nginx:1.18
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 600
# 定义健康检查探针
livenessProbe:
# 指定探针的检测方法为exec。
exec:
# 指定exec要执行的命令
command:
- cat
- /tmp/healthy
# 指定第一次进行健康检查的秒数,该值在生产环境中应该确保这个延迟时间内容器可以正常启动运行。
initialDelaySeconds: 15
# 指定每次周期的健康检查的间隔时间。
periodSeconds: 5
# 指定执行exec定义命令的超时的秒数。
timeoutSeconds: 1
# 检查1次成功就认为服务是健康的。
successThreshold: 1
# 检查连续3次失败就认为服务是不健康的。
failureThreshold: 3
httpGet使用
apiVersion: v1
kind: Pod
metadata:
name: livenessprobe-httpGet
spec:
containers:
- name: nginx
image: nginx:1.18
ports:
- containerPort: 80
# 定义健康检查探针
livenessProbe:
httpGet: # 指定探针的检测方法为httpGet。
path: /index.html # 指定访问的文件路径信息即可,无需指定IP地址,因为默认就是访问本机,可以理解为127.0.0.1。
port: 80 # 指定对容器的哪个端口发送GET请求。
initialDelaySeconds: 15
# 指定每次周期的健康检查的间隔时间。
periodSeconds: 5
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
tcpSocket
apiVersion: apps/v1
kind: Deployment
metadata:
name: livenessprobe-tcpsocket
spec:
replicas: 1
selector:
matchLabels:
app: livenessprobe-tcpsocket
template:
metadata:
labels:
app: livenessprobe-tcpsocket
spec:
containers:
- name: nginx
image: registry.cn-guangzhou.aliyuncs.com/jiajia-k8s/nginx:1.21
ports:
- containerPort: 80
args:
- /bin/sh
- -c
- tail -f /etc/hosts
livenessProbe:
tcpSocket:
port: 80 # 检测80端口是否可以连通,若连不通则会抛出检查容器出现问题,而后重启容器。
initialDelaySeconds: 10
periodSeconds: 3
successThreshold: 1
failureThreshold: 2
很明显,上述案例暴露了80端口,由于启动容器时并没有启动nginx,而是去使用tail指令去查看一个文件内容达到阻塞容器的目的,因此在容器启动10后就开始第一次检查,而后每个3秒检查1次,达到指定次数后会触发重启操作,可以看到55秒内探测了4次,52秒内重启了两次
readinessProbe使用
exec使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: readinessProbe-exec
labels:
apps: nginx
spec:
replicas: 3
selector:
matchLabels:
apps: nginx
template:
metadata:
name: nginx
labels:
apps: nginx
spec:
containers:
- name: nginx
image: nginx:1.18
command:
- /bin/bash
- -c
- touch /tmp/nginx-healthy; sleep 60; rm -f /tmp/nginx-healthy; sleep 60;
livenessProbe:
exec:
command:
- cat
- /tmp/nginx-healthy
failureThreshold: 3
initialDelaySeconds: 15
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
exec:
command:
- cat
- /tmp/nginx-healthy-2023
failureThreshold: 3
initialDelaySeconds: 15
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
从事件日志来看,Liveness Probe
和 Readiness Probe
都因为无法找到 /tmp/nginx-healthy
文件而失败。这是由于容器中的命令在 60 秒后删除了该文件,导致探针在检查时无法访问该文件。
- Liveness Probe 失败触发了容器重启。此探针用于检测容器是否健康,不健康时会重启容器。
- Readiness Probe 失败使得 Pod 从 Service 的 Endpoints 列表中移除,导致 Pod 无法接收流量。这表示 Pod 当前无法处理请求。
httpGet使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: readinessprobe-httpget
spec:
replicas: 1
selector:
matchLabels:
app: readinessprobe-httpget
template:
metadata:
labels:
app: readinessprobe-httpget
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /healthz # HTTP 请求的路径
port: 80 # 容器内服务的端口
initialDelaySeconds: 15
periodSeconds: 5
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 1
tcpSocket使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: readinessprobe-tcpsocket
spec:
replicas: 1
selector:
matchLabels:
app: readinessprobe-tcpsocket
template:
metadata:
labels:
app: readinessprobe-tcpsocket
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
livenessProbe:
tcpSocket:
port: 80
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 1
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 15
periodSeconds: 5
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 1
startupProbe使用
httpGet使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: startupprobe-httpget
spec:
replicas: 1
selector:
matchLabels:
app: startupprobe-httpget
template:
metadata:
labels:
app: startupprobe-httpget
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /startup
port: 80
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 10
timeoutSeconds: 5
tcpSocket使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: startupprobe-tcpsocket
spec:
replicas: 1
selector:
matchLabels:
app: startupprobe-tcpsocket
template:
metadata:
labels:
app: startupprobe-tcpsocket
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
startupProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 10
timeoutSeconds: 5
标签:容器,name,Kubernetes,Probe,探针,nginx,健康检查,POD,Pod
From: https://www.cnblogs.com/Unstoppable9527/p/18352747