Kubernetes 应用健康检查

应用的状态可以被实时观测:

  1. 健康状态资源使用
  2. 实时日志
  3. Liveness Probe(就绪探针)
  4. Readness(存活探针)

应用健康状态

探测方式

  • httpGet 发送 HTTP 请求返回200-399状态码表明容器健康
  • Exec 通过执行命令来检查服务是否正常,命令返回0表示容器健康
  • tcpSocket 通过容器的 IP 和端口执行 TCP 检查,如果能够建立 TCP 连接表示容器健康

 

探测结果

  • Success 容器通过了检查
  • Failure 容器未通过检查
  • Unknown 未能执行检查,不采取任何操作

 

重启策略

  • Always 总是重启
  • OnFailure 失败才重启
  • Never 永不重启

API 对象

exec

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;
    livenessProb:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

 

httpGet

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProb:
      httpGet:
        path: /healthz
        port: 8000
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 5
      periodSeconds: 5

 

tcpSocket

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8000
    readnessProbe:
      tcpSocket:
        port: 8000
      initialDelaySeconds: 5
      periodSecond: 10
    livenessProbe:
      tcpSocket:
        port: 8000
      initialDelaySeconds: 5
      periodSecond: 20

 

参数

  • initialDelaySeconds Pod 启动后延迟多久进行检查
  • periodSeconds 检查的间隔时间
  • timeoutSeconds 探测的超时时间
  • successThreshold 探测失败后再次判断成功的阈值
  • failureThreshold 探测失败的重试次数

 

Liveness(存活探针) Readness(就绪探针)
作用 用于判断容器是否存活,即 Pod 状态是否为 Running,如果 Liveness 探针判断容器不健康,会触发 kubelet 杀掉容器,并根据配置的策略判断是否重启容器,如果不配置 Liveness 探针,则认为返回值默认为成功。 用于判断容器是否启动完成,即 Pod 是否为 Ready,如果探测结果不成功,会将 Pod 从 Endpoint 中移除,直至下次判断成功,再将 Pod 挂回到 Endpoint 上。
检测失败 杀掉 Pod 切断上层流量到 Pod
适用场景 支持重新拉起的应用 启动后无法立即对外服务的应用

注意事项

  • 调大判断的超时阈值,防止在容器压力较高的情况下出现偶发超时
  • 调整判断的次数阈值,3次默认值在短周期下不一定是最佳实践
  • exec 如果执行的是 shell 脚本判断,在容器中可能调用时间会非常长
  • 使用 tcpSocket 的方式遇到 TLS 场景,需要业务层判断是否有影响

 

应用故障排查

Pod 停留在 Pending❓

调度器没有介入,可以通过 kubectl describe pod,查看事件排查,通常和资源使用相关

 

Pod 停留在 waiting❓

一般表示 Pod 的镜像没有正常拉取

 

Pod 不断被拉起且可以看到 crashing❓

通常表示 Pod 已经完成调度并启动,但是启动失败,通常是由于配置、权限造成,需要查看 Pod 日志

 

Pod 处在 Running 但是没有正常工作❓

通常是由于部分字段拼写错误造成的,可通过校验部署来排查 kubectl apply -validate -f pod.yaml

 

Service 无法正常工作❓

在排除网络插件自身的问题外,最可能的是 label 配置有问题,可以通过查看 endpoint 的方式进行检查

 

应用远程调试

进入一个正在运行的 Pod❓

$ kubectl exec -it pod_name /bin/bash

 

进入一个正在运行包含多容器的 Pod❓

$ kubectl exec -it pod_name -c container_name /bin/bash

 

Service 远程调试

当集群中应用依赖的应用需要本地调试时: 可以使用 Telepresence 将本地的应用代理到集群中的一个 Service 上

Telepresence --swap-deployment $DEPLOYMENT_NAME

 

当本地开发的应用需要调用集群中的服务时: 可以使用 Port-Forward 将远程的应用代理到本地的端口上

$ kubectl port-forward svc/app -n app_namespace

 

kubectl-debug 调试工具

https://github.com/aylei/kubectl-debug

 

发表评论