美文网首页K8S容器编排最佳实践
K8S容器编排之POD健康检测(1)

K8S容器编排之POD健康检测(1)

作者: 云爬虫技术研究笔记 | 来源:发表于2019-01-09 00:33 被阅读8703次

    Pod健康检测机制

    对于Pod的健康状态检测,kubernetes提供了两类探针(Probe)来执行对Pod的健康状态检测:

    • LivenessProbe探针:

    用于判断容器是否存活,即Pod是否为running状态,如果LivenessProbe探针探测到容器不健康,则kubelet将kill掉容器,并根据容器的重启策略是否重启,如果一个容器不包含LivenessProbe探针,则Kubelet认为容器的LivenessProbe探针的返回值永远成功。

    • ReadinessProbe探针:

    用于判断容器是否启动完成,即容器的Ready是否为True,可以接收请求,如果ReadinessProbe探测失败,则容器的Ready将为False,控制器将此PodEndpoint从对应的serviceEndpoint列表中移除,从此不再将任何请求调度此Pod上,直到下次探测成功。


    每类探针都支持三种探测方法:

    • exec:通过执行命令来检查服务是否正常,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康。

    • httpGet:通过发送http请求检查服务是否正常,返回200-399状态码则表明容器健康。

    • tcpSocket:通过容器的IP和Port执行TCP检查,如果能够建立TCP连接,则表明容器健康。
      探针探测的结果有以下三者之一:

    • Success:Container通过了检查。

    • Failure:Container未通过检查。

    • Unknown:未能执行检查,因此不采取任何措施。


    LivenessProbe探针配置

    示例一:通过exec方式做健康探测

    exec-liveness.yaml  
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        test: liveness
      name: liveness-exec
    spec:
      containers:
      - name: liveness
        image: k8s.gcr.io/busybox
        args:
        - /bin/sh
        - -c
        - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 5
          periodSeconds: 5
    

    在该配置文件中,对容器执行livenessProbe检查,periodSeconds字段指定kubelet每5s执行一次检查,检查的命令为cat /tmp/healthyinitialDelaySeconds字段告诉kubelet应该在执行第一次检查之前等待5秒,
    如果命令执行成功,则返回0,那么kubelet就认为容器是健康的,如果为非0,则Kubelet会Kill掉容器并根据重启策略来决定是否需要重启。

    当容器启动时,它会执行以下命令:

     /bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
    

    对于容器的前30秒,有一个/tmp/healthy文件。因此,在前30秒内,该命令cat /tmp/healthy返回成功代码。30秒后,cat /tmp/healthy返回失败代码。

    创建Pod:

    kubectl create -f https://k8s.io/examples/pods/probe/exec-liveness.yaml
    

    30秒内,查看Pod事件

    kubectl describe pod liveness-exec
    

    输出表明尚未探测到失败

    FirstSeen    LastSeen    Count   From            SubobjectPath           Type        Reason      Message
    --------- --------    -----   ----            -------------           --------    ------      -------
    24s       24s     1   {default-scheduler }                    Normal      Scheduled   Successfully assigned liveness-exec to worker0
    23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulling     pulling image "k8s.gcr.io/busybox"
    23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulled      Successfully pulled image "k8s.gcr.io/busybox"
    23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Created     Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
    23s       23s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Started     Started container with docker id 86849c15382e
    

    35秒后,再次查看Pod事件

    kubectl describe pod liveness-exec
    

    在输出的中显示探测失败,并且容器已被杀死重新创建

    FirstSeen LastSeen    Count   From            SubobjectPath           Type        Reason      Message
    --------- --------    -----   ----            -------------           --------    ------      -------
    37s       37s     1   {default-scheduler }                    Normal      Scheduled   Successfully assigned liveness-exec to worker0
    36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulling     pulling image "k8s.gcr.io/busybox"
    36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Pulled      Successfully pulled image "k8s.gcr.io/busybox"
    36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Created     Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
    36s       36s     1   {kubelet worker0}   spec.containers{liveness}   Normal      Started     Started container with docker id 86849c15382e
    2s        2s      1   {kubelet worker0}   spec.containers{liveness}   Warning     Unhealthy   Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
    

    再等30秒,确认Container已重新启动

    kubectl get pod liveness-exec
    

    下面输出中RESTARTS的次数已增加:

    AME            READY     STATUS    RESTARTS   AGE
    liveness-exec   1/1       Running   1          1m
    

    示例二:通过HTTP方式做健康探测

    pods/probe/http-liveness.yaml  
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        test: liveness
      name: liveness-http
    spec:
      containers:
      - name: liveness
        image: k8s.gcr.io/liveness
        args:
        - /server
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
            httpHeaders:
            - name: X-Custom-Header
              value: Awesome
          initialDelaySeconds: 3
          periodSeconds: 3
    

    在配置文件中,使用k8s.gcr.io/liveness镜像,创建出一个Pod,其中periodSeconds字段指定kubelet每3秒执行一次探测,initialDelaySeconds字段告诉kubelet延迟等待3秒,探测方式为向容器中运行的服务发送HTTP GET请求,请求8080端口下的/healthz, 任何大于或等于200且小于400的代码表示成功。任何其他代码表示失败。

    创建此Pod

    kubectl create -f https://k8s.io/examples/pods/probe/http-liveness.yaml
    

    10秒后,查看Pod事件以验证liveness探测失败并且Container已重新启动:

    kubectl describe pod liveness-http
    

    httpGet探测方式有如下可选的控制字段

    host:要连接的主机名,默认为Pod IP,可以在http request head中设置host头部
    scheme: 用于连接host的协议,默认为HTTP
    path:http服务器上的访问URI。
    httpHeaders:自定义HTTP请求headersHTTP允许重复headers
    port: 容器上要访问端口号或名称。

    示例三:通过TCP方式做健康探测

    Kubelet将尝试在指定的端口上打开容器上的套接字,如果能建立连接,则表明容器健康。

    pods/probe/tcp-liveness-readiness.yaml  
    apiVersion: v1
    kind: Pod
    metadata:
      name: goproxy
      labels:
        app: goproxy
    spec:
      containers:
      - name: goproxy
        image: k8s.gcr.io/goproxy:0.1
        ports:
        - containerPort: 8080
        readinessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
    

    TCP检查方式HTTP检查方式非常相似,示例中两种探针都使用了,在容器启动5秒后,kubelet将发送第一个readinessProbe探针,这将连接到容器的8080端口,如果探测成功,则该Pod将被标识为ready,10秒后,kubelet将进行第二次连接。
    除此之后,此配置还包含了livenessProbe探针,在容器启动15秒后,kubelet将发送第一个livenessProbe探针,仍然尝试连接容器的8080端口,如果连接失败则重启容器。
    创建:

    kubectl create -f https://k8s.io/examples/pods/probe/tcp-liveness-readiness.yaml
    

    15秒后,查看Pod事件以验证活动探测:

    kubectl describe pod goproxy
    

    当容器有多个端口时,通常会给每个端口命名,所以在使用探针探测时,也可以直接写自定义的端口名称

    ports:
    - name: liveness-port
      containerPort: 8080
      hostPort: 8080
    livenessProbe:
      httpGet:
        path: /healthz
        port: liveness-port
    

    相关文章

      网友评论

        本文标题:K8S容器编排之POD健康检测(1)

        本文链接:https://www.haomeiwen.com/subject/bpwirqtx.html