通过OpenKruise SidecarSet功能,可以为调度到虚拟节点的Pod自动注入Sidecar容器,从而解耦业务容器和辅助功能容器。本文介绍如何创建SidecarSet定义Sidecar容器,并自动将Sidecar容器注入到虚拟节点的Pod中。
基本概念
Sidecar:一种将应用辅助功能从应用本身剥离出来作为单独进程或容器的设计方式。该模式允许您向应用无侵入添加多种功能,避免为满足第三方组件需求而向应用添加额外的配置代码。
Sidecar容器:在Pod中添加附加容器,扩展和增强主容器,无需改变主容器。
SidecarSet:是阿里云开源的云原生应用自动化引擎OpenKruise的核心功能之一。SidecarSet可以为符合条件的Pod自动注入Sidecar容器,实现Sidecar容器(如监控、日志等agent)的定义和生命周期与业务容器解耦。
前提条件
集群版本为1.22及以上,集群类型为ACK Serverless集群Pro版。
已安装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容器经常需要在业务容器前启动,在业务容器后退出,您可以通过设置容器启动和退出顺序实现。
自动结束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.yaml
filebeat-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.yaml
sidecarset.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.yaml
sidecarset-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.yaml
echo-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
预期返回如下,表示挂载正常。