做者 | 徐迪、張曉宇mysql
導讀:本文根據徐迪和張曉宇在 KubeCon NA 2019 大會分享整理。分享將會從如下幾個方面進行切入:首先會簡單介紹一下什麼是 Sidecar 容器;其次,會分享幾個阿里巴巴經濟體的通用場景,以及他們是如何解決這些挑戰的。git
Sidecar 容器並非一個新鮮事物。它是一種設計模式,主要用來作一些輔助的工做,好比網絡連通性、下載拷貝文件之類的事情;若是你們熟悉 Docker Swarm 的話,就會發現 Docker Ambassador 其實就是 Sidecar。github
如上所示,Service Consumer 和 Redis Provider 強耦合,部署在同一個節點上。若是這個時候,Redis Provider 出現問題,須要鏈接到另一個 Redis 實例上,須要從新配置,並重啓 Service Provider。sql
那麼在引入了 Ambassador 之後,問題變得相對簡單些,只須要重啓這裏的 Redis Ambassador 便可,並不須要 Service Consumer 進行任何變更。設計模式
固然這種模式,還能夠進行跨節點通訊,好比下圖。這樣 Service Consumer 和 Redis Provider 就能夠部署在不一樣的節點上。在某種程度上,很容易地就將兩種服務進行了解耦。網絡
通常來說,Sidecar 容器能夠:less
事實上,Sidecar 愈來愈被你們接受,而且使用愈來愈普遍。Sidecar 容器一般和業務容器(非 Sidecar 容器)部署在同一個 Pod 裏,共享相同的生命週期,爲業務容器提供輔助功能。這是一個很是好的模式,可以極大程度解耦應用,而且支持異構組件,下降技術壁壘。ide
但目前 Kubernetes 對 Sidecar 的管理還不完善,愈來愈不知足咱們的使用,尤爲是在生產環境中使用 Sidecar。微服務
假設咱們在一個 Pod 內注入了多個 Sidecar,可是 Sidecar 之間或者 Sidecar 和業務容器之間有相互依賴關係。以下這個例子,咱們須要先啓動 proxy Sidecar 容器用於創建網絡鏈接,這樣 mysql client 才能鏈接到遠端的 mysql 集羣,並在本地暴露服務。然後主的業務容器才能正常工做。ui
#1 proxy_container (sidecar) #2 mysql_client #3 svc_container
固然,有的人會以爲這個地方,能夠經過諸如更改鏡像啓動腳本延遲啓動等方法來解決。可是這些方法侵入性太強,不利於擴展,還很難進行準確的配置。
咱們來看看另一個案例。Sidecar 容器和業務容器耦合在同一個 Pod 內,共享相同的生命週期。所以,單獨來管控 Sidecar 容器很是不方,好比更新 Sidecar 的鏡像。
好比,咱們已經給不少 Pod 注入了 Istio Proxy 這樣的 Sidecar 容器,目前運行狀態良好。可是若是這個時候咱們想升級這個 Proxy 鏡像的話,該怎麼辦?
若是按照Istio 社區官方的文檔,咱們須要從新注入這些 Sidecar 容器。具體來講,須要刪除原有 Pod,從新生成一份新的 Pod(有些 workload 關聯的 Pod,會由相應的 workload 控制器自動生成)。
那若是咱們有不少個這樣的 Pod 須要處理的話,怎麼辦?經過命令行的話,太不方便,並且容易出錯。經過本身單獨寫的代碼的話,可擴展性是個問題,須要頻繁更改這些代碼。
並且這裏還有另一個問題,咱們確定不會一會兒升級全部的 Sidecar,確定要有個灰度的過程,也就是隻升級一部分 Sidecar,這個時候又該怎麼辦呢?
這裏咱們很是感謝 Joseph Irving (@Joseph-Irving) 提出了一個 Sidecar kep,經過定義 LifecycleType 來區分是不是 Sidecar 容器。
將來只須要在 Pod Spec 中,按以下方式標記便可:
name: sidecarContainer image: foo lifecycle: type: Sidecar
Pod 內容器的啓動順序按照:初始化容器->Sidecar 容器->業務容器 的順序依次啓動。
其中上述 kep 的 kubelet 端實現 正在進行中。
爲了支持 Sidecar 更多的使用場景,咱們以此爲基礎提出了 PreSidecar 和 PostSidecar,分別用於在業務容器以前和以後啓動。
具體的使用場景見 咱們的 PR。
爲何咱們以爲 Sidecar 應該區分前置和後置呢?
這是由於在一些場景下,咱們須要 Sidecar 容器優先於應用容器啓動,幫助作一些準備工做。例如分發證書,建立共享卷,或者拷貝下載一些其餘文件等。
而在另一些場景下,咱們須要一些 Sidecar 容器在應用容器以後啓動。考慮到解耦和版本管理的因素,咱們將應用分爲兩部分,應用容器專一於業務自己,而一些數據和個性化的配置放在 Sidecar 容器中。一般狀況下,這兩個容器將會共享一個存儲卷,後置的 Sidecar 容器會更新替換掉一些默認和過期數據。
固然考慮到將來更復雜的場景,咱們可能還會對容器的啓動順序作 DAG 編排,固然這個須要視生產實際須要而定。
爲了解決 Sidecar 的管理工做,咱們須要一個更細粒度的 workload 方便咱們進行管理。這個 workload 咱們命名爲 SidecarSet,目前已經開源,生產可用。你們能夠訪問 OpenKruise 這個項目,能夠在項目的 roadmap 裏瞭解咱們目前的一些新進展。OpenKruise 這個項目目前有三個生產可用的 workload,分別是 Advanced StatefulSet、BroadcastJob、SidecarSet。另外2個 workload(AdvancedHPA 和 PodHealer)正在加緊開發中, 很快會開源出來,敬請期待。相關使用 Demo,你們能夠觀看 Lachlan Evenson 的嚐鮮視頻。
spec 中的 SidecarContainer 的定義就是 Kubernetes 代碼庫中的 corev1.Container 定義。經過額外的一個 labelSelector,能夠很方便地對指定的容器組進行操做。咱們支持滾動升級(RollingUpdate)的方式,讓用戶能夠分批的升級 Sidecar,同時也提供了 pause 功能,能夠在緊急狀況下暫停 Sidecar 的升級。
若是隻是簡單升級 Sidecar 的鏡像, SidecarSet 控制器僅僅會 patch 原有 pod 的,很是方便的就能夠一鍵升級鏡像。
咱們在生產實踐過程當中,還發現了一些其餘的挑戰,目前還在尋找比較好的解法。
通常來說 Sidecar 容器佔用的資源都比較小,那麼這個資源要不要計算到整個 pod 當中?仍是能夠直接共享業務容器的資源便可?相同的 Sidecar 在和不一樣的應用容器搭配使用,如何準確給 Sidecar 容器分配資源這些都須要進行考慮。
通常來說,Sidecar 容器都是非主要容器,那麼這類容器出現問題時,好比 liveness 探活,要不要對主容器的狀態或者整個 pod 的狀態也產生影響。再或者,Sidecar 鏡像更新出現問題時,要不要直接標記整個 pod 出現問題。固然,還有一些其餘的挑戰,咱們只是列舉了幾個通用的。對於這些挑戰,咱們須要你們一塊兒集思廣益,找到比較合理的解法。
隨着 Sidecar 在生產環境使用愈來愈普遍,對其的管理愈發須要重視。Sidecar 雖然和業務容器部署在同一個 Pod 內,可是其本質上只是輔助性的容器。本文介紹了目前 Sidecar 的典型使用案例,以及面臨的挑戰,同時跟上游社區一塊兒合做,將阿里經濟體的技術解決方案在社區落地,幫助更多的用戶.
做者簡介:
徐迪 螞蟻金服技術專家:負責螞蟻金融雲 PaaS 平臺建設,Kubernetes 社區老兵,核心代碼庫貢獻量社區前50;
張曉宇 阿里雲技術專家:負責阿里巴巴雲原生應用容器平臺的生態建設,主要設計和研發節點穩定性和資源利用率相關解決方案,同時也是 Kubernetes 社區熱心的成員和貢獻者。
「阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的技術圈。」