目錄
- 引言
- 一、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容器僅作為初始化工具短暫存在。