您好,登錄后才能下訂單哦!
作者 | 酒祝 阿里云技術專家
導讀: OpenKruise 是阿里云開源的大規模應用自動化管理引擎,在功能上對標了 Kubernetes 原生的 Deployment/StatefulSet 等控制器,但 OpenKruise 提供了更多的增強功能如 優雅原地升級、發布優先級/打散策略、多可用區 workload 抽象管理、統一 sidecar 容器注入管理等,都是經歷了阿里巴巴超大規模應用場景打磨出的核心能力。這些 feature 幫助我們應對更加多樣化的部署環境和需求、為集群維護者和應用開發者帶來更加靈活的部署發布組合策略。
目前在阿里巴巴內部云原生環境中,絕大部分應用都統一使用 OpenKruise 的能力做 Pod 部署、發布管理,而不少業界公司和阿里云上客戶由于 K8s 原生 Deployment 等負載不能完全滿足需求,也轉而采用 OpenKruise 作為應用部署載體。
在介紹 OpenKruise 新增能力之前,我們先來看一下原生 K8s workload 所提供的發布能力:
以上這些策略在測試環境或是小場景下尚且可行,但其實無法完全滿足大規模的應用場景。比方說:
這里我們只針對 v0.5.0 版本 CloneSet 和 SidecarSet 的兩個主要功能改動來介紹,有興趣的同學可以在 Github changelog 上看到版本改動明細: https://github.com/openkruise/kruise/blob/master/CHANGELOG.md 。
在阿里巴巴內部的云原生環境下,絕大部分無狀態應用都使用 CloneSet 管理。為了應對超大規模應用的極致部署需求,我們在其中支持:
而在今年 2 月份的 Kruise v0.4.0 版本中,我們將 CloneSet 推出到開源。CloneSet 一經發布就廣受關注,目前已經有多家知名互聯網公司在調研使用。
最初版本的 CloneSet 并未支持 maxSurge(先擴后縮發布),只支持了 maxUnavailable、partition 等策略。這對阿里巴巴內部的大體量應用來說不是問題,但是很多社區用戶的平臺上都有小規模的應用,如果不能配置先擴后縮,那么在發布階段可能會影響到應用的可用性。
在收到社區的 issue #250 #260 反饋后,我們在 CloneSet 中新增了 maxSurge 策略的支持并于 v0.5.0 版本中提供,在此也感謝社區 fatedier shiyan2016 等成員的參與貢獻和寶貴建議。至此,CloneSet 已經覆蓋了 K8s 原生 workload 的所有發布策略,下圖構建了 CloneSet 目前提供的發布功能:
這里暫時不對 CloneSet 的發布策略做詳細說明,我們后續會有專項文章來介紹。我們只看一下新增的 maxSurge 是如何配合流式、分批發布來實現的呢?接下來我們用幾個簡單的例子來看一下:
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
# ...
spec:
replicas: 5 # Pod 總數為 5
updateStrategy:
maxSurge: 20% # 多擴出來 5 * 20% = 1 個 Pod (rounding up)
maxUnavailable: 0 # 保證發布過程 5 - 0 = 5 個 Pod 可用
partition: 3 # 保留 3 個舊版本 Pod (只發布 5 - 3 = 2 個 Pod)
當開始發布時,CloneSet 會先根據 maxSurge 多擴出來一個 Pod,此時 Pod 總數為 6(5 個舊版,1 個新版):
$ kubectl get clone demo
NAME DESIRED UPDATED UPDATED_READY READY TOTAL AGE
demo 5 1 0 5 6 17m
隨后,CloneSet 會在保證 maxUnavailable 的前提下逐漸把 Pod 刪除、新建的方式更新,直到滿足 partition=3 即剩余 3 個舊版本 Pod。此時,因為已經達到了期望的終態,CloneSet 會把新版本 Pod 刪除一個,此時 Pod 總數為 5(3 個舊版,2 個新版):
$ kubectl get clone demo
NAME DESIRED UPDATED UPDATED_READY READY TOTAL AGE
demo 5 2 2 5 5 17m
這里可以觀察一段時間,當需要繼續往下發布時,再次修改 partition 為 0。然后,CloneSet 會再次根據 maxSurge 多擴出來一個 Pod,此時 Pod 總數為 6(3 個舊版,3 個新版):
$ kubectl get clone demo
NAME DESIRED UPDATED UPDATED_READY READY TOTAL AGE
demo 5 3 2 5 6 17m
隨后,CloneSet 會在保證 maxUnavailable 的前提下逐漸把 Pod 刪除、新建的方式更新,直到滿足 partition=0 即所有 Pod 都升級到新版本。最后,CloneSet 會把新版本 Pod 刪除一個,此時 Pod 總數為 5(5 個新版):
$ kubectl get clone demo
NAME DESIRED UPDATED UPDATED_READY READY TOTAL AGE
demo 5 5 5 5 5 17m
CloneSet 提供了 Pod 原地升級和重建升級兩種升級方式,都可以配合 maxSurge / maxUnavailable / partition 等策略來發布。
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
# ...
spec:
updateStrategy:
type: InPlaceIfPossible
maxSurge: 20%
如果在原地升級方式下配置了 maxSurge,CloneSet 會先擴出來 maxSurge 數量的 Pod,然后對舊版本 Pod 采用 in-place 的方式來升級(更新 Pod spec 中的 image 鏡像),最后在滿足 partition 終態之后再清理刪掉 maxSurge 數量的 Pod。
通過這種方式,既保證了發布過程的業務可用性,也盡量使 Pod 發布過程中 IP、volume 等信息不變。
SidecarSet 是 Kruise 提供的另一個重磅功能,不同于 CloneSet/StatefulSet 這些管理業務 Pod 的 workload,SidecarSet 是負責統一管理集群中的 sidecar 容器版本和注入。
而 v0.5.0 版本中新增的功能,就是在 sidecar 容器注入的時候,解決了 SidecarSet 和 Pod 中 volume 重復定義的沖突問題。這也是來自于一個社區 issue #254 反饋,他們使用 SidecarSet 做日志采集 sidecar 的管理,并期望以旁路的方式注入到所有 Pod 中。
舉個例子,我們需要往集群中每個 Pod 都注入一個日志采集 sidecar 容器。但是一來我們無法讓每個應用開發者都在自己的 CloneSet/Deployment 中增加這個容器的定義,二來即使在所有應用的 workload 中都加了,如果我們想要升級這個日志采集容器的鏡像版本,還得更新所有應用的 workload,這樣做的成本實在太高了!
而 OpenKruise 提供的 SidcarSet 正是為了解決上述這個問題。我們只需要將 sidecar 定義寫到一個全局的 SidcarSet 中,不管用戶用 CloneSet、Deployment、StatefulSet 等任何方式部署,擴出來的 Pod 中都會注入我們定義好的 sidecar 容器。
以日志采集為例,我們可以先定義一個 SidecarSet:
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: log-sidecar
spec:
selector:
matchLabels:
app-type: long-term # 往所有帶 long-term 標簽的 Pod 中注入
containers:
- name: log-collector
image: xxx:latest
volumeMounts:
- name: log-volume
mountPath: /var/log # 將 log-volume 的卷掛到 /var/log 目錄,采集這個目錄下的日志
volumes:
- name: log-volume # 定義一個名為 log-volume 的卷
emptyDir: {}
這里大家可能會問,如果每個應用打出日志的目錄路徑不同,怎么辦?不要急,這就是本次 volume merge 的功能所在。
這個時候,比如有一個應用 A 擴容的原始 Pod 如下:
apiVersion: v1
kind: Pod
metadata:
labels:
app-type: long-term
spec:
containers:
- name: app
image: xxx:latest
volumeMounts:
- name: log-volume
mountPath: /app/logs # 應用自己的日志目錄
volumes:
- name: log-volume # 定義一個名為 log-volume 的卷
persistentVolumeClaim:
claimName: pvc-xxx
那么 kruise webhook 就會將 SidecarSet 中定義的 log sidecar 容器注入到 Pod 中:
apiVersion: v1
kind: Pod
metadata:
labels:
app-type: long-term
spec:
containers:
- name: app
image: xxx:latest
volumeMounts:
- name: log-volume
mountPath: /app/logs # 應用自己的日志目錄
- name: log-collector
image: xxx:latest
volumeMounts:
- name: log-volume
mountPath: /var/log
volumes:
- name: log-volume # 定義一個名為 log-volume 的卷
persistentVolumeClaim:
claimName: pvc-xxx
可以看到,因為 SidecarSet 和 Pod 中定義的日志 volume 名字都叫 log-volume,那么在注入的時候就會以 Pod 中定義的 volume 為準。比如這里 Pod 中的 volume 采用了 pvc 的方式來掛載 pv,那么注入 sidecar 后,同樣會把這個卷掛到 sidecar 容器中的 /var/log 目錄下,然后執行日志采集即可。
這樣以 SidecarSet 的方式管理 sidecar 容器,既和應用部署發布做了解耦,也同樣可以和應用容器共享 volume 卷,來實現日志采集、監控等相關 sidecar 功能。
本次 v0.5.0 版本的升級,主要帶來了應用無損發布和 sidecar 容器管理上更加便捷的能力。
后續 OpenKruise 還會持續在應用部署/發布能力上做出更深的優化,我們也歡迎更多的同學參與到 OpenKruise 社區來,共同建設一個場景更加豐富、完善的 K8s 應用管理、交付擴展能力,能夠面向更加規模化、復雜化、極致性能的場景。
為了更多開發者能夠享受到 Serverless 帶來的紅利,這一次,我們集結了 10+ 位阿里巴巴 Serverless 領域技術專家,打造出最適合開發者入門的 Serverless 公開課,讓你即學即用,輕松擁抱云計算的新范式——Serverless。
點擊即可免費觀看課程: https://developer.aliyun.com/learning/roadmap/serverless
“ 阿里巴巴云原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦云原生流行技術趨勢、云原生大規模的落地實踐,做最懂云原生開發者的公眾號。”
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。