Pod探针、钩子
Pod常用操作
1、更改pod启动命令和参数
# vim nginx.yaml
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:stable # 必选,容器所用的镜像的地址
command: # 可选,容器启动执行的命令
- sleep
- "600"
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
2、分配CPU和内存
root@VM-26-198-ubuntu:/usr/local/src/study# cat pod.yaml
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
namespace: test
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:stable # 必选,容器所用的镜像的地址
resources:
requests:
memory: "100Mi"
cpu: 100m
command: # 可选,容器启动执行的命令
- sleep
- "600"
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
request:容器启动所需的最低资源量
- 调度依据:k8s调度器根据
requests
的值选择节点,只有当pod
所在的节点的可用资源大于等于pod
中所有容器的requests
总和时,pod
才会被调度到该节点。 - 资源预留:为容器预留最低资源保障,避免资源不足时被其他容器抢占。
limits:
资源上限:限制容器运行时可使用的最大资源量,如果超过限制:
- cpu:会被限制使用频率(通过Cgroup的cpu.cfs_quota_us实现)
- 内存:触发OOMKiller终止容器。
3、Pod配置环境变量及内置字段
root@VM-26-198-ubuntu:/usr/local/src/study# cat pod.yaml
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
namespace: test
labels:
env: prod
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:stable # 必选,容器所用的镜像的地址
resources:
requests:
memory: "100Mi"
cpu: 100m
env:
- name: ENV
value: test
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: LABEL_APP
valueFrom:
fieldRef:
fieldPath: metadata.labels['env']
command: # 可选,容器启动执行的命令
- sleep
- "600"
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
root@VM-26-198-ubuntu:/usr/local/src/study#
root@VM-26-198-ubuntu:/usr/local/src/study# kubectl exec nginx -n test env
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx
ENV=test
POD_NAME=nginx
POD_NAMESPACE=test
POD_NODE_NAME=10.122.26.235
POD_IP=172.16.4.110
LABEL_APP=prod
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://172.16.192.1:443
KUBERNETES_PORT_443_TCP=tcp://172.16.192.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=172.16.192.1
KUBERNETES_SERVICE_HOST=172.16.192.1
NGINX_VERSION=1.22.0
NJS_VERSION=0.7.6
PKG_RELEASE=1~bullseye
HOME=/root
实际案例:
可选的内置字段:
metadata.name
metadata.namespace
metadata.uid
metadata.labels[xxx]
metadata.annotations[xxx]
spec.nodeName
spec.serviceAccountName
status.hostIP
status.hostIPs
status.podIP
status.podIPs
4、探针
startupProbe
:启动探针,判断容器内应用是否已经启动,如果配置了该探针,就会先禁用其他探测,直到他完成。如果探测失败,kubelet会杀死容器,之后根据重启策略进行处理,如果探测成功,或者没有配置startupProbe。则状态为成功,之后就不再探测。
- 适用场景:启动时间较长的应用(如Java服务),避免存活/就绪探针在初始化阶段误判。
livenessProbe
:存活探针,用于探测容器是否存活,如果探测失败,kubelet会杀死容器并根据重启策略进行相应处理。如果未指定,默认为success
- 适用场景:检测应用死锁、进程阻塞等长期不可用状态。例如,Web服务无响应时触发重启。
readnessProbe
:就绪探针,一般用于探测容器内应用是否健康,判断应用是否可以提供服务,如果可以则可以处理用户请求(添加到service),如果不健康,endpointscontroller将从所有的service的endpoints中删除次容器所在Pod的Ip地址。
- 适用场景:应用启动依赖外部服务(如数据库)时,确保依赖就绪后再开放流量。
####### 1. HTTP GET探测
- 方法:向容器指定端口和路径发送HTTP请求,通过状态码(2xx/3xx)判断成功。
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30 # 容器启动后等待30秒开始探测
periodSeconds: 10 # 每10秒探测一次
适用场景:Web服务、API服务等HTTP应用的健康检查
####### 2.TCP Socket探测
- 方法:尝试与容器指定端口建立TCP连接,成功即视为健康。
readinessProbe:
tcpSocket:
port: 3306
timeoutSeconds: 5 # 超时时间设为5秒
####### 3. Exec命令探测
- 方法:执行容器内自定义命令,返回值为0表示成功,否则失败。
startupProbe:
exec:
command:
- sh
- -c
- "ps -ef | grep java" # 检查Java进程是否存在
failureThreshold: 30 # 允许失败30次(总等待时间=periodSeconds*failureThreshold)
####### 4. gRPC 探测(Kubernetes v1.24+)
定义:通过 gRPC 协议调用容器的健康检查服务,需遵循 gRPC 健康检查协议。
微服务架构中使用 gRPC 协议的应用(如 Go/Python 实现的 gRPC 服务)。
需要更高效、低延迟的健康检查(相比 HTTP)。
livenessProbe:
grpc:
port: 50051 # gRPC 服务监听端口
service: my-svc # 可选:指定健康检查的服务名(默认为空)
startupProbe:
root@VM-26-198-ubuntu:/usr/local/src/study# cat pod.yaml
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
namespace: test
labels:
env: prod
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:stable # 必选,容器所用的镜像的地址
resources:
requests:
memory: "100Mi"
cpu: 100m
readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
httpGet: # 接口检测方式
path: /index.html # 检查路径
port: 80
scheme: HTTP # HTTP or HTTPS
#httpHeaders: # 可选, 检查的请求头
#- name: end-user
# value: Jason
initialDelaySeconds: 10 # 初始化时间, 健康检查延迟执行时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功 1 次表示就绪
failureThreshold: 2 # 检测失败 2 次表示未就绪
livenessProbe: # 可选,健康检查
tcpSocket: # 端口检测方式
port: 80
initialDelaySeconds: 10 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功 1 次表示就绪
failureThreshold: 2 # 检测失败 2 次表示未就绪
startupProbe:
tcpSocket: # 端口检测方式
port: 80
initialDelaySeconds: 10 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功 1 次表示就绪
failureThreshold: 2 # 检测失败 2 次表示未就绪
env:
- name: ENV
value: test
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: LABEL_APP
valueFrom:
fieldRef:
fieldPath: metadata.labels['env']
command: # 可选,容器启动执行的命令
- sleep
- "30"
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
5、启动前和启动后钩子
postStart
- 作用与触发时机
- 作用:在容器启动后立即执行自定义操作,通常用于初始化配置或启动辅助进程。
- 触发时机:容器创建完成后异步触发,与主进程并行执行(不阻塞容器启动)
支持两种执行方式:
- Exec命令:在容器内执行脚本或命令。
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo '容器已启动' > /tmp/start.log"]
- HTTP请求:向容器内指定路径发送HTTP GET请求。
lifecycle:
postStart:
httpGet:
path: /init
port: 8080
2. 典型使用场景
- 初始化配置:生成配置文件或修改环境变量。
Textcommand: ["/bin/sh", "-c", "cp /app/config_template.yml /app/config.yml"]
- 依赖下载:启动时拉取动态配置或数据文件。
- 服务注册:向注册中心(如Consul)发送服务上线通知。
- 日志标记:记录容器启动时间或版本信息。
3. 注意事项
- 异步执行:钩子执行与容器主进程并发,无法保证执行顺序[1]。
- 超时限制:默认30秒内未完成则强制终止钩子[2]。
- 失败处理:若钩子执行失败,容器会被杀死并根据
restartPolicy
重启[
使用较少,一般用initContainer初始化配置
preStop(零宕机发版)
1. 作用与触发时机
- 作用:在容器终止前执行清理操作,确保服务优雅关闭。
- 触发时机:收到终止信号(如Pod删除或滚动更新)后同步触发,必须完成后才会发送SIGTERM/SIGKILL
Exec命令:
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 30; nginx -s quit"]
HTTP请求:
lifecycle:
preStop:
httpGet:
path: /graceful-shutdown
port: 8080
3.典型使用场景
- 优雅关闭服务:通知应用处理完现有请求后再退出。
最佳的使用方法是让开发提供一个接口,来下线剔除pod IP,要么就配置sleep
Textcommand: ["/bin/sh", "-c", "kill -SIGTERM $(pidof app) && sleep 10"]
- 服务注销:从注册中心(如Eureka)移除当前实例。
- 资源释放:关闭数据库连接或释放文件锁。
- 日志归档:将未持久化的日志上传到存储系统。
4.注意事项
- 超时处理:若钩子执行超过默认30秒,仍会强制终止容器
- 必要性:强烈建议配置preStop,避免流量中断(尤其是HTTP服务)
- 与terminationGracePeriodSeconds配合:延长优雅关闭时间窗口。
Textspec: terminationGracePeriodSeconds: 60 # 默认30秒,可调整