通過OpenKruise SidecarSet功能,可以為調度到虛擬節點的Pod自動注入Sidecar容器,從而解耦業務容器和協助工具功能容器。本文介紹如何建立SidecarSet定義Sidecar容器,並自動將Sidecar容器注入到虛擬節點的Pod中。
基本概念
Sidecar:一種將應用協助工具功能從應用本身剝離出來作為單獨進程或容器的設計方式。該模式允許您嚮應用無侵入添加多種功能,避免為滿足第三方組件需求而嚮應用添加額外的配置代碼。
Sidecar容器:在Pod中添加附加容器,擴充和增強主容器,無需改變主容器。
SidecarSet:是阿里雲開源的雲原生應用自動化引擎OpenKruise的核心功能之一。SidecarSet可以為合格Pod自動注入Sidecar容器,實現Sidecar容器(如監控、日誌等agent)的定義和生命週期與業務容器解耦。
適用範圍
ACK虛擬節點同時支援ECI和ACS兩種算力。使用ACS時同時支援CPU和GPU算力。
前提條件
叢集版本為1.22及以上,叢集類型為ACK託管叢集Pro版或者ACK專有叢集。
已安裝ack-virtual-node組件,且版本為v2.10.0及以上。更多資訊,請參見ACK Virtual Node。
已安裝ack-kruise組件,且版本為v1.3.0及以上。更多資訊,請參見OpenKruise。
重要虛擬節點情境下,支援OpenKruise v1.3.0及以下版本的SidecarSet全部功能,但不支援1.3.0以上版本中新增的SidecarSet功能。
已自訂Kube API Server組件的參數配置,在featureGates中設定
SidecarSetServerlessPod=true以開啟SidecarSet功能的特性門控。更多資訊,請參見自訂控制面組件參數。
功能介紹
SidecarSet
您可以使用與預設SidecarSet完全一致的方式來匹配所有調度到虛擬節點的Pod,即通過標籤serverless.alibabacloud.com/virtual-node: "true"指定。該標籤會在Pod確定調度到虛擬節點後添加。關於預設SidecarSet的使用方法,請參見SidecarSet。
SidecarSet另一個常用的功能是跨命名空間引用ConfigMap和Secret。DaemonSet核心容器運行經常依賴ConfigMap(如配置參數),將DaemonSet核心容器注入到業務Pod中時,業務Pod與ConfigMap通常在不同的命名空間。由於虛擬節點情境不支援DaemonSet,需要採用Sidecar容器替代。在Sidecar容器的Volume中通過Namespace/Name方式,可以跨命名空間引用ConfigMap和Secret。
跨命名空間訪問ConfigMap和Secret需要授權。具體方式,請參見SidecarSetResourceBinding。
SidecarSetResourceBinding
出於安全考慮,在Sidecar容器Volume中引入其他命名空間的ConfigMap和Secret時,需要通過SidecarSetResourceBinding顯式授權。
該授權僅授予對ConfigMap和Secret的唯讀許可權(Get,List,Watch)。
容器啟動和退出順序
Sidecar容器經常需要在業務容器前啟動,在業務容器後退出,您可以通過設定容器啟動和退出順序(ECI)和配置Sidecar容器啟停順序(ACS)實現。
自動結束Sidecar容器
對於Job類Pod,Sidecar容器可能會導致業務容器完成後Job無法退出的情況,您可以通過強制終止Sidecar容器並忽略容器退出碼來解決問題。
升級Sidecar容器
使用Sidecar模式後,您可能會有Sidecar容器升級等營運需求。您可以使用OpenKruise已有的Sidecar熱升級功能,該方式能在不影響Pod可用性情況下無縫升級Sidecar容器,且與當前虛擬節點方式完全相容。
採集標準輸出日誌
通過將虛擬節點Pod的標準輸出日誌(以stdlog卷的形式)掛載到Sidecar容器的指定目錄,可以採集業務容器的標準輸出日誌。更多資訊,請參見掛載stdlog實現掛載容器標準輸出日誌。
操作樣本
下文示範如何向業務Pod(echo-server)注入Sidecar容器(filebeat容器),您可以參考操作樣本設計您的實際業務應用。
部署SidecarSet,用於後續為虛擬節點上的業務Pod自動注入Sidecar容器。
部署ConfigMap,用於後續掛載到Sidecar容器。
kubectl apply -f filebeat-config.yamlfilebeat-config.yaml的內容樣本如下。本樣本僅將設定檔(filebeat.yml)掛載到Sidecar容器並列印,相關變數不生效,無需替換。
apiVersion: v1 kind: ConfigMap metadata: name: filebeat-config namespace: kube-system labels: k8s-app: filebeat data: filebeat.yml: |- filebeat.inputs: - type: log paths: - /var/log/std/*.log processors: - add_kubernetes_metadata: host: ${NODE_NAME} # 不生效,無需修改,請直接使用。 matchers: - logs_path: logs_path: "/var/log/std/" # To enable hints based autodiscover, remove `filebeat.inputs` configuration and uncomment this: #filebeat.autodiscover: # providers: # - type: kubernetes # node: ${NODE_NAME} # hints.enabled: true # hints.default_config: # type: container # paths: # - /var/log/containers/*${data.kubernetes.container.id}.log processors: - add_cloud_metadata: - add_host_metadata: cloud.id: ${ELASTIC_CLOUD_ID} # 不生效,無需修改,請直接使用。 cloud.auth: ${ELASTIC_CLOUD_AUTH} # 不生效,無需修改,請直接使用。 output.elasticsearch: hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}'] username: ${ELASTICSEARCH_USERNAME} # 不生效,無需修改,請直接使用。 password: ${ELASTICSEARCH_PASSWORD} # 不生效,無需修改,請直接使用。部署SidecarSet,用於描述Sidecar容器。
kubectl apply -f sidecarset.yamlsidecarset.yaml的內容樣本如下。本樣本中,作為Sidecar容器的filebeat容器將列印設定檔的內容,並且掛載了stdlog,可以收集業務Pod的標準輸出日誌。
apiVersion: apps.kruise.io/v1alpha1 kind: SidecarSet metadata: name: filebeat-sidecarset spec: selector: matchLabels: serverless.alibabacloud.com/virtual-node: "true" # 表示匹配所有調度到虛擬節點的Pod。 updateStrategy: type: NotUpdate containers: # 此樣本未真正運行filebeat,替換為bosybox cat。 #- name: filebeat # image: docker.elastic.co/beats/filebeat:8.6.1 # args: [ # "-c", "/etc/filebeat.yml", # "-e", # ] - name: filebeat image: busybox imagePullPolicy: IfNotPresent args: [ "/bin/sh", "-c", "cat /etc/filebeat.yml && sleep 36000", ] env: - name: ECI_SIDECAR_CONTAINER # 表示Sidecar容器在業務容器後退出。 value: "true" volumeMounts: - name: config mountPath: /etc/filebeat.yml readOnly: true subPath: filebeat.yml - name: stdlog # 掛載Pod標準輸出日誌以便Sidecar容器讀取。 mountPath: /var/log/std readOnly: true volumes: - name: config configMap: name: kube-system/filebeat-config # 使用Namespace/Name方式指定引用其他Namespace下的ConfigMap。 - name: stdlog csi: driver: stdlogplugin.csi.alibabacloud.com授權Sidecar容器能夠訪問ConfigMap。
如果業務Pod和ConfigMap處於不同的命名空間,業務Pod中注入的Sidecar容器訪問ConfigMap時,需要通過SidecarSetResourceBinding顯式授權。
kubectl apply -f sidecarset-resourcebinding.yamlsidecarset-resourcebinding.yaml的內容樣本如下。本樣本計劃部署業務Pod在
default命名空間,而ConfigMap處於kube-system命名空間,因此需要授權。# 授權filebeat-sidecarset,SidecarSet匹配的Pod能夠訪問kube-system命名空間下filebeat-config ConfigMap。 apiVersion: sidecarset.alibabacloud.com/v1alpha1 kind: SidecarSetResourceBinding metadata: name: filebeat-sidecarset-resourcebinding namespace: kube-system # 此SidecarSetResourceBinding僅對kube-system命名空間下的資源做授權。 labels: spec: subjects: - kind: SidecarSet name: filebeat-sidecarset resourceRefs: - kind: ConfigMap name: filebeat-config
部署調度到虛擬節點的業務Pod。
kubectl apply -f echo-server.yamlecho-server.yaml的內容樣本如下。該Deployment包含一個副本,Pod包含一個容器,添加了
alibabacloud.com/eci: "true"的Label後,Pod會被調度到虛擬節點。apiVersion: apps/v1 kind: Deployment metadata: name: echo-server labels: app: echo-server spec: replicas: 1 selector: matchLabels: app: echo-server template: metadata: labels: app: echo-server alibabacloud.com/eci: "true" spec: containers: - name: echo-server image: hashicorp/http-echo imagePullPolicy: IfNotPresent args: - -listen=:8080 - -text="hello world"確認業務Pod已自動注入Sidecar容器,並驗證掛載結果。
查看業務Pod。
kubectl get pod預期返回如下,可以看到業務Pod包含2個容器,說明Sidecar容器注入成功。
NAME READY STATUS RESTARTS AGE echo-server-f8bdc5844-r44nj 2/2 Running 0 14m驗證Sidecar容器已掛載業務Pod的標準輸出日誌。
kubectl exec echo-server-f8bdc5844-r44nj -c filebeat -- cat /var/log/std/echo-server/0.log預期返回如下,可以看到業務Pod的標準輸出日誌。
2025-04-29T11:26:06.783205694+08:00 stderr F 2025/04/29 03:26:06 Server is listening on :8080驗證Sidecar容器已掛載跨命名空間的設定檔。
kubectl exec echo-server-f8bdc5844-r44nj -c filebeat -- cat /etc/filebeat.yml預期返回如下,表示掛載正常。