笔者:张首富
时间:2022-04-15
w x:y18163201

背景

我们在真实的生产环境中,在启动服务的时候可能会有先后顺序,比如服务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。

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/