Kubernetes-POD的健康检查

简介

在Pod的生命周期中,可以执行多种操作如下图:

  1. 初始化容器:主容器启动前,可以先运行一个或多个初始化容器。初始化容器是串行执行的,必须全部成功完成后才会启动主容器。初始化容器运行结束后即退出,不再占用资源。
  2. Post Start钩子:主容器启动后,可以指定一个Post Start钩子,用于在主容器启动后执行一些额外的操作。
  3. Pre Stop钩子:在主容器终止之前,可以指定一个Pre Stop钩子,用于在主容器结束前执行必要的清理或其他操作。
  4. 健康探针:Pod启动后,其健康状态由以下几类探针进行检测:
    • Startup Probe(启动探针):用于确保容器成功启动,在启动完成前其他探针不会干扰容器的启动过程。
    • Liveness Probe(存活探针):用于检测容器是否存活。如果探测失败,Kubernetes会重启该容器。
    • Readiness Probe(就绪探针):用于检测容器是否已准备好接收流量。如果探测失败,该Pod将暂时从服务端点中移除,直到其恢复就绪状态。

什么是探针

在Kubernetes中,探针(Probe)用于管理容器的生命周期,主要包括以下三种类型:

Liveness Probe(存活探针)

  • 作用:判断容器是否处于运行状态(即容器是否存活)。
  • 行为
    1. 如果Liveness Probe探测到容器处于非健康状态,kubelet会杀掉该容器,并根据容器的重启策略进行处理。
    2. 如果未配置Liveness Probe,kubelet会默认认为容器始终处于“成功”状态。
  • 场景:Liveness Probe用于捕捉容器死锁等问题。例如,当应用程序虽然运行但无法处理请求时,探针会检测到这个问题,并重启容器,使应用在存在bug的情况下依然能够继续运行。

Readiness Probe(就绪探针)

  • 作用:判断容器是否已启动完成并准备好接受请求。
  • 行为
    1. 如果Readiness Probe探测失败,Pod的状态会被修改,Endpoint Controller会将该Pod从Service的Endpoint中移除。
    2. 如果未配置Readiness Probe,kubelet会默认认为容器处于“成功”状态。
  • 场景:Readiness Probe用于控制哪些Pod可以作为Service的后端。如果Pod处于非就绪状态,它将被从Service的负载均衡中移除。

Startup Probe(启动探针)

  • 作用:检测应用程序是否已完全启动。
  • 行为
    1. 在Startup Probe成功之前,其他探针(Liveness和Readiness)将被禁用。
    2. 如果Startup Probe探测失败,kubelet将终止容器并根据重启策略重启它。
    3. 如果未配置Startup Probe,kubelet会默认认为容器已成功启动。
  • 场景:Startup Probe适用于启动时间较长的应用程序,确保应用完全启动后再启用其他探针。

通过合理配置这三类探针,可以确保Kubernetes中的容器在生命周期的各个阶段都处于健康状态,并能够及时处理异常情况。

什么时候使用探针?

何时使用存活探针(Liveness Probe)

  • 容器可能卡死或无响应:如果你的应用程序在遇到问题时可能卡死或进入无响应状态,而不会自行崩溃,那么就应该使用存活探针。Liveness Probe 可以检测到这些状态,并触发 kubelet 终止并重启容器。
  • 确保自动重启:如果你希望容器在探测失败时被杀死并重新启动,以确保应用的持续可用性,那么应配置存活探针。此时,可以将 restartPolicy 设置为 AlwaysOnFailure,以确保在探针检测到问题时容器能够自动重启。

何时使用就绪探针(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秒内重启了两次

image.png

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 ProbeReadiness Probe 都因为无法找到 /tmp/nginx-healthy 文件而失败。这是由于容器中的命令在 60 秒后删除了该文件,导致探针在检查时无法访问该文件。

  • Liveness Probe 失败触发了容器重启。此探针用于检测容器是否健康,不健康时会重启容器。
  • Readiness Probe 失败使得 Pod 从 Service 的 Endpoints 列表中移除,导致 Pod 无法接收流量。这表示 Pod 当前无法处理请求。

image.png
image.png
image.png

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
posted @ 2024-08-10 20:22  &UnstopPable  阅读(8)  评论(0编辑  收藏  举报