Sidecar容器学习
1. 什么是Sidecar容器
Sidecar容器中文翻译边车容器,主要作用就是为Pod中的业务容器,提供辅助功能,比如:在spec.containers:
运行一个nginx作为业务容器,在spec.containers
中运行filebeat日志采集器,边车容器也可以称为Init容器的特例。
2. Sidecar容器与Init容器和业务容器对比
官网有对比:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/sidecar-containers/#differences-from-application-containers,我自己总结以下。
和业务容器对比:
容器类型 | 功能 | 启动方式 | 生命周期 | 命名空间 |
---|---|---|---|---|
Sidecar容器 | 为业务容器提供辅助功能 | 多个Sidecar容器并行启动 | 拥有独立的生命周期,对Sidecar的维护不会影响业务容器。 | 与业务容器共享相同的网络和存储命名空间。这种共存使它们能够紧密交互并共享资源。 |
业务容器 | 执行业务代码 | 并行启动 | - | - |
容器终止:
当Pod被杀死或者重建时,kubelet会向所有容器发送SIGTERM信号,留给30s的时间用于处理请求,超过30s后,还未停止就会向容器发送SIGKILL强制停止。但是当Pod中有Sidecar容器时,kubelet会推迟终止边车容器,具体实现是:需要等到所有的业务容器停止后,边车容器才会接收到SIGTERM信号,但是这个时候30s安全停止时间可能已经过去25s,紧接着,kubelet会向所有容器发送SIGKILL信号,强制停止,这也包括Sidecar容器,所以,这时Sidecar的退出码可能非0,由于Sidecar不是业务容器所以可以忽略这个异常。
和Init容器对比:
容器类型 | 启动模式 | 是否支持:lifecycle、livenessProbe、startupProbe、readinessProbe | 是否能与业务容器交互 |
---|---|---|---|
Sidecar容器 | 在业务容器启动前,并行启动,与主应用容器同时运行,在整个 Pod 的生命周期中都处于活动状态,并且可以独立于主容器启动和停止 | 支持 | 与业务容器共享相同的网络和存储命名空间。这种共存使它们能够紧密交互并共享资源。 |
Init容器 | 在业务容器启动前,串行启动,执行完就退出 | 不支持 | Init 容器在主容器启动之前停止,因此 Init 容器无法与 Pod 中的应用容器交换消息。 所有数据传递都是单向的(例如,Init 容器可以将信息放入 emptyDir 卷中)。 |
3. Sidecar容器和Pod的生命周期
如果创建 Init 容器时将 restartPolicy 设置为 Always, 则它将在整个 Pod 的生命周期内启动并持续运行。
如果为此 Init 容器指定了 readinessProbe,其结果将用于确定 Pod 的 ready 状态。
由于这些容器被定义为 Init 容器,所以它们享有与其他 Init 容器相同的顺序和按序执行保证, 从而允许将边车容器与常规 Init 容器混合使用,支持复杂的 Pod 初始化流程。
在 Pod 终止时, kubelet 会推迟终止边车容器,直到主应用容器已完全停止。边车容器随后将按照它们在 Pod 规约中出现的相反顺序被关闭。 这种方法确保了在不再需要边车服务之前这些边车继续发挥作用,以支持 Pod 内的其他容器,具体实现上面已经讲过了。
4. 容器内的资源共享
和Init容器一样,优先要满足保证边车容器的limit/request,业务容器和边车容器limit/request谁的大就使用谁的配置去申请资源。
4 创建带有Sidecar容器的Pod
创建一个tail_f_nginx的边车容器,持续打印nginx容器中的日志,yaml资源文件如下:
cat nginx-po.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: web
containerPort: 80
protocol: TCP
volumeMounts:
- name: html
mountPath: /var/log/nginx
initContainers:
- name: tailfnginx
image: busybox:latest
imagePullPolicy: IfNotPresent
restartPolicy: Always
command: ['sh','-c','tail -F /var/log/nginx/access.log']
volumeMounts:
- name: html
mountPath: /var/log/nginx
volumes:
- name: html
emptyDir: {}
使用kubectl describe pod nginx
查看Pod事件:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m default-scheduler Successfully assigned default/nginx to k8s-node01
Normal Pulled 3m26s kubelet Container image "busybox:latest" already present on machine
Normal Created 3m26s kubelet Created container: tailfnginx
Normal Started 3m26s kubelet Started container tailfnginx
Normal Pulled 3m25s kubelet Container image "nginx:latest" already present on machine
Normal Created 3m25s kubelet Created container: nginx
Normal Started 3m24s kubelet Started container nginx
如上可以看出边车容器优先与业务容器启动。
访问nginx容器,查看tailfnginx容器是否能正常打印日志:
kubectl describe pods/nginx | grep '^IP:'
IP: 10.244.1.11
curl 10.244.1.11
kubectl logs pods/nginx -c tailfnginx
tail: can't open '/var/log/nginx/access.log': No such file or directory
tail: /var/log/nginx/access.log has appeared; following end of new file
10.244.0.0 - - [12/Sep/2025:15:21:20 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.9.1" "-"
可以看到正常获取到了nginx访问的日志,但是第一条日志显示没有找到/var/log/nginx/access.log文件,这是因为优先与nginx容器启动,nginx还没有启动导致的。