Kubernetes應(yīng)用管理器OpenKruise
OpenKruise
OpenKruise 是 Kubernetes 的一個(gè)標(biāo)準(zhǔn)擴(kuò)展,它可以配合原生 Kubernetes 使用,并為管理應(yīng)用容器、sidecar、鏡像分發(fā)等方面提供更加強(qiáng)大和高效的能力。
核心功能
原地升級(jí)
原地升級(jí)是一種可以避免刪除、新建 Pod 的升級(jí)鏡像能力。它比原生 Deployment/StatefulSet 的重建 Pod 升級(jí)更快、更高效,并且避免對(duì) Pod 對(duì)其他不需要更新的容器造成干擾。
Sidecar 管理
支持在一個(gè)單獨(dú)的 CR 中定義 sidecar 容器,OpenKruise 能夠幫你把這些 Sidecar 容器注入到所有符合條件的 Pod 中。這個(gè)過程和 Istio 的注入很相似,但是你可以管理任意你關(guān)心的 Sidecar。
跨多可用區(qū)部署
定義一個(gè)跨多個(gè)可用區(qū)的全局 workload,容器,OpenKruise 會(huì)幫你在每個(gè)可用區(qū)創(chuàng)建一個(gè)對(duì)應(yīng)的下屬 workload。你可以統(tǒng)一管理他們的副本數(shù)、版本、甚至針對(duì)不同可用區(qū)采用不同的發(fā)布策略。
CRD 列表
- CloneSet
- 提供更加高效、確定可控的應(yīng)用管理和部署能力,支持優(yōu)雅原地升級(jí)、指定刪除、發(fā)布順序可配置、并行/灰度發(fā)布等豐富的策略,可以滿足更多樣化的應(yīng)用場(chǎng)景。
- Advanced StatefulSet
- 基于原生 StatefulSet 之上的增強(qiáng)版本,默認(rèn)行為與原生完全一致,在此之外提供了原地升級(jí)、并行發(fā)布(最大不可用)、發(fā)布暫停等功能。
- SidecarSet
- 對(duì) sidecar 容器做統(tǒng)一管理,在滿足 selector 條件的 Pod 中注入指定的 sidecar 容器。
- UnitedDeployment
- 通過多個(gè) subset workload 將應(yīng)用部署到多個(gè)可用區(qū)。
- BroadcastJob
- 配置一個(gè) job,在集群中所有滿足條件的 Node 上都跑一個(gè) Pod 任務(wù)。
- Advanced DaemonSet
- 基于原生 DaemonSet 之上的增強(qiáng)版本,默認(rèn)行為與原生一致,在此之外提供了灰度分批、按 Node label 選擇、暫停、熱升級(jí)等發(fā)布策略。
- AdvancedCronJob
- 一個(gè)擴(kuò)展的 CronJob 控制器,目前 template 模板支持配置使用 Job 或 BroadcastJob。
以上在官方文檔都有介紹,本文主要著重實(shí)戰(zhàn),先講CloneSet,其他控制器后面會(huì)陸續(xù)更新。。。
部署Kruise到Kubernetes集群
這里使用helm來安裝Kruise
1、現(xiàn)在kruise Chart
- wget https://github.com/openkruise/kruise/releases/download/v0.7.0/kruise-chart.tgz
- tar -zxf kruise-chart.tgz
- cd kruise
- [root@ kruise]# ls -l
- total 16
- -rw-r--r-- 1 root root 311 Dec 20 15:09 Chart.yaml
- -rw-r--r-- 1 root root 4052 Dec 20 15:09 README.md
- drwxr-xr-x 2 root root 4096 Dec 23 10:18 templates
- -rw-r--r-- 1 root root 659 Dec 20 15:09 values.yaml
2、修改values.yaml,默認(rèn)不用修改也行
3、執(zhí)行部署
- [root@qd01-stop-k8s-master001 kruise]# kubectl create ns kruise
- namespace/kruise created
- [root@qd01-stop-k8s-master001 kruise]# helm install kruise -n kruise -f values.yaml .
- W1223 10:22:13.562088 1589994 warnings.go:67] apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
- 。。。。。。。
- NAME: kruise
- LAST DEPLOYED: Wed Dec 23 10:22:12 2020
- NAMESPACE: kruise
- STATUS: deployed
- REVISION: 1
- TEST SUITE: None
- 這里會(huì)看到一堆的deprecated信息,因?yàn)樾掳娴膋ubernetes對(duì)CRD的版本會(huì)淘汰,可以根據(jù)自己的集群版本修改CRD的API版本即可
4、檢查kruise部署狀態(tài)
- [root@qd01-stop-k8s-master001 kruise]# helm ls -n kruise
- NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
- kruise kruise 1 2020-12-23 10:22:12.963651877 +0800 CST deployed kruise-0.7.0
- 可以看到,集群中有的kruise crd類型
- [root@qd01-stop-k8s-master001 kruise]# kubectl get crd|grep kruise
- advancedcronjobs.apps.kruise.io 2020-12-23T02:22:13Z
- broadcastjobs.apps.kruise.io 2020-12-23T02:22:13Z
- clonesets.apps.kruise.io 2020-12-23T02:22:13Z
- daemonsets.apps.kruise.io 2020-12-23T02:22:13Z
- sidecarsets.apps.kruise.io 2020-12-23T02:22:13Z
- statefulsets.apps.kruise.io 2020-12-23T02:22:13Z
- uniteddeployments.apps.kruise.io 2020-12-23T02:22:13Z
下面我們開始來使用這些管理器
CloneSet
CloneSet 控制器提供了高效管理無狀態(tài)應(yīng)用的能力,它可以對(duì)標(biāo)原生的 Deployment,但 CloneSet 提供了很多增強(qiáng)功能。
1、我們先創(chuàng)建一個(gè)簡(jiǎn)單的CloneSet,yaml如下
- apiVersion: apps.kruise.io/v1alpha1
- kind: CloneSet
- metadata:
- labels:
- app: nginx-alpine
- name: nginx-alpine
- spec:
- replicas: 5
- selector:
- matchLabels:
- app: nginx-alpine
- template:
- metadata:
- labels:
- app: nginx-alpine
- spec:
- containers:
- - name: nginx
- image: nginx:alpine
2、部署
- [root@qd01-stop-k8s-master001 demo]# kubectl apply -f CloneSet.yaml
- cloneset.apps.kruise.io/nginx-alpine created
- [root@qd01-stop-k8s-master001 demo]# kubectl get po |grep nginx
- nginx-alpine-29g7n 1/1 Running 0 45s
- nginx-alpine-bvgqm 1/1 Running 0 45s
- nginx-alpine-q9tlw 1/1 Running 0 45s
- nginx-alpine-s2t46 1/1 Running 0 44s
- nginx-alpine-sslvf 1/1 Running 0 44s
- 從輸出結(jié)果看,和原生的Deployment沒有啥區(qū)別
- #注意,這里如果get deployment是看不到nginx-alpine這個(gè)應(yīng)用的,需要get cloneset才能看到
- [root@qd01-stop-k8s-master001 demo]# kubectl get deployment
- [root@qd01-stop-k8s-master001 demo]# kubectl get cloneset
- NAME DESIRED UPDATED UPDATED_READY READY TOTAL AGE
- nginx-alpine 5 5 5 5 5 2m16s
CloneSet 允許用戶配置 PVC 模板 volumeClaimTemplates,用來給每個(gè) Pod 生成獨(dú)享的 PVC,這是 Deployment 所不支持的。 如果用戶沒有指定這個(gè)模板,CloneSet 會(huì)創(chuàng)建不帶 PVC 的 Pod。
3、現(xiàn)在來創(chuàng)建一個(gè)帶有 PVC 模板的例子
- apiVersion: apps.kruise.io/v1alpha1
- kind: CloneSet
- metadata:
- labels:
- app: nginx-2
- name: nginx-2
- spec:
- replicas: 5
- selector:
- matchLabels:
- app: nginx-2
- template:
- metadata:
- labels:
- app: nginx-2
- spec:
- containers:
- - name: nginx
- image: nginx:alpine
- volumeMounts:
- - name: data-vol
- mountPath: /usr/share/nginx/html
- volumeClaimTemplates:
- - metadata:
- name: rbd
- spec:
- accessModes: [ "ReadWriteOnce" ]
- storageClassName: rbd
- resources:
- requests:
- storage: 2Gi
部署
- [root@qd01-stop-k8s-master001 demo]# kubectl apply -f CloneSet.yaml
- cloneset.apps.kruise.io/nginx-2 created
- [root@qd01-stop-k8s-master001 demo]# kubectl get pv|grep data-vol
- pvc-0fde19f3-ea4b-47e0-81be-a8e43812e47b 2Gi RWO Delete Bound default/data-vol-nginx-2-t55h8 rbd 83s
- pvc-72accf10-57a6-4418-a1bc-c64633b84434 2Gi RWO Delete Bound default/data-vol-nginx-2-t49mk rbd 82s
- pvc-8fc8b9a5-afe8-446a-9190-08fcee0ec9f6 2Gi RWO Delete Bound default/data-vol-nginx-2-jw2zp rbd 84s
- pvc-c9fba396-e357-43e8-9510-616f698da765 2Gi RWO Delete Bound default/data-vol-nginx-2-b5fdd rbd 84s
- pvc-e5302eab-a9f2-4a71-a5a3-4cd43205e8a0 2Gi RWO Delete Bound default/data-vol-nginx-2-l54dz rbd 84s
- [root@qd01-stop-k8s-master001 demo]# kubectl get po|grep nginx
- nginx-2-b5fdd 1/1 Running 0 97s
- nginx-2-jw2zp 1/1 Running 0 97s
- nginx-2-l54dz 1/1 Running 0 97s
- nginx-2-t49mk 1/1 Running 0 96s
- nginx-2-t55h8 1/1 Running 0 96s
從部署結(jié)果可以看到,每個(gè)pod都創(chuàng)建了一個(gè)PVC,這個(gè)是原生的Deployment不能實(shí)現(xiàn)的。
注意:
- 每個(gè)被自動(dòng)創(chuàng)建的 PVC 會(huì)有一個(gè) ownerReference 指向 CloneSet,因此 CloneSet 被刪除時(shí),它創(chuàng)建的所有 Pod 和 PVC 都會(huì)被刪除。
- 每個(gè)被 CloneSet 創(chuàng)建的 Pod 和 PVC,都會(huì)帶一個(gè) apps.kruise.io/cloneset-instance-id: xxx 的 label。關(guān)聯(lián)的 Pod 和 PVC 會(huì)有相同的 instance-id,且它們的名字后綴都是這個(gè) instance-id。
- 如果一個(gè) Pod 被 CloneSet controller 縮容刪除時(shí),這個(gè) Pod 關(guān)聯(lián)的 PVC 都會(huì)被一起刪掉。
- 如果一個(gè) Pod 被外部直接調(diào)用刪除或驅(qū)逐時(shí),這個(gè) Pod 關(guān)聯(lián)的 PVC 還都存在;并且 CloneSet controller 發(fā)現(xiàn)數(shù)量不足重新擴(kuò)容時(shí),新擴(kuò)出來的 Pod 會(huì)復(fù)用原 Pod 的 instance-id 并關(guān)聯(lián)原來的 PVC。
- 當(dāng) Pod 被重建升級(jí)時(shí),關(guān)聯(lián)的 PVC 會(huì)跟隨 Pod 一起被刪除、新建。
- 當(dāng) Pod 被原地升級(jí)時(shí),關(guān)聯(lián)的 PVC 會(huì)持續(xù)使用。
4、指定 Pod 縮容
當(dāng)一個(gè) CloneSet 被縮容時(shí),有時(shí)候用戶需要指定一些 Pod 來刪除。這對(duì)于 StatefulSet 或者 Deployment 來說是無法實(shí)現(xiàn)的,因?yàn)?StatefulSet 要根據(jù)序號(hào)來刪除 Pod,而 Deployment/ReplicaSet 目前只能根據(jù)控制器里定義的排序來刪除。
CloneSet 允許用戶在縮小 replicas 數(shù)量的同時(shí),指定想要?jiǎng)h除的 Pod 名字。
現(xiàn)在我們來修改上面例子的部署文件,指定刪除nginx-2-t55h8這個(gè)Pod
- apiVersion: apps.kruise.io/v1alpha1
- kind: CloneSet
- metadata:
- labels:
- app: nginx-2
- name: nginx-2
- spec:
- replicas: 4
- scaleStrategy:
- podsToDelete:
- - nginx-2-t55h8
然后更新yaml文件
- [root@qd01-stop-k8s-master001 demo]# kubectl apply -f CloneSet.yaml
- cloneset.apps.kruise.io/nginx-2 configured
- [root@qd01-stop-k8s-master001 demo]# kubectl get po|grep nginx
- nginx-2-b5fdd 1/1 Running 0 11m
- nginx-2-jw2zp 1/1 Running 0 11m
- nginx-2-l54dz 1/1 Running 0 11m
- nginx-2-t49mk 1/1 Running 0 11m
現(xiàn)在看輸入結(jié)果,已經(jīng)沒有nginx-2-t55h8這個(gè)Pod了
這個(gè)功能很實(shí)用,比如某臺(tái)機(jī)器故障了,或者負(fù)載太高,你想刪除指定的pod。
5、升級(jí)功能
- CloneSet 提供了和 Advanced StatefulSet 相同的 3 個(gè)升級(jí)方式,默認(rèn)為 ReCreate:
- ReCreate: 控制器會(huì)刪除舊 Pod 和它的 PVC,然后用新版本重新創(chuàng)建出來。
- InPlaceIfPossible: 控制器會(huì)優(yōu)先嘗試原地升級(jí) Pod,如果不行再采用重建升級(jí)。目前,只有修改 spec.template.metadata.* 和 spec.template.spec.containers[x].image 這些字段才可以走原地升級(jí)。
- InPlaceOnly: 控制器只允許采用原地升級(jí)。因此,用戶只能修改上一條中的限制字段,如果嘗試修改其他字段會(huì)被 Kruise 拒絕。
現(xiàn)在我們來嘗試原地升級(jí)Pod功能,把nginx鏡像由nginx:alpine 升級(jí)為 nginx:latest
首先修改yaml文件,這里只粘貼出文件的修改的部分
- apiVersion: apps.kruise.io/v1alpha1
- kind: CloneSet
- ...
- spec:
- replicas: 4
- updateStrategy:
- type: InPlaceIfPossible
- inPlaceUpdateStrategy:
- gracePeriodSeconds: 10
- ......
- spec:
- containers:
- - name: nginx
- image: nginx
執(zhí)行升級(jí)
- [root@qd01-stop-k8s-master001 demo]# kubectl apply -f CloneSet.yaml
- cloneset.apps.kruise.io/nginx-2 configured
- 使用 kubectl describe查看升級(jí)過程
- Events:
- Type Reason Age From Message
- ---- ------ ---- ---- -------
- Warning FailedScheduling 59m default-scheduler 0/22 nodes are available: 22 pod has unbound immediate PersistentVolumeClaims.
- Warning FailedScheduling 59m default-scheduler 0/22 nodes are available: 22 pod has unbound immediate PersistentVolumeClaims.
- Warning FailedScheduling 59m default-scheduler 0/22 nodes are available: 22 pod has unbound immediate PersistentVolumeClaims.
- Normal Scheduled 59m default-scheduler Successfully assigned default/nginx-2-l54dz to qd01-stop-k8s-node007.ps.easou.com
- Normal SuccessfulAttachVolume 59m attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-e5302eab-a9f2-4a71-a5a3-4cd43205e8a0"
- Normal Pulling 58m kubelet Pulling image "nginx:alpine"
- Normal Pulled 58m kubelet Successfully pulled image "nginx:alpine" in 6.230045975s
- Normal Killing 55s kubelet Container nginx definition changed, will be restarted
- Normal Pulling 55s kubelet Pulling image "nginx"
- Normal Pulled 26s kubelet Successfully pulled image "nginx" in 29.136659264s
- Normal Created 23s (x2 over 58m) kubelet Created container nginx
- Normal Started 23s (x2 over 58m) kubelet Started container nginx
從輸出可以看到,Container nginx definition changed, will be restarted,Pod并沒有刪除在重建,而是在原來的基礎(chǔ)上直接更新了鏡像文件,并重啟了服務(wù)。
原地升級(jí)減少了刪除重建環(huán)節(jié),節(jié)省了升級(jí)時(shí)間和資源調(diào)度頻率。。。
6、Partition 分批灰度
Partition 的語義是 保留舊版本 Pod 的數(shù)量或百分比,默認(rèn)為 0。這里的 partition 不表示任何 order 序號(hào)。
- 在發(fā)布過程中設(shè)置了 partition:
- 如果是數(shù)字,控制器會(huì)將 (replicas - partition) 數(shù)量的 Pod 更新到最新版本。
- 如果是百分比,控制器會(huì)將 (replicas * (100% - partition)) 數(shù)量的 Pod 更新到最新版本。
現(xiàn)在我將上面的例子的 image 更新為 nginx:1.19.6-alpine 并且設(shè)置 partition=3
- kind: CloneSet
- metadata:
- labels:
- app: nginx-2
- name: nginx-2
- spec:
- replicas: 5
- updateStrategy:
- type: InPlaceIfPossible
- inPlaceUpdateStrategy:
- gracePeriodSeconds: 10
- partition: 3
- selector:
- matchLabels:
- app: nginx-2
- template:
- metadata:
- labels:
- app: nginx-2
- spec:
- containers:
- - name: nginx
- image: nginx:1.19.6-alpine
查看結(jié)果
- Status:
- Available Replicas: 5
- Collision Count: 0
- Label Selector: app=nginx-2
- Observed Generation: 6
- Ready Replicas: 5
- Replicas: 5
- Update Revision: nginx-2-7b44cb9c8
- Updated Ready Replicas: 2
- Updated Replicas: 2
- Events:
- Type Reason Age From Message
- ---- ------ ---- ---- -------
- Normal SuccessfulUpdatePodInPlace 45m cloneset-controller successfully update pod nginx-2-l54dz in-place(revision nginx-2-5879fd9f7)
- Normal SuccessfulUpdatePodInPlace 44m cloneset-controller successfully update pod nginx-2-t49mk in-place(revision nginx-2-5879fd9f7)
- Normal SuccessfulUpdatePodInPlace 43m cloneset-controller successfully update pod nginx-2-b5fdd in-place(revision nginx-2-5879fd9f7)
- Normal SuccessfulUpdatePodInPlace 43m cloneset-controller successfully update pod nginx-2-jw2zp in-place(revision nginx-2-5879fd9f7)
- Normal SuccessfulCreate 22m cloneset-controller succeed to create pod nginx-2-zpp8z
- Normal SuccessfulUpdatePodInPlace 5m22s cloneset-controller successfully update pod nginx-2-zpp8z in-place(revision nginx-2-7b44cb9c8)
- Normal SuccessfulUpdatePodInPlace 4m55s cloneset-controller successfully update pod nginx-2-jw2zp in-place(revision nginx-2-7b44cb9c8)
- [root@qd01-stop-k8s-master001 demo]# kubectl get pod -L controller-revision-hash
- NAME READY STATUS RESTARTS AGE CONTROLLER-REVISION-HASH
- nginx-2-b5fdd 1/1 Running 1 99m nginx-2-5879fd9f7
- nginx-2-jw2zp 1/1 Running 2 99m nginx-2-7b44cb9c8
- nginx-2-l54dz 1/1 Running 1 99m nginx-2-5879fd9f7
- nginx-2-t49mk 1/1 Running 1 99m nginx-2-5879fd9f7
- nginx-2-zpp8z 1/1 Running 1 19m nginx-2-7b44cb9c8
從輸出信息我們可以看到,Update Revision已經(jīng)更新為nginx-2-7b44cb9c8,而Pod中只有兩個(gè)Pod升級(jí)了。
由于我們?cè)O(shè)置了 partition=3,控制器只升級(jí)了 2 個(gè) Pod。
Partition 分批灰度功能完善了原生的Pod升級(jí)方式,使得升級(jí)能夠進(jìn)行更靈活,能夠進(jìn)行灰度上線。超贊。。。
7、最后再演示下發(fā)布暫停
用戶可以通過設(shè)置 paused 為 true 暫停發(fā)布,不過控制器還是會(huì)做 replicas 數(shù)量管理:
- 首先,我們將示例中image改為nginx:1.18.0 并設(shè)置副本數(shù)為10,修改后更新yaml,運(yùn)行結(jié)果如下:
- [root@qd01-stop-k8s-master001 demo]# kubectl get po -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |sort
- nginx-2-7lzx9: nginx:1.18.0,
- nginx-2-b5fdd: nginx:1.18.0,
- nginx-2-jw2zp: nginx:1.18.0,
- nginx-2-l54dz: nginx:1.18.0,
- nginx-2-nknrt: nginx:1.18.0,
- nginx-2-rgmsc: nginx:1.18.0,
- nginx-2-rpr5z: nginx:1.18.0,
- nginx-2-t49mk: nginx:1.18.0,
- nginx-2-v2bpx: nginx:1.18.0,
- nginx-2-zpp8z: nginx:1.18.0,
- 現(xiàn)在我們修改yaml文件,將image修改為nginx:alpine 執(zhí)行更新,運(yùn)行如下
- [root@qd01-stop-k8s-master001 demo]# kubectl get po -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |sort
- nginx-2-7lzx9: nginx:1.18.0,
- nginx-2-b5fdd: nginx:1.18.0,
- nginx-2-jw2zp: nginx:1.18.0,
- nginx-2-l54dz: nginx:1.18.0,
- nginx-2-nknrt: nginx:alpine,
- nginx-2-rgmsc: nginx:alpine,
- nginx-2-rpr5z: nginx:alpine,
- nginx-2-t49mk: nginx:1.18.0,
- nginx-2-v2bpx: nginx:alpine,
- nginx-2-zpp8z: nginx:1.18.0,
- 現(xiàn)在看到,有4個(gè)pod的image已經(jīng)更新為nginx:alpine 然后我們?cè)俅涡薷膟aml文件,添加paused: true
- spec:
- replicas: 10
- updateStrategy:
- paused: true
- type: InPlaceIfPossible
- inPlaceUpdateStrategy:
- gracePeriodSeconds: 10
- 再次執(zhí)行apply,更新yaml,再次查看更新進(jìn)度,發(fā)現(xiàn)pod并沒有繼續(xù)更新了,已經(jīng)暫停升級(jí)image了
- [root@qd01-stop-k8s-master001 demo]# kubectl get po -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |sort
- nginx-2-7lzx9: nginx:1.18.0,
- nginx-2-b5fdd: nginx:1.18.0,
- nginx-2-jw2zp: nginx:1.18.0,
- nginx-2-l54dz: nginx:1.18.0,
- nginx-2-nknrt: nginx:alpine,
- nginx-2-rgmsc: nginx:alpine,
- nginx-2-rpr5z: nginx:alpine,
- nginx-2-t49mk: nginx:1.18.0,
- nginx-2-v2bpx: nginx:alpine,
- nginx-2-zpp8z: nginx:1.18.0,
- 最后把paused: true取消,再次apply yaml文件,升級(jí)會(huì)繼續(xù)。。。
- [root@qd01-stop-k8s-master001 demo]# kubectl get po -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |sort
- nginx-2-7lzx9: nginx:alpine,
- nginx-2-b5fdd: nginx:alpine,
- nginx-2-jw2zp: nginx:alpine,
- nginx-2-l54dz: nginx:alpine,
- nginx-2-nknrt: nginx:alpine,
- nginx-2-rgmsc: nginx:alpine,
- nginx-2-rpr5z: nginx:alpine,
- nginx-2-t49mk: nginx:alpine,
- nginx-2-v2bpx: nginx:alpine,
- nginx-2-zpp8z: nginx:alpine,
以上就是整個(gè)發(fā)布暫停的演示,這個(gè)功能好處就是;我們?cè)谏?jí)的過程中可以隨時(shí)中斷升級(jí)。
除此之外,CloneSet還有很多特性,例如:MaxUnavailable 最大不可用數(shù)量、MaxSurge 最大彈性數(shù)量、升級(jí)順序、打散策略、生命周期鉤子等,鑒于文章篇幅,這些特性不再演示了,有需要的可以查看官方文檔。