容器钩子
容器钩子(Container Hooks)是 Kubernetes 提供的一种机制,允许你在容器生命周期中的特定时机执行自定义命令或脚本,用于执行一些初始化或清理任务。
钩子类型
| 类型 | 触发时机 | 典型用途 |
|---|---|---|
| postStart | 容器启动后、主进程执行前 | 日志标记、权限设置、服务注册等 |
| preStop | 容器终止前(SIGTERM发出后) | 优雅关机、连接断开、状态上报等 |
使用钩子
有这样一个场景:部署一个 nginx 服务,并为其创建一个测试网页
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 5
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx-app
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command:
- sh
- -c
- echo "Test web page" > /usr/share/nginx/html/index.html
# 在停止Pod前优雅关闭nginx服务
preStop:
exec:
command:
- sh
- -c
- nginx -s stop
容器探针
存活性探针
存活性探测是 kubernetes 用于检测容器是否处于运行状态的一种机制,它定期向容器发送一个请求,并根据结果判断容器是否正在运行。
语法
| 字段 | 类型 | 说明 |
|---|---|---|
livenessProbe | object | 存活性探测 |
livenessProbe.exec | object | 在容器中执行特定的测试命令 |
livenessProbe**.**httpGet | object | 发送 HTTP GET 请求测试容器活性 |
livenessProbe.tcpSocket | object | 对指定的 TCP 端口进行连接测试 |
livenessProbe.failureThreshold | integer | 在连续检测失败 N 次后,认定该容器已终止 |
livenessProbe.initialDelaySeconds | integer | 在 Pod 启动 N 秒后开始执行检测 |
livenessProbe.periodSeconds | integer | 两次检测的间隔时间(默认 10s) |
livenessProbe.successThreshold | integer | 连续 N 次测试成功后将容器视为成功启动,默认为 1,意味着需要连续成功通过 2 次测试 |
livenessProbe.terminationGracePeriodSeconds | integer | 在容器终止前等待的时间,以便让容器执行清理和关闭连接等工作,默认值为 30s |
livenessProbe.timeoutSeconds | integer | 超时时间,在指定的时间内未获得响应,视为测试失败 |
示例
- 使用 exec 的方式进行存活健康探测
apiVersion: v1
kind: Pod
metadata:
labels:
run: test-nginx
name: test-nginx
spec:
containers:
- image: nginx:latest
name: test-nginx
ports:
- containerPort: 80
livenessProbe:
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 10
timeoutSeconds: 3
exec:
command:
- sh
- -c
- |
curl -f http://localhost/ || exit 1
restartPolicy: Always
- 使用 httpGet 的方式进行健康测试
apiVersion: v1
kind: Pod
metadata:
labels:
run: test-nginx
name: test-nginx
spec:
containers:
- image: nginx:latest
name: test-nginx
ports:
- containerPort: 80
livenessProbe:
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 10
timeoutSeconds: 3
httpGet:
scheme: HTTP #也可以是HTTPS
path: /healthz # 设定专门用于执行健康测试的路径
port: 80
host: 127.0.0.1
httpHeaders: # 通过指定HTTP headers防止普通用户访问
- name: X-Health-Check
value: kube-probe
restartPolicy: Always
- 使用 tcpSocket 的方式进行健康测试
tcpSocket 通常用于服务不提供 HTTP 访问但仍需要使用 TCP 连接的情景,比如服务器连接
apiVersion: v1
kind: Pod
metadata:
labels:
run: db
name: db
spec:
containers:
- image: mysql:8.0
name: db
ports:
- containerPort: 80
livenessProbe:
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 10
timeoutSeconds: 3
tcpSocket:
host: 127.0.0.1
port: 3306
restartPolicy: Always
就绪性探针
就绪性探针是 kubernetes 中用于确定 Pod 是否准备好接受流量的机制,通过就绪性探针,kubernetes 可以在流量发送到 Pod 之前,检查容器中的 Pod 是否已经启动并做好了处理用户请求的准备。如果 Pod 未通过就绪性检测,kubelet 将从 Service 的地址池中将 Pod 移除,防止流量转发到未就绪的 Pod 上导致流量丢失。
就绪性探测通常通过 HTTP 或 TCP 的方式实现。
语法
| 字段 | 类型 | 说明 |
|---|---|---|
readinessProbe | object | 存活性探测 |
readinessProbe.exec | object | 在容器中执行特定的测试命令 |
readinessProbe**.**httpGet | object | 发送 HTTP GET 请求测试容器是否就绪 |
readinessProbe.tcpSocket | object | 对指定的 TCP 端口进行连接测试 |
readinessProbe.failureThreshold | integer | 在连续检测失败 N 次后,认定该容器处于未就绪状态 |
readinessProbe.initialDelaySeconds | integer | 在 Pod 启动 N 秒后开始执行检测 |
readinessProbe.periodSeconds | integer | 两次检测的间隔时间(默认 10s) |
readinessProbe.successThreshold | integer | 连续 N 次测试成功后将容器视为已就绪,默认为 1,意味着需要连续成功通过 2 次测试 |
readinessProbe.timeoutSeconds | integer | 超时时间,在指定的时间内未获得响应,视为测试失败 |
使用
与livenessProbe的使用方法基本相同
启动探针
启动探针(startupProbe)是 Kubernetes 中的一种探针类型,专门用于判断容器“是否启动完成”。它和 livenessProbe、readinessProbe 一样是容器探针的一种,但功能和用途不同。
启动探针适合启动时间较长的服务。只有在启动成功后,Kubernetes 才会开始执行 livenessProbe 和 readinessProbe。
为什么需要启动探针
一些服务(如 Java/SpringBoot、数据库等)启动时间长,在启动前就执行了 livenessProbe,容易被误判为“卡死”而重启,导致 “启动失败死循环”。
使用 startupProbe 可以防止这种情况
- 容器启动期间只执行
startupProbe startupProbe成功后,才开始执行livenessProbe和readinessProbe
启动探针与就绪性探针和存活性探针一样,也有 exec, httpGet 和 tcpSocket 三种方法
示例
为 SpringBoot 应用配置启动探针
apiVersion: v1
kind: Pod
metadata:
labels:
run: java-app
name: java-app
spec:
containers:
- image: java-app:v1
name: java-app
ports:
- containerPort: 80
startupProbe:
periodSeconds: 5
failureThreshold: 12 # 最大启动容忍时间 5 * 12s = 60s
timeoutSeconds: 3
httpGet:
path: /actuator/health
port: 8000
restartPolicy: Always
kubectl 命令查看 Pod 状态时的探测结果
使用 kubectl 命令查看 pod 状态时,有一个 READY 字段,该字段通常是 1/1 或 0/1,前者代表 Pod 存活且已就绪,后者代表 Pod 存活但未就绪。
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5947598c79-zbs52 1/1 Running 3 (84m ago) 9d
calico-node-7ts8z 1/1 Running 3 (84m ago) 9d
coredns-79b94494c7-q5jgb 1/1 Running 2 (84m ago) 7d2h
hostpath-provisioner-c778b7559-t8xrd 1/1 Running 3 (84m ago) 7d2h
讨论
文章中的问题、补充与不同观点,欢迎在这里交流。