容器

Kubernetes学习笔记四:容器钩子与探针

使用Kubernetes的容器钩子与探针执行在Pod生命周期内指定时间点的特定操作以及通过探针确定容器是否就绪或存活

容器钩子

容器钩子(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 用于检测容器是否处于运行状态的一种机制,它定期向容器发送一个请求,并根据结果判断容器是否正在运行。

语法

字段类型说明
livenessProbeobject存活性探测
livenessProbe.execobject在容器中执行特定的测试命令
livenessProbe**.**httpGetobject发送 HTTP GET 请求测试容器活性
livenessProbe.tcpSocketobject对指定的 TCP 端口进行连接测试
livenessProbe.failureThresholdinteger在连续检测失败 N 次后,认定该容器已终止
livenessProbe.initialDelaySecondsinteger在 Pod 启动 N 秒后开始执行检测
livenessProbe.periodSecondsinteger两次检测的间隔时间(默认 10s)
livenessProbe.successThresholdinteger连续 N 次测试成功后将容器视为成功启动,默认为 1,意味着需要连续成功通过 2 次测试
livenessProbe.terminationGracePeriodSecondsinteger在容器终止前等待的时间,以便让容器执行清理和关闭连接等工作,默认值为 30s
livenessProbe.timeoutSecondsinteger超时时间,在指定的时间内未获得响应,视为测试失败

示例

  1. 使用 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
  1. 使用 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
  1. 使用 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 的方式实现。

语法

字段类型说明
readinessProbeobject存活性探测
readinessProbe.execobject在容器中执行特定的测试命令
readinessProbe**.**httpGetobject发送 HTTP GET 请求测试容器是否就绪
readinessProbe.tcpSocketobject对指定的 TCP 端口进行连接测试
readinessProbe.failureThresholdinteger在连续检测失败 N 次后,认定该容器处于未就绪状态
readinessProbe.initialDelaySecondsinteger在 Pod 启动 N 秒后开始执行检测
readinessProbe.periodSecondsinteger两次检测的间隔时间(默认 10s)
readinessProbe.successThresholdinteger连续 N 次测试成功后将容器视为已就绪,默认为 1,意味着需要连续成功通过 2 次测试
readinessProbe.timeoutSecondsinteger超时时间,在指定的时间内未获得响应,视为测试失败

使用

livenessProbe的使用方法基本相同

启动探针

启动探针(startupProbe)是 Kubernetes 中的一种探针类型,专门用于判断容器“是否启动完成”。它和 livenessProbereadinessProbe 一样是容器探针的一种,但功能和用途不同。

启动探针适合启动时间较长的服务。只有在启动成功后,Kubernetes 才会开始执行 livenessProbereadinessProbe

为什么需要启动探针

一些服务(如 Java/SpringBoot、数据库等)启动时间长,在启动前就执行了 livenessProbe,容易被误判为“卡死”而重启,导致 “启动失败死循环”。

使用 startupProbe 可以防止这种情况

  • 容器启动期间只执行 startupProbe
  • startupProbe 成功后,才开始执行 livenessProbereadinessProbe

启动探针与就绪性探针和存活性探针一样,也有 exec, httpGettcpSocket 三种方法

示例

为 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/10/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

讨论

文章中的问题、补充与不同观点,欢迎在这里交流。