运用背景
当前打榜平台在去创建被测服务的时候,会根据被测服务 POD 的 Ready 状态来去判断被测服务 POD 是否准备就绪。然而,这存在一个问题,有的服务可能在启动后,还需要执行一些指令才算真的可以对外服务。如果这个时候,直接开始测试流程,与被测服务通信、发送数据,往往会请求失败。
最开始,使用了两种非常简单的方式来避免这个问题。
一种是,在测试流程开始,直接 sleep 3 分钟,推迟与被测服务通信的时间。
一种是,为测试流程的第一次请求增加重试机制,在一定的重试次数限制下进行测试。
然而,这两种方式都不够优雅。
最后了解到 K8S 有一个 readinessProbe 属性,可以用来更改 POD 的就绪检查机制。
使用 readinessProbe 解决 ready 需求
从官网中 copy 一个例子,内容如下。
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: registry.k8s.io/liveness
args:
- /server
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 3readinessProbe 可以配置 httpGet 属性,代表 K8S 通过 get 请求 POD 的某个路径来判断 POD 服务是否真的处于 Ready 状态。
各个参数的含义如下:
- path:http 请求路径
- port:服务端口号
- initialDelaySeconds:POD 拉起后多久进行第一次 readiness 检测
- periodSeconds:两次 readiness 检测的时间
这样,被测服务只需要补充一个 /healthz 接口,在自身真正准备好了后,返回一个 200 状态码;当自身没有准备好时,返回一个大于 399 的状态码就可以。这样就可以优雅的实现上面的需求了。
各种 readinessProbe 方案
通过执行 command 来判断
当 command 在容器中执行后返回非 0 状态时,容器被认为是非就绪状态。
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5通过执行 HTTP GET 请求来判断
如果收到的 HTTP 状态码在 200 到 399 之间,则认为 Pod 已经就绪。每隔 5 秒钟,Kubernetes 都会重复进行一次检查。
如果应用暂时无法处理请求,则返回一个非 200-399 的状态码,这样 Kubernetes 就会让该 Pod 暂时不参与服务,直至 readiness probe 成功。
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5通过 TCP Socket 探测
K8S 尝试建立到容器的 TCP 连接。如果探针能够建立连接,那么健康检查就认为成功;反之,如果连接失败,则认为探针检查失败。
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 5