OpenKruise SidecarSet采用Admission Webhook机制,在创建Pod的阶段对匹配了目标Label的所有Pod注入Sidecar容器。但由于此时Pod还未调度到虚拟节点,SidecarSet无法实现仅对调度到虚拟节点的Pod生效。您可以借助虚拟节点组件(ACK Virtual Node)仅为调度到虚拟节点上的Pod自动注入Sidecar容器,来解耦虚拟节点中Pod的Sidecar容器与业务容器。
功能介绍
基本概念
Sidecar容器:将一个容器添加到另一个Pod中作为一个附加容器,以扩展和增强主容器,而无需改变主容器本身。关于Sidecar容器在ACS集群中的配置方式,请参见功能说明。
SidecarSet:是阿里云开源的云原生应用自动化引擎OpenKruise的核心功能之一。使用SidecarSet可以为集群中创建的符合条件的Pod自动注入Sidecar容器,实现Sidecar容器(如监控、日志等agent)的定义和生命周期与业务容器解耦。
SidecarSet使用说明
您可以在SidecarSet中通过标签serverless.alibabacloud.com/virtual-node: "true"
指定匹配所有调度到虚拟节点的Pod,该标签会在Pod确定调度到虚拟节点后打上,默认会优先使用ECI弹性实例。您还可以通过配置alibabacloud.com/compute-class: general-purpose
来指定匹配ACS Pod类型的实例。
DaemonSet核心容器运行经常依赖ConfigMap,例如用于配置参数。当将DaemonSet核心容器注入到业务Pod时,业务Pod与ConfigMap通常在不同的命名空间。此时,可以通过在Sidecar容器Volume中通过namespace/name
方式引用其他命名空间的ConfigMap。跨命名空间访问ConfigMap和Secret需要授权。具体方式,请参见SidecarSetResourceBinding。
只对特定类型的Pod注入Sidecar
上述SidecarSet默认将对所有调度到虚拟节点的Pod注入Sidecar容器。如果您只想针对虚拟节点的特定Pod进行调度,可以通过修改.spec.selector
实现,示例如下。
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: filebeat-sidecarset
spec:
containers:
...
selector:
matchLabels:
serverless.alibabacloud.com/virtual-node: "true"
alibabacloud.com/compute-class: general-purpose
app: nginx
配置项 | 说明 |
serverless.alibabacloud.com/virtual-node | 必填,表示匹配所有调度到虚拟节点的Pod。 |
alibabacloud.com/compute-class | 可选,若只希望调度到ACS类型的虚拟节点上时必须配置。更多关于compute-class的内容,请参见ACS Pod实例概述。 |
app | 可选,若只希望针对某个具体的应用注入,可以配置自定义标签。 |
SidecarSetResourceBinding
出于安全考虑,在Sidecar容器Volume中引入其他命名空间的ConfigMap和Secret需要通过SidecarSetResourceBinding显式授权。
该授权仅授予对ConfigMap和Secret的只读权限(Get,List,Watch)。
# 授权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命名空间下的资源做授权。
spec:
subjects:
- kind: SidecarSet
name: filebeat-sidecarset
resourceRefs:
- kind: ConfigMap
name: filebeat-config
- kind: Secret
name: elasticsearch-master-certs
容器启动和退出顺序和Job类Pod
Sidecar容器常需要如下两个诉求:
Sidecar容器需要在业务容器前启动,在业务容器后退出。
对于Job类Pod而言,Sidecar容器需要在业务容器退出后主动退出。
在ACS场景下,您可以在Sidecar容器上面设置环境变量__IS_SIDECAR__="true"
来实现上述诉求。详情内容,请参见配置Sidecar容器启停顺序。
升级Sidecar容器
使用Sidecar模式后,您可能会有Sidecar容器升级等运维需求。您可以使用OpenKruise已有的Sidecar热升级功能,该方式能在不影响Pod可用性情况下无缝升级Sidecar容器,且与当前虚拟节点方式完全兼容。
前提条件
已创建ACK集群Pro版、ACK专有集群或ACK Serverless集群Pro版,且集群版本在1.22及以上。具体操作,请参见创建ACK托管集群、创建ACK专有集群或创建ACK Serverless集群。
已安装虚拟节点组件(ACK Virtual Node),且版本为v2.13.0及以上。更多信息,请参见ACK Virtual Node。
已安装ack-kruise组件,且版本为v1.3.0及以上。更多信息,请参见ack-kruise。
已启用
SidecarSetServerlessPod=true
特性门控。具体操作,请参见自定义控制面组件参数,在Kube API Server组件featureGates中设置SidecarSetServerlessPod=true
。
操作示例
下文将以filebeat容器作为Sidecar容器注入到nginx业务Pod为例,展示完整的使用流程。
部署ConfigMap。
说明此配置文件是kube-system命名空间的ConfigMap。本示例仅将该配置文件挂载到Sidecar容器并打印内容,相关变量不生效,无需替换。
使用以下内容,创建configmap.yaml。
apiVersion: v1 data: filebeat.yml: | filebeat.inputs: - type: log paths: - /var/log/* - /stdout/* output.elasticsearch: host: '${NODE_NAME}' hosts: '["https://${ELASTICSEARCH_HOSTS:elasticsearch-master:9200}"]' username: '${ELASTICSEARCH_USERNAME}' password: '${ELASTICSEARCH_PASSWORD}' protocol: https ssl.certificate_authorities: [ "/usr/share/filebeat/certs/ca.crt" ] kind: ConfigMap metadata: name: filebeat-config namespace: kube-system
执行以下命令,部署ConfigMap。
kubectl apply -f configmap.yaml
部署filebeat容器的SidecarSet。
说明本示例filebeat容器将会同时采集业务容器的文件日志和标准输出。
使用以下内容,创建sidecarset.yaml。
执行以下命令,部署SidecarSet。
kubectl apply -f sidecarset.yaml
授权filebeat容器能够访问kube-system命名空间下的ConfigMap。
说明由于业务Pod位于default命名空间下,filebeat容器被注入后跨Namespace访问ConfigMap需要显式授权。
使用以下内容,创建policy.yaml。
apiVersion: sidecarset.alibabacloud.com/v1alpha1 kind: SidecarSetResourceBinding metadata: name: filebeat-sidecarset-resourcebinding namespace: kube-system # 此SidecarSetResourceBinding只能对kube-system命名空间下的资源做授权。 spec: subjects: - kind: SidecarSet name: filebeat-sidecarset resourceRefs: - kind: ConfigMap name: filebeat-config - kind: Secret name: elasticsearch-master-certs
执行以下命令,部署SidecarSetResourceBinding。
kubectl apply -f policy.yaml
使用以下内容,部署Nginx业务Pod。具体操作,请参见通过编排模板创建Linux应用。
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx alibabacloud.com/compute-class: general-purpose alibabacloud.com/compute-qos: default spec: containers: - name: nginx image: mirrors-ssl.aliyuncs.com/nginx:latest resources: limits: cpu: "1" memory: 200Mi requests: cpu: 100m memory: 100Mi volumeMounts: # Share log directory with filebeat sidecar container via volumeMount - mountPath: /var/log/nginx name: varlog volumes: - name: varlog emptyDir: {} nodeSelector: type: virtual-kubelet tolerations: - key: virtual-kubelet.io/provider operator: Equal value: alibabacloud effect: NoSchedule
执行以下命令,查看业务Pod。
kubectl get pods nginx-785d5xxxxx-xxxxx
预期输出:
NAME READY STATUS RESTARTS AGE nginx-785d5xxxxx-xxxxx 2/2 Running 0 10m
可以看到,Pod包含2个容器,说明注入成功。
验证filebeat容器已挂载业务Pod文件日志和标准输出日志。
执行以下命令,进入filebeat容器。
kubectl exec -it deploy/nginx -c filebeat -- /bin/bash
在容器中查看异常日志。
cat /var/log/error.log
预期输出:
2024/11/08 07:20:54 [notice] 1#1: using the "epoll" event method 2024/11/08 07:20:54 [notice] 1#1: nginx/1.27.2 2024/11/08 07:20:54 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 2024/11/08 07:20:54 [notice] 1#1: OS: Linux 5.10.134-17.2.1.lifsea8.x86_64 2024/11/08 07:20:54 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2024/11/08 07:20:54 [notice] 1#1: start worker processes 2024/11/08 07:20:54 [notice] 1#1: start worker process 29
在容器中查看标准输出日志。
cat /stdout/nginx/0.log
预期输出:
2024-11-08T15:20:53.99215101+08:00 stdout F /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration 2024-11-08T15:20:53.992173978+08:00 stdout F /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ 2024-11-08T15:20:54.003081339+08:00 stdout F /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 2024-11-08T15:20:54.085010761+08:00 stdout F 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf 2024-11-08T15:20:54.276107913+08:00 stdout F 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf 2024-11-08T15:20:54.276263126+08:00 stdout F /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh 2024-11-08T15:20:54.276842182+08:00 stdout F /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh 2024-11-08T15:20:54.345892283+08:00 stdout F /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh 2024-11-08T15:20:54.347524813+08:00 stdout F /docker-entrypoint.sh: Configuration complete; ready for start up
验证filebeat容器已挂载跨命名空间的配置文件filebeat-config。
kubectl exec deploy/nginx -c filebeat -- cat /usr/share/filebeat/filebeat.yml
预期输出:
filebeat.inputs: - type: log paths: - /var/log/* - /stdout/* output.elasticsearch: host: '${NODE_NAME}' hosts: '["https://${ELASTICSEARCH_HOSTS:elasticsearch-master:9200}"]' username: '${ELASTICSEARCH_USERNAME}' password: '${ELASTICSEARCH_PASSWORD}' protocol: https ssl.certificate_authorities: [ "/usr/share/filebeat/certs/ca.crt" ]
出现此输出则表明挂载正常。