笔者:张首富
时间:2022-04-15
背景
我们在真实的生产环境中,在启动服务的时候可能会有先后顺序,比如服务A不启动成功,服务器B无法启动,服务B不启动成功服务器C又无法启动。所以这个时候我们该怎么办呢?想到的第一种方法就是使用探针,但是细想一下发现探针又好像不能完成我们的需求。(探针并不能控制不让服务启动,只能探测服务是否启动完成)
这个时候就去翻官网,发现init 容器好像能满足我们的需求
Init containers
官方文档:https://kubernetes.io/zh/docs/concepts/workloads/pods/init-containers/
我们这个地方来摘取符合我们上面需求的部分。
init containers 是什么?
Init 容器是一种特殊容器,在 Pod内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。
你可以在 Pod 的规约中与用来描述应用容器的 containers
数组平行的位置指定 Init 容器。(init 容器是按照yaml文件的书写顺序来顺序执行的,只有等上一个执行成功并结束才会执行下一个)
理解 init containers
每个 Pod中可以包含多个容器, 应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
Init 容器与普通的容器非常像,除了如下两点:
- 它们总是运行到完成。
- 每个都必须在下一个启动之前成功完成。
如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 然而,如果 Pod 对应的 restartPolicy
值为 "Never",并且 Pod 的 Init 容器失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。
看到这是不是就明白了,init containers 就是我们需要的东西,他就是我们的救世主。我们可以在POD B内添加一个init containers容器.这个容器的作用就是去探测pod A是否正常启动,这个探测可以是http 也可以是TCP的。(看你脚本如何写了)
截止到这个地方我们的问题就得以解决了。其他init pod相关的就自己去看官方文档吧
例子
serviceA服务依赖serviceB,而serviceB采用上文提及Readness探针的HTTPGetAction Handler。
代码语言:javascript复制spec:
initContainers:
- name: init-serviceA
image: registry.docker.dev.fwmrm.net/busybox:latest
command: ['sh', '-c', "curl --connect-timeout 3 --max-time 5 --retry 10 --retry-delay 5 --retry-max-time 60 serviceB:portB/pathB/"]
containers:
参考文档:
https://dockone.io/article/2587
https://kubernetes.io/zh/docs/concepts/workloads/pods/init-containers/