从 Kubernetes 1.28 开始使用边车容器
今天是Jobcan Advent Calendar的第4天。
我将讲述备受期待的侧车容器在Kubernetes 1.28中的最新进展。
从 Kubernetes 1.29 版本开始,此功能将会默认启用,并升级为 Beta 版本。(如果能在 AdCar 的日期明天的时候发布就好了…)
SidecarContainers 功能已经进入了 beta 阶段,并默认启用。 (#121579, @gjkim42) [SIG Node]
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.md
简而言之
-
- Kubernetes 1.28 でアルファリリースされた Sidecar Containers は特殊な init Container
-
- Sidecar Containers はメインコンテナより前から起動する
Sidecar Containers はJob の完了判定対象とならない
今までスクリプトやアプリケーション自体に入れる必要のあった待機処理/終了処理が不要に
另外在本文中,“Sidecar”主要指用于辅助主要运行容器和中继通信的各种容器。
传统的 Sidecar 容器存在的问题
在Kubernetes中,虽然过去就已经能够为一个Pod配置多个容器,但存在以下问题。
与主容器同时启动
传统的Sidecar无法定义与主容器之间的关系。
因此,如果不特别注意,不能保证Sidecar会在主容器之前启动。
例如,对于承担连接到外部的代理任务的Sidecar容器,可能会出现一种微妙而困扰的状态,即临时阻断主要容器的通信。

工作无法完成
工作资源是一个适合批处理等任务的资源,当描述的容器全部完成时,工作将会终止。
无论主容器的状态如何,副车容器基本上都会持续运行。因此,如果滥用作业资源以使用副车容器,只有副车容器将持续运行并导致一个莫名其妙的作业继续保持执行状态。

传统的处理方法
对于上述问题,需要通过在容器内或者容器的执行脚本中进行一些处理来解决。
我们来看一个示例,假设把 Cloud SQL 代理放在 Sidecar 容器中。
apiVersion: "batch/v1"
kind: "Job"
metadata:
name: "sidecar-test"
spec:
template:
spec:
restartPolicy: "Never"
containers:
- name: main
image: "main:latest"
imagePullPolicy: "Never"
command: ["/bin/bash", "-c"]
args:
- |
(until curl -o - ${MYSQL_HOST}:8090/readiness &>/dev/null; do sleep 1; done)
trap "touch /tmp/pod/terminated" EXIT
/main
env:
- name: MYSQL_HOST
value: "0.0.0.0"
volumeMounts:
- name: "tmp-pod"
mountPath: "/tmp/pod"
- name: cloud-sql-proxy
image: "gcr.io/cloudsql-docker/gce-proxy:1.33.13-alpine"
command: ["/bin/sh", "-c"]
args:
- |
/cloud_sql_proxy \
-instances=${PROJECT}:${REGION}:${INSTANCE_NAME}=tcp:0.0.0.0:3306 \
-term_timeout=30s \
-use_http_health_check \
-health_check_port=8090 &
CHILD_PID=$!
(while true; do if [[ -f "/tmp/pod/terminated" ]]; then kill -TERM ${CHILD_PID}; break; fi; sleep 1; done) &
wait ${CHILD_PID}
if [[ -f "/tmp/pod/terminated" ]]; then exit 0; else exit 1; fi
ports:
- name: "mysql-port"
containerPort: 3306
volumeMounts:
- name: "tmp-pod"
mountPath: "/tmp/pod"
readOnly: true
volumes:
- name: "tmp-pod"
emptyDir: {}
展示如下.

只希望能传达出「我们别无选择,只能这样做」的氛围即可。
这种步骤描述与 Kubernetes 的「以 YAML 声明式管理」的概念相去甚远。
Cloud SQL Proxy的代码是参考Kubernetes之前的一个问题而创建的。
在Cloud SQL Proxy v2中,添加了一个名为quitquitquit的选项来启动关闭Cloud SQL Proxy v2的端点,通过调用相应的端点可以简化代碼描述。
apiVersion: “batch/v1”
kind: “Job”
metadata:
name: “sidecar-test”
spec:
template:
spec:
restartPolicy: “Never”
containers:
– name: main
image: “main:latest”
imagePullPolicy: “Never”
command: [“/bin/bash”, “-c”]
args:
– |
(until curl -o – ${MYSQL_HOST}:8090/readiness &>/dev/null; do sleep 1; done)
/main
curl ${MYSQL_HOST}:8091/quitquitquit
env:
– name: MYSQL_HOST
value: “0.0.0.0”
– name: cloud-sql-proxy
image: “gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.7.2-alpine”
args:
– “–address=0.0.0.0”
– “–max-sigterm-delay=30s”
– “–health-check”
– “–http-port=8090”
– “–exit-zero-on-sigterm”
– “–admin-port=8091”
– “–quitquitquit”
– “${PROJECT}:${REGION}:${INSTANCE_NAME}”
ports:
– name: “mysql-port”
containerPort: 3306
引入了 Sidecar Containers 的功能
Kubernetes 1.28发布了Sidecar容器的Alpha版本。通过这个功能,您可以在initContainer中使用restartPolicy: always来指定一个容器,使其作为指定的Sidecar容器运行。这个特殊的initContainer与平常的initContainer不同,具有以下特性。
-
- 完了を前提とせず, 終了しなくてもメインコンテナが起動する
メインコンテナの実行中も継続して実行される
readinessProbe, startupProbe が利用できる
startupProbe が成功するまでメインコンテナの起動が遅延される
此外,在Job资源中,这个特殊的initContainer不会被视为完成条件的容器。
总而言之,可以实现以下事项。
-
- Sidecar コンテナの startup が完了するまでメインコンテナの起動を待機する
- 特にシグナル送付や共有 Volume 操作なしで Sidecar つきの Job を終了させる
如果重新写上述的Cloud SQL代理示例,将会是以下这样的。
apiVersion: "batch/v1"
kind: "Job"
metadata:
name: "sidecar-test"
spec:
template:
spec:
restartPolicy: "Never"
containers:
- name: main
image: "main:latest"
imagePullPolicy: "Never"
command: ["/main"]
env:
- name: MYSQL_HOST
value: "0.0.0.0"
initContainers:
- name: cloud-sql-proxy
image: "gcr.io/cloudsql-docker/gce-proxy:1.33.13"
restartPolicy: "Always" # Sidecar Container として動作させる
command:
- "/cloud_sql_proxy"
- "-instances=${PROJECT}:${REGION}:${INSTANCE_NAME}=tcp:0.0.0.0:3306"
- "-term_timeout=30s"
- "-use_http_health_check"
- "-health_check_port=8090"
ports:
- name: "mysql-port"
containerPort: 3306
startupProbe:
httpGet:
path: /readiness
port: 8090
请参见下图。

变得超级简单。
$ kubectl get po -w
NAME READY STATUS RESTARTS AGE
sidecar-test-t7f7b 0/2 Init:0/1 0 4s
sidecar-test-t7f7b 0/2 Init:0/1 0 5s
sidecar-test-t7f7b 0/2 PodInitializing 0 11s
sidecar-test-t7f7b 1/2 PodInitializing 0 12s
sidecar-test-t7f7b 2/2 Running 0 13s
sidecar-test-t7f7b 1/2 Completed 0 22s
sidecar-test-t7f7b 0/2 Completed 0 23s
优点
可以声明式地使用 Sidecar 容器
捕捉EXIT信号并生成文件,始终监视文件是否生成并启动退出处理,以及使用curl进行通信的必要性将完全消失。
重点是各个容器应该做什么,不再需要无用的增加了检查流程的shell脚本中是否有错误。
当然,减少了需要做的事情,也会提高可读性和可维护性。
可以消除不必要的Shell系列。
由于不再需要像以前那样编写shell脚本,您可以删除与之相关的shell和工具集。这简单地导致容器大小的减小和安全性的提高。
缺点
容器启动速度下降
initContainer作用是延迟主容器的启动,因此会产生相应的等待时间。如果在主处理启动之前原本已经加入了等待处理,那么这就不是一个问题。但是,如果在应用程序端进行了覆盖等处理,那么这个等待时间会纯粹地影响启动速度。此外,如果使用多个Sidecar容器,initContainer将按顺序处理,因此会导致等待时间的纵向延长。
总结
-
- Kubernetes 1.28 でリリースされた Sidecar Containers は特殊な initContainer
-
- Sidecar Containers はメインコンテナより前から起動し続ける
-
- Sidecar Containers は Job の完了判定対象とならない
- 今までスクリプト書いてたの何だったん???ってくらいスッキリする
希望尽快成为Google广告合作伙伴。
公告
DONUTS正在积极开展新进与在职员工的招聘活动,请点击此处了解更多详情。
我们还正在寻找JobCan的基础设施工程师。
请提供一些相关信息
大问题(从2016年开始存在…根深蒂固)
https://github.com/kubernetes/kubernetes/issues/25908