【云原生】Kubernetes(k8s)之容器的探测

时间:2021-10-01 01:13:52

一、探测类型及使用场景

1.1、startupProbe(启动探测)

指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被禁用,直到此探针成功为止。探测成功之后,启动探测停止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。

使用场景:
容器需要较长时间才能启动就绪的 Pod ,可以指定启动探针。那么可以避免设置一个超长时间间隔的存活探测。例如:容器需要在启动期间加载大型数据、配置文件或执行迁移等

1.2、readinessProbe(就绪探测)

指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。就绪探测失败时,不会杀死容器进程,只会将端点从service中移除,使其收不到流量。

使用场景:

  1. 仅在探测成功时才开始向 Pod 发送请求流量,意味着pod只在探测成功之后才开始接受请求数据。
  2. 如果应用程序对后端服务有严格的依赖性,可以同时实现存活态和就绪态探针,存活态探针检测通过后,可以通过就绪态探针会额外检查每个所需的后端服务是否可用

1.3、livenessProbe(存活探测)

指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success。

使用场景:

  1. 如果希望容器在探测失败时被杀死并重新启动,并指定 restartPolicy 为 “Always” 或"OnFailure"。
  2. 如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,可以不需要指定存活探针。kubelet 将根据 Pod 的 restartPolicy 自动执行修复操作。

二、检查机制

(1)exec。在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
(2)httpGet。对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于400,则诊断被认为是成功的。
(3)tcpSocket。对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。
(4)grpc。使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC健康检查。 如果响应的状态是 “SERVING”,则认为诊断成功。 gRPC 探针是一个 alpha 特性,只有在你启用了 “GRPCContainerProbe” 特性时才能使用。

三、探测结果

(1)Success(成功),容器通过了诊断。
(2)Failure(失败),容器未通过诊断。
(3)Unknown(未知),诊断失败,因此不会采取任何行动。

四、容器探测案例

apiVersion: v1
kind: Pod
metadata:
  name: myhello-pod
  namespace: default
  labels:
    name: myhello-pod
    env: dev
spec:
  restartPolicy: Always
  initContainers:
  - name: init-myservice
    image: busybox
    # 查找命名空间下myservice服务,如果存在则执行成功,如果不存在则一直查找
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox
    # 查找命名空间下mydb服务,如果存在则执行成功,如果不存在则一直查找
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
  containers:
  - name: myhello
    image: nongtengfei/hello:curl
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    command: ["./app"]
    args: ["--param1=k8s-p1", "--param2=k8s-p2"]
    resources:
      limits:
        cpu: 200m
        memory: 500Mi
      requests:
        cpu: 100m
        memory: 200Mi
    env: # 注入到容器的环境变量
    - name: env1
      value: "k8s-env1"
    - name: env2
      value: "k8s-env2"
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c","echo post start command exec >> /tmp/data"]
      preStop:
        exec:
          command: ["/bin/sh", "-c","echo pre stop command exec >> /tmp/data"]
    startupProbe:
      exec:
        command: ["/bin/sh", "-c","statuscode=`curl -o /dev/null -s -w % {http_code} http://localhost/healthz`; [ $$statuscode -le 400 ] || exit 1"]
      # 指定初始化时间,即探针在容器启动之后的延迟时长
      initialDelaySeconds: 5
      # 探测周期,即每隔多长时间探测一次
      periodSeconds: 5
      # 最小连续失败次数,即连续失败多少次表示探测失败
      failureThreshold: 3
      # 最小连续成功次数,即连续探测成功多少次表示探测成功,liveness 和 startup 必须为1
      successThreshold: 1
      # 探测超时时间
      timeoutSeconds: 1
    readinessProbe:
      httpGet:
        path: /health
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5
      failureThreshold: 3
      successThreshold: 1
      timeoutSeconds: 1
    livenessProbe:
      httpGet:
        path: /health
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5
      failureThreshold: 3
      successThreshold: 1
      timeoutSeconds: 1
  - name: myredis #容器的名称
    image: redis #容器对应的 Docker Image
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 6379
    resources:
      limits:
        cpu: 200m
        memory: 500Mi
      requests:
        cpu: 100m
        memory: 200Mi
    livenessProbe:
      tcpSocket:
        port: 6379
      initialDelaySeconds: 5
      periodSeconds: 5
      failureThreshold: 3
      successThreshold: 1
      timeoutSeconds: 1

【云原生】Kubernetes(k8s)之容器的探测