1. 故事背景

本来我从未关注过官方这篇文章Istio Service 健康检查,因为这不是属于K8S的自带的功能吗?而且你看那篇文章,通篇说的都是TLS相关的。所以这次说的并不是和这篇文章有关的内容,而是在我使用Istio后,对于健康检查上遇到的坑。

2. 提前准备

  • 本次试验是在CentOS 7.4 64位系统,root用户下进行
  • Kubernetes(k8s)集群
  • istio版本1.0.2
  • SpringBoot项目

3. 实践

K8S存在两类探针,liveness和readiness,前者用于检查项目是否存货,后者检查项目是否就绪(是否可以提供服务了)。两类探针均有三种方式去检查:

  • 命令
  • tcp请求
  • http请求

我当时使用的是readiness探针,目的是检查SpringBoot项目是不是已经启动成功了,同时选用了tcp请求的方式,只检查对应的端口是否已经打开(理论上,项目启动成功,端口才会打开),配置代码截选如下:

# 监听13193端口是否打开,5秒后开始监听,每隔10秒一次
readinessProbe:
  tcpSocket:
    port: 13193
  initialDelaySeconds: 5
  periodSeconds: 10

这样的配置,运行十分正常,每当滚动更新的时候,Service都可以正常加入和移除对应的pod,从而几乎没有服务中断的过程。这样的好日子,知道使用了Istio后,发生了改变。

在我不经历间发现,滚动更新居然发生了服务中断,我这什么配置都没改啊,我当时就把怀疑对象放在Istio上,是不是需要额外配置什么,国内国外翻了一遍,中文英文搜了一轮,并没有相关有帮助的内容。

陷入沉思,因为Istio掌管了整个网络,而方式是使用sidecar模式,往pod里面放入一个代理Envoy。我就琢磨,是不是其实端口是已经打开了,但是网络代理还没有通?所以是不是我不检查端口,而是检查项目对应的接口呢?

于是我修改成http请求的方式,新增/health接口(什么都没干,直接返回200):

readinessProbe:
  httpGet:
    path: /health
  port: 13193
  initialDelaySeconds: 5
  periodSeconds: 10

没想到,从前滚动更新的效果回来了!

4. 总结

  1. 别偷懒,http请求检查比较靠谱
  2. 如果你发现整个世界都没有,要怀疑自己
  3. 以上两条不正确,有时间真的要深入了解原理