5

在Kubernetes中实现Sidecar类型的Container

 3 years ago
source link: https://note.qidong.name/2020/10/k8s-pod-sidecar/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在Kubernetes中实现Sidecar类型的Container

2020-10-24 10:25:51 +08  字数:1824  标签: K8s

在一个Pod中,某个Container运行主要业务的同时,需要另一个Container协同 ——这是一个常见的业务场景,这个协同Container通常称为Sidecar。 主要的Container在运行时,Sidecar需要已经就绪;而当主要的Container停止后,Sidecar也需要停止。

这一功能,虽然是Pod级别的,但基本上也只有Job类业务会使用。 如果是Deployment,其实根本不需要区分Sidecar类型,大家默认都不会停,让外部统一决定生命周期即可。

目前(v1.20版本),官方仍然没有正式支持Sidecar类型的Container。 本文先介绍一个网上流传的乌龙,再介绍一种自己实现的土办法。

官方支持(乌龙)

Kubernetes自1.18版本,正式支持了Sidecar,作为一种lifestyle.type。 经实测证明,这是个乌龙,实际上该功能还未正式进入主线。

一般网上给出的样例,调整成一个直接拿去可以跑的形式,大概是这样的:

---
apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: main
          image: alpine:3.12
          args:
            - sleep
            - 5
        - name: sidecar
          image: alpine:3.12
            - sleep
            - 100
          lifecycle:
            type: Sidecar

理论上,官方支持后,会以containers.lifecycle.type的方式,使用Sidecar类型。 也就是说,以上Job会自动在5秒后结束,而不需要等待100秒。

但既然功能还未进主线,相关MR也已被关闭。

误导文章如下:

其中还有一个像模像样的动态图:

Sidecar

相关PR与issue如下:

这事的情况,大概是在PR#79649提出Sidecar功能。 但是PR#1980被merge后,实现的基础消失了,lifecycle.type因其它原因被删除了。 而新提的PR#80744也是基于它的,也没被merge。 相关文章,属于提前吹捧,结果现实打脸。

Hack方案

既然官方没有,而且即使在v1.18添加,CCE也没有更新,那么只能自己准备Sidecar方案。 Sidecar类型的Container,其生命周期需要满足的条件和前面那个动图没有区别。

一个方案是,在主要的容器中,维护一个文件锁,而在其它容器中,根据这个锁的存在性决定自己的生命周期。

---
apiVersion: batch/v1
kind: Job
metadata:
  name: sidecar
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: main
          image: alpine:3.12
          imagePullPolicy: IfNotPresent
          args:
            - 'sh'
            - '-c'
            - >
              for i in 1 2 3;
              do
                date
                sleep 3s;
              done;
              rm /tmp/lifecycle/running.lock
          lifecycle:
            postStart:
              exec:
                command: ["touch", "/tmp/lifecycle/running.lock"]
            preStop:
              exec:
                command: ["rm", "/tmp/lifecycle/running.lock"]
          volumeMounts:
            - mountPath: /tmp/lifecycle/
              name: lifecycle
        - name: sidecar
          image: alpine:3.12
          imagePullPolicy: IfNotPresent
          command:
            - 'sh'
            - '-c'
            - >
              tail -f /dev/null &
              while [ -f /tmp/lifecycle/running.lock ];
              do
                date
                sleep 1s;
              done;
              jobs -p | xargs kill -9
          volumeMounts:
            - mountPath: /tmp/lifecycle/
              name: lifecycle
      volumes:
        - name: lifecycle
          emptyDir: {}
      securityContext:
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000

以上代码示例中,每一行包含/tmp/lifecycle的,都是Hack的关键。

这里通过挂载/tmp/lifecycle/目录,并确保在main中的一个入口(postStart)和两个出口(preStop与正常退出)之间, 维持/tmp/lifecycle/running.lock文件的存在。 在sidecar容器中,通过主进程轮询/tmp/lifecycle/running.lock文件,并在其消失后随之退出。

此外,监控检查也是一个可行方案。

    livenessProbe:
      exec:
        command:
          - cat
          - /tmp/lifecycle/running.lock
      initialDelaySeconds: 3
      periodSeconds: 1

但它有一些细节问题要调整,比如重试次数。 而最大的副作用是,Job总是失败的,这一点不能接受,因此放弃。

在实际使用中,可以用Python等高级语言,实现更复杂的Sidecar容器守护启动器。 除了定时检查文件锁以外,还需要监控子进程的运行状态。 以上的简单Shell样例中,子进程(其实是业务逻辑上的主进程)如果已经退出,主进程是不知道的。

结论

目前Kubernetes官方对Sidecar类型的容器,仍然缺乏原生支持。 网上流传的文案,其实都是错的。 而由于原MR的实现基础被删除,新方案还遥遥无期。

在Kubernetes正式支持Sidecar之前,仍然只能用各种Hack手段来实现其等价功能。 虽然对Sidecar容器做健康检查,可以实现类似生命周期,但是Pod总是以失败结束。 因此副作用最小的思路,还是让Sidecar容器的服务被一个特殊daemon守护,它轮询主要容器的状态,决定服务生死。 细节上,轮询无论使用文件锁还是网络通信,都是可以的。

参考



本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可,详见本站版权声明

本站没有任何支持评论功能的计划。 如果你对本站的设计、内容、观点有什么意见,欢迎来信指正。


作者:匿蟒 邮箱:[email protected] 备案:闽ICP备15022549号


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK