k8s的SidecarSet配置和initContainers
目录
- 引言
- 一、k8s如何实现Sidecar
- 这段配置正确吗?
- 正确的配置方式
- 为什么这样做?
- 一个简单的例子
- 总结
- 二、什么是SidecarSet
- 主要功能
- 使用场景
- 示例配置
- 三、也可以通过 initContainers 的 restartPolicy 实现边车逻辑
- 四、题外话:什么是InitContainer
- 核心功能
- 常见用途
- 示例
引言
前篇文章《k8s的CRD自定义资源类型示例》,我们介绍了k8s的CRD自定义资源类型,遗留了一个问题,SidecarSet 属于 Kubernetes 默认的 kind 类型吗?属于CRD吗?我们继续来探讨一下。
本文作为抛砖引玉,部分内容小马也并未实践验证(指见过实例但未自己配置run过),仅为互相学习参考。
一、k8s如何实现Sidecar
这段配置正确吗?
先来看一段k8s SidecarSet配置例子。
apiVersion: v1
kind: Pod
metadata:name: my-pod
spec:containers:- name: main-containerimage: my-app-image# ...# 添加 sidecar 容器的定义sidecarContainers:- name: sidecar-containerimage: my-sidecar-image# ...
问题:这段配置正确吗?
DS是这么回答的。👇
您好!您提供的配置片段是不正确的。
标准的 Kubernetes Pod 配置中不存在 sidecarContainers
这个字段。
在 Kubernetes 中,所有的容器(无论是主容器还是 Sidecar 容器)都定义在 spec.containers
这一个数组里。Kubernetes 本身并不区分“主”和“辅助”,所有在同一个 Pod 里的容器都是平等定义的,共享网络和存储等资源。我们只是根据它们的功能角色,习惯性地称其中一个为“主容器”,其他的为“Sidecar 容器”。
正确的配置方式
您的 Pod 定义应该修改如下:
# 作为常规容器定义的方式
apiVersion: v1
kind: Pod
metadata:name: my-pod
spec:containers: # 只有一个 containers 数组- name: main-container # 你的主应用容器image: my-app-image# ... 其他配置(如端口、环境变量等)- name: sidecar-container # 你的 Sidecar 容器image: my-sidecar-image# ... Sidecar 容器的其他配置# 还可以定义更多的容器...# - name: another-sidecar# image: another-image
为什么这样做?
这种设计是 Kubernetes 的核心概念之一:
- 亲密性:Sidecar 模式用于将紧密协作的容器部署在同一个 Pod 中。
- 资源共享:同一个 Pod 内的所有容器:
- 共享相同的网络命名空间(localhost)、IP 地址和端口空间。
- 可以通过共享卷(Volumes)来交换数据。
一个简单的例子
下面是一个更具体的例子,包含一个主 Web 服务器和一个 Sidecar 容器(用于从共享卷中读取日志):
apiVersion: v1
kind: Pod
metadata:name: web-server-with-logger
spec:volumes:- name: shared-logs # 定义一个共享卷emptyDir: {}containers:- name: web-serverimage: nginx:alpineports:- containerPort: 80volumeMounts:- name: shared-logs # 将共享卷挂载到主容器的日志目录mountPath: /var/log/nginx- name: log-sidecarimage: busyboxargs: [/bin/sh, -c, 'tail -f /var/log/nginx/access.log'] # Sidecar 实时读取日志volumeMounts:- name: shared-logs # 将同一个共享卷也挂载到 Sidecar 容器mountPath: /var/log/nginx
总结
请记住:永远使用 spec.containers
数组来定义 Pod 中的所有容器。sidecarContainers
不是一个有效的 Kubernetes 字段,会导致 API 校验错误,Pod 创建失败。
但需要注意,在Kubernetes中,kind: Pod
是用于定义最小可部署计算单元的核心配置。实际生产环境中通常通过Deployment/StatefulSet等控制器间接管理Pod,而非直接操作。即如Deployment
中的template
字段定义了Pod的规格,包括容器镜像、端口等配置。
如:
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: serverbname: deployment-test-name #Deployment namenamespace: my-test-space #命名空间(隔离)
spec:replicas: 2selector:matchLabels:app: serverb #label标签template:metadata:labels:app: serverb #label标签spec:containers:- image: 'mirrors-registry-hub.com/mytestspace:serverb-v2' #容器将运行的镜像仓库中的镜像serverb-v2name: serverb #容器nameports:- containerPort: 9502 #容器的端口(相当于docker run时指定的端口)resources:limits:cpu: 250mmemory: 128Mirequests:cpu: 250mmemory: 128Mi
Deployment定义:通过replicas:2声明需要2个Pod副本,selector匹配带有app:serverb标签的Pod。
Pod模板:template字段定义了Pod的规格,包括容器镜像、端口等配置。
自动管理:Deployment会自动创建ReplicaSet来维护Pod副本数,确保始终有2个serverb Pod运行。
二、什么是SidecarSet
除了上文中作为常规容器定义,kind: Pod形式的主辅容器定义来实现Sidecar,边车容器应与主容器并列定义在 containers 字段中,共享 Pod 的网络和存储命名空间
还。有SidecarSet方式。
SidecarSet
是 Kubernetes 的一种自定义资源定义(CRD),属于Kruise
扩展功能,主要用于在 Pod
中自动注入辅助容器
(sidecar),实现日志收集、监控、鉴权等功能。
SidecarSet 不属于 Kubernetes 默认的 kind 类型,而是由 OpenKruise 项目提供的 CRD(Custom Resource Definition),用于专门管理 Sidecar 容器的生命周期。
OpenKruise是一个CNCF孵化项目,为Kubernetes提供扩展工作负载和应用管理功能,如CloneSet、AdvancedStatefulSet等。它增强了Kubernetes的自动化能力,包括原地升级、sidecar容器管理、高可用性防护和高级运维特性,适用于大规模云原生应用部署和管理。
主要功能
- 自动注入:通过 admission webhook 机制,为符合标签选择器(如
app=nginx
)的 Pod 自动添加 sidecar 容器。 - 版本管理:支持原地升级已注入的 sidecar 容器镜像,无需重新部署 Pod。
- 解耦设计:将 sidecar 容器的定义与业务容器解耦,便于独立升级和维护。
使用场景
适用于需要为特定 Pod 注入无状态辅助容器的场景,例如日志采集、监控代理等。例如,当所有 Pod 需统一注入日志收集器时,可使用 SidecarSet;若仅部分 Pod 需要特定功能(如慢查询采样),则更适合使用 SidecarSet 精细控制。
示例配置
# SidecarSet的方式注入边车
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata: name: scs-demo
spec: selector: matchLabels: app: nginx # app=nginx 的 Pod containers: - name: sidecar1 image: busybox command: ["sleep", "999d"] volumeMounts: - name: log-volume mountPath: /var/log
该配置会匹配所有 app=nginx
的 Pod,并向其注入 busybox
容器用于日志收集。
三、也可以通过 initContainers 的 restartPolicy 实现边车逻辑
当然还有一种方式,若集群启用了 SidecarContainers 特性门控(默认从 v1.29 开始启用),可通过 initContainers 的 restartPolicy 实现边车逻辑。
# 使用 Kubernetes 原生 Sidecar 特性(v1.29+)方式
apiVersion: v1
kind: Pod
metadata:name: my-pod
spec:initContainers:- name: sidecar-containerimage: my-sidecar-imagerestartPolicy: Always # 关键配置,使容器持续运行containers:- name: main-containerimage: my-app-image
常规容器方式适用于所有版本,但需手动管理边车生命周期。
原生 Sidecar 特性支持独立重启策略,避免主容器退出时边车阻塞 Pod 终止。
四、题外话:什么是InitContainer
InitContainer
是Kubernetes中 Pod 的一部分,用于在主容器启动前执行初始化任务。
核心功能
- 顺序执行:多个InitContainer按定义顺序依次运行,所有InitContainer执行完成后主容器才会启动。
- 资源共享:与主容器共享存储卷和网络命名空间,InitContainer产生的数据可被主容器使用。
常见用途
- 数据库初始化:在主容器启动前完成数据库表创建、数据导入等操作。
- 配置文件加载:将配置文件、证书等从存储卷复制到主容器内部。
- 资源预热:提前分配CPU、内存等资源,避免主容器启动时资源不足。
- 网络检查:验证与其他服务的网络连接是否正常。
示例
apiVersion: v1
kind: Pod
metadata:name: myapp-pod
spec:containers:- name: myapp-containerimage: myappvolumeMounts:- name: config-volumemountPath: /appinitContainers:- name: config-initimage: busyboxcommand: ["sh", "-c", "cp /etc/config /app/config"]volumeMounts:- name: config-volumemountPath: /appvolumes:- name: config-volumeemptyDir: {}
该YAML定义了一个Kubernetes Pod资源,包含主容器和初始化容器,功能如下:
- 基础结构
apiVersion/kind:声明Kubernetes资源类型为Pod
metadata:定义Pod名称为myapp-pod
- 主容器
运行myapp镜像,挂载共享卷config-volume到/app目录
- 初始化容器
使用busybox镜像,启动时执行命令将/etc/config复制到共享卷的/app/config
通过volumeMounts与主容器共享存储空间
- 存储卷配置
定义emptyDir类型的临时卷config-volume,供容器间共享文件
特点:通过初始化容器完成预配置后,主容器才启动,确保依赖文件就绪。临时卷生命周期与Pod绑定。
这个Pod会运行两个容器,但它们的运行方式不同:
-
主容器
myapp-container(基于myapp镜像)会持续运行,直到Pod被删除; -
初始化容器
config-init(基于busybox镜像)仅在Pod启动时运行一次,完成配置文件复制后立即退出;
关键区别:
初始化容器先于主容器执行;
初始化容器执行完成后才会启动主容器;
初始化容器完成任务后即终止,不会持续运行。
因此最终Pod中持续运行的只有myapp容器,busybox容器仅作为初始化工具短暂存在。