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

 

发表评论