OpenKruise SidecarSet采用Admission Webhook机制,在创建Pod的阶段对匹配了目标Label的所有Pod注入Sidecar容器。此时Pod还未调度到虚拟节点,无法仅对调度到虚拟节点的Pod生效。您可以借助虚拟节点组件(ACK Virtual Node)仅为调度到虚拟节点上的Pod自动注入Sidecar容器,来解耦虚拟节点Pod的Sidecar容器与业务容器。
基本概念
Sidecar:一种将应用功能从应用本身剥离出来作为单独进程的设计方式。该模式允许您向应用无侵入添加多种功能,避免为满足第三方组件需求而向应用添加额外的配置代码。
Sidecar容器:将一个容器添加到另一个Pod中作为一个附加容器,以扩展和增强主容器,而无需改变主容器本身。
SidecarSet:是阿里云开源的云原生应用自动化引擎OpenKruise的核心功能之一。使用SidecarSet可以为集群中创建的符合条件的Pod自动注入Sidecar容器,实现Sidecar容器(如监控、日志等agent)的定义和生命周期与业务容器解耦。
使用限制
ACK Virtual Node组件支持OpenKruise v1.3及以下版本的SidecarSet全部功能,不支持1.3以上版本中新增的SidecarSet功能。
前提条件
已创建Kubernetes版本为1.22及以上的ACK集群Pro版、ACK Serverless集群Pro版或者ACK专有集群。具体操作,请参见创建ACK托管集群、创建集群或创建ACK专有集群。
已安装ack-kruise组件,且版本为v1.3.0及以上。更多信息,请参见ack-kruise。
已安装虚拟节点组件(ACK Virtual Node),且版本为v2.10.0及以上。更多信息,请参见ACK Virtual Node。
已启用SidecarSetServerlessPod=true
特性门控。具体操作,请参见自定义控制面组件参数,在Kube API Server组件featureGates中设置SidecarSetServerlessPod=true
。
功能介绍
SidecarSet
您可以使用与默认SidecarSet完全一致的方式来匹配所有调度到虚拟节点的Pod,即通过标签serverless.alibabacloud.com/virtual-node: "true"
指定。该标签会在Pod确定调度到虚拟节点后打上。关于默认SidecarSet的使用方法,请参见SidecarSet。
另一个常用的功能是跨命名空间引用ConfigMap和Secret。DaemonSet核心容器运行经常依赖ConfigMap,如配置参数。将DaemonSet核心容器注入到业务Pod中,业务Pod与ConfigMap通常在不同的命名空间,在Sidecar容器Volume中通过namespace/name
方式引用其他命名空间的ConfigMap。
展开查看代码详情
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:
- name: filebeat
image: busybox
imagePullPolicy: IfNotPresent
args: [
"/bin/sh",
"-c",
"cat /etc/filebeat.yml && sleep 36000", # 此示例仅打印filebeat配置内容。
]
volumeMounts:
- name: config
mountPath: /etc/filebeat.yml
readOnly: true
subPath: filebeat.yml
volumes:
- name: config
configMap:
name: kube-system/filebeat-config # 使用namespace/name方式指定引用其他namespace下ConfigMap。
跨命名空间访问ConfigMap和Secret需要授权。具体方式,请参见下方SidecarSetResourceBinding。
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命名空间下的资源做授权。
labels:
spec:
subjects:
- kind: SidecarSet
name: filebeat-sidecarset
resourceRefs:
- kind: ConfigMap # 仅授权只读权限(Get, List, Watch)。
name: filebeat-config
容器启动和退出顺序
Sidecar容器经常需要在业务容器前启动,在业务容器后退出,您可以通过设置容器启动和退出顺序实现。
升级Sidecar容器
使用Sidecar模式后,您可能会有Sidecar容器升级等运维需求。您可以使用OpenKruise已有的Sidecar热升级功能,该方式能在不影响Pod可用性情况下无缝升级Sidecar容器,且与当前虚拟节点方式完全兼容。
日志收集
通过将虚拟节点Pod标准输出日志卷挂载到Sidecar容器指定目录,可以收集业务容器的日志。具体信息,请参见挂载stdlog实现挂载容器标准输出日志。
展开查看代码详情
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:
# 此示例仅打印Sidecar容器日志内容。
- name: filebeat
image: busybox
imagePullPolicy: IfNotPresent
args: [
"/bin/sh",
"-c",
"cat /var/log/std/filebeat/0.log && sleep 36000",
]
volumeMounts:
- name: stdlog # 挂载Pod标准输出日志卷/var/log/std目录以便sidecar容器读取。
mountPath: /var/log/std
readOnly: true
volumes:
- name: stdlog
flexVolume:
driver: alicloud/pod-stdlog # Pod标准输出日志卷。
操作示例
下文将以filebeat容器作为Sidecar容器注入到echo-server业务Pod为例,展示完整的使用流程。
部署filebeat容器配置文件。
配置文件是kube-system命名空间的ConfigMap,将被挂载到filebeat容器里。本示例仅将该配置文件挂载到Sidecar容器并打印,相关变量不生效,无需替换。
展开查看代码详情
kubectl apply -f - << EOF
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} # 不生效,无需修改,请直接使用。
EOF
部署filebeat容器的SidecarSet描述。
本示例filebeat容器仅打印配置内容。同时,filebeat容器还挂载了业务Pod的标准输出卷,可以收集业务Pod的标准输出日志。
展开查看代码详情
kubectl apply -f - << EOF
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标准输出日志卷/var/log/std目录以便sidecar容器读取。
mountPath: /var/log/std
readOnly: true
volumes:
- name: config
configMap:
name: kube-system/filebeat-config # 使用namespace/name方式指定引用其他namespace下ConfigMap。
- name: stdlog
flexVolume:
driver: alicloud/pod-stdlog # Pod标准输出日志卷。
EOF
授权filebeat容器能够访问kube-system命名空间下的配置文件。
因为echo-server业务Pod位于default命名空间下,filebeat容器被注入后跨namespace访问配置文件需要显式授权。
展开查看代码详情
kubectl apply -f - << EOF
# 授权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
EOF
部署echo-server业务Pod。
展开查看代码详情
kubectl apply -f - << EOF
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"
EOF
查看业务Pod。
kubectl get pod
NAME READY STATUS RESTARTS AGE
echo-server-54f5cf556c-8ms5z 2/2 Running 0 41s
输出表明,Pod包含2个容器,说明注入成功。
验证filebeat容器已挂载业务Pod标准输出日志。
kubectl exec echo-server-54f5cf556c-8ms5z -c filebeat -- cat /var/log/std/echo-server/0.log
2023-07-07T00:40:07.927378153+08:00 stderr F 2023/07/06 16:40:07 Server is listening on :8080
输出表明,可以看到业务Pod标准输出日志。
验证filebeat容器已挂载跨命名空间的配置文件filebeat-config。
展开查看代码详情
kubectl exec echo-server-54f5cf556c-8ms5z -c filebeat -- cat /etc/filebeat.yml
filebeat.inputs:
- type: log
paths:
- /var/log/std/*.log
# 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}
输出表明,挂载正常。