name: sidecarset
spec:
…
updateStrategy:
type: RollingUpdate
maxUnavailable: 10%
这样调整后,对于余下的 980 个 pod,将会按照最大不可用的数量(10% * 1000 = 100)的顺序进行发布,直到所有的 pod 都发布完成。
Partition 的语义是保留旧版本 Pod 的数量或百分比,默认为 0
。这里的 partition
不表示任何 order
序号。如果在发布过程中设置了 partition
:
-
如果是数字,控制器会将
(replicas - partition)
数量的 Pod 更新到最新版本。 -
如果是百分比,控制器会将
(replicas * (100% - partition))
数量的 Pod 更新到最新版本。
MaxUnavailable 是发布过程中保证的,同一时间下最大不可用的 Pod 数量,默认值为 1。用户可以将其设置为绝对值或百分比(百分比会被控制器按照 selected pod 做基数来计算出一个背后的绝对值)。
注意:maxUnavailable 和 partition 两个值是没有必然关联。举例:
-
当 {matched pod}=100,partition=50,maxUnavailable=10,控制器会发布 50 个 Pod 到新版本,但是发布窗口为 10,即同一时间只会发布 10 个 Pod,每发布好一个 Pod 才会再找一个发布,直到 50 个发布完成。
-
当 {matched pod}=100,partition=80,maxUnavailable=30,控制器会发布 20 个 Pod 到新版本,因为满足 maxUnavailable 数量,所以这 20 个 Pod 会同时发布。
[](()5. 金丝雀发布
对于有金丝雀发布需求的业务,可以通过 strategy.selector 来实现。方式:对于需要率先金丝雀灰度的 pod 打上固定的 labels[canary.release] = true,再通过 strategy.selector.matchLabels 来选中该 pod。
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: sidecarset
spec:
…
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
- canary.release: true
maxUnavailable: 10%
上述配置只会发布打上金丝雀 labels 的容器,在完成金丝雀验证之后,通过将 updateStrategy.selector 配置去掉,就会继续通过最大不可用来滚动发布。
[](()6. 打散发布
SidecarSet 对于 pod 的升级顺序,默认按照如下规则:
-
对升级的 pod 集合,保证多次升级的顺序一致。
-
选择优先顺序是(越小优先级越高):unscheduled < scheduled, pending < unknown < running, not-ready < ready, newer pods < older pods。
除了上述默认发布顺序之外,scatter 打散策略允许用户自定义将符合某些标签的 Pod 打散到整个发布过程中。比如,对于像 logtail 这种全局性的 sidecar container,一个集群当中很可能注入了几十个业务 pod,因此可以使用基于 应用名 的方式来打散 logtail 的方式进行发布,实现不同应用间打散灰度发布的效果,并且这种方式可以同最大不可用一起使用。
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: sidecarset
spec:
…
updateStrategy:
type: RollingUpdate
配置pod labels,假设所有的pod都包含labels[app_name]
scatterStrategy:
- key: app_name
value: nginx
- key: app_name
value: web-server
- key: app_name
value: api-gateway
maxUnavailable: 10%
注意:当前版本必须要列举所有的应用名称,我们将在下个版本支持只配置 label key 的智能打散方式。
[](()7. 实践
阿里巴巴以及蚂蚁集团内部已经大规模的使用 SidecarSet 来管理 sidecar 容器,下面我将通过日志采集 Logtail sidecar 来作为一个示例。
- 基于 sidecarSet.yaml 配置文件创建 SidecarSet 资源。
sidecarset.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: logtail-sidecarset
spec:
selector:
matchLabels:
app: nginx
updateStrategy:
type: RollingUpdate
maxUnavailable: 10%
containers:
- name: logtail
image: log-service/logtail:0.16.16
when recevie sigterm, logtail will delay 10 seconds and then stop
command:
-
sh
-
-c
-
/usr/local/ilogtail/run_logtail.sh 10
livenessProbe:
exec:
command:
-
/etc/init.d/ilogtaild
-
status
resources:
limits:
memory: 512Mi
requests:
cpu: 10m
memory: 30Mi
share this volume
volumeMounts:
- name: nginx-log
mountPath: /var/log/nginx
transferEnv:
- sourceContainerName: nginx
envName: TZ
volumes:
- name: nginx-log
emptyDir: {}
- 基于 pod.yaml 创建 Pod。
apiVersion: v1
kind: Pod
metadata:
labels:
matches the SidecarSet’s selector
app: nginx
name: test-pod
spec:
containers:
- name: nginx
image: log-service/docker-log-test:latest
command: [“/bin/mock_log”]
args: [“–log-type=nginx”, “–stdout=false”, “–stderr=true”, “–path=/var/log/nginx/access.log”, “–total-count=1000000000”, “–logs-per-sec=100”]
volumeMounts:
- name: nginx-log
mountPath: /var/log/nginx
envs:
- name: TZ
value: Asia/Shanghai
volumes:
- name: nginx-log
emptyDir: {}
- 创建这个 Pod,你会发现其中被注入了 logtail 容器:
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
test-pod 2/2 Running 0 118s
$ kubectl get pods test-pod -o yaml |grep ‘logtail:0.16.16’
image: log-service/logtail:0.16.16
- 此时,SidecarSet 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 status 被更新为:
$ kubectl get sidecarset logtail-sidecarset -o yaml | grep -A4 status
status:
matchedPods: 1
observedGeneration: 1
readyPods: 1
updatedPods: 1
- 更新 sidecarSet 中 sidecar container 的 image logtail:0.16.18。
$ kubectl edit sidecarsets logtail-sidecarset
sidecarset.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: logtail-sidecarset
spec:
containers:
- name: logtail
image: log-service/logtail:0.16.18
- 此时,发现 pod 中的 logtail 容器已经被更新为了 logtail:0.16.18 版本,并且 pod 以及其它的容器没有重启。
$ kubectl get pods |grep test-pod
test-pod 2/2 Running 1 7m34s
$ kubectl get pods test-pod -o yaml |grep ‘image: logtail:0.16.18’
image: log-service/logtail:0.16.18
$ kubectl describe pods test-pod
Events:
Type Reason Age From Message
Normal Killing 5m47s kubelet Container logtail definition changed, will be restarted
Normal Pulling 5m17s kubelet Pulling image “log-service/logtail:0.16.18”
Normal Created 5m5s (x2 over 12m) kubelet Created container logtail
Normal Started 5m5s (x2 over 12m) kubelet Started container logtail
Normal Pulled 5m5s kubelet Successfully pulled image “log-service/logtail:0.16.18”