需求来源
- 当应用迁移到K8s后,要如何保障应用健康稳定?
- 提高应用的可观测性,提高应用的可恢复能力
- 应用的状态可以被实时观测
- 应用健康状态
- 应用资源使用
- 应用实时日志
- 应用出现问题需要降低影响范围,进行问题调试、诊断
- 应用出现问题可以通过自愈机制恢复
Liveness与Readiness
应用健康状态-Liveness与Readiness
当应用的Pod已经运行起来,如何让K8s检查应用的状态,判断是否已经准备好对外提供服务?
- Readiness指针主要监控Pod状态,决定是否转发流量
- Liveness指针监控Pod是否存活,根据策略决定是否拉起
应用健康状态-使用方式
- 探测方式
- httpGet 通过发送http GET请求返回200-399状态码则表明容器健康
- Exec 通过执行命令来检查服务是否正常,命令返回值为0则表示容器健康
- tcpSocket 通过容器的IP和Port执行TCP检查,如果能够建立TCP链接则表明容器健康
- 探测结果
- Success container通过了检查
- Failure Container未通过检查
- Unknown 未能执行检查,不采取任何动作
- 重启策略
- Always 总是重启
- OnFailure 失败才重启
- Never 永远不重启
应用健康状态-pod probe spec
- initialDelaySeconds Pod启动后延迟多久进行检查,单位秒
- periodSeconds 检查的时间间隔,默认为10秒
- timeoutSeconds 检测的超时时间,默认为1秒
- successThreshold 探测失败后再次判断成功的阈值,默认为一次
- failureThreshold 探测失败的重启次数,默认为3次
应用健康状态-Liveness与Readiness的总结
问题诊断
应用故障排查-常见应用异常
- Pod停留在Pending
- pending表示调度器没有介入,可以通过kubectl describe pod,查看时间排查,通常和资源使用相关
- pod停留在waiting
- 一般表示Pod的镜像没有正常的拉取,通常可能和私有镜像拉取,镜像地址不存在,镜像公网拉去有关
- Pod不断被拉起且可以看到crashing
- 通常表示Pod已经完成调度并启动,但是启动失败,通常是由于配置、权限造成,需查看Pod日志
- Pod处于Running但是没有正常工作
- 通常是由于部分字段拼写错误造成的,可以通过校验部署来排查,例如:kubectl apply -validate -f pod.yaml
- Service 无法正常工作
- 在排除网络插件自身的问题外,最可能的是label配置有问题,可以通过查看endpoint的方式进行检查。
应用远程调试
Pod远程调试
- 当我们把一个应用部署到集群中发现问题需要快速进行验证修改时,可以通过远程调试的方式进行修改、验证。
- 进入一个正在运行的Pod
- kubectl exec -it pod-name /bin/bash
- 进入一个正在运行包含多容器的Pod
- kubectl exec -it pod-name -c container-name /bin/bash
service远程调试
- 当集群中应用依赖的应用需要本地调试时:
- 可以使用Telepresence将本地的应用代理到集群中的一个Service上
- Telepresence -swap-deploymeny $DEPLOYMENT_NAME
- 可以使用Telepresence将本地的应用代理到集群中的一个Service上
- 当本地开发的应用需要调用集群中的服务时:
- 可以使用Port-Forward将远程的应用代理到本地的端口上
- kubectl port-forward svc/app -n app-namespace
- 可以使用Port-Forward将远程的应用代理到本地的端口上
开源的调试工具-kubectl-debug
总结
- 应用状态探针与自动恢复
- Liveness Probe保活探针
- Readiness Probe就绪探针
- 应用问题诊断的三个步骤
- 通过describe查看状态,通过状态判断排查方向
- 查看对象的event事件,获取更详细的信息
- 查看Pod的日志确定应用自身的情况
- 应用远程调试
- 代理本地应用到集群-Telepresence
- 代理远程应用到本地-Port-Forward