您好,登錄后才能下訂單哦!
作者 | 徐迪、張曉宇
導讀:本文根據徐迪和張曉宇在 KubeCon NA 2019 大會分享整理。分享將會從以下幾個方面進行切入:首先會簡單介紹一下什么是 Sidecar 容器;其次,會分享幾個阿里巴巴經濟體的通用場景,以及他們是如何解決這些挑戰的。
Sidecar 容器并不是一個新鮮事物。它是一種設計模式,主要用來做一些輔助的工作,比如網絡連通性、下載拷貝文件之類的事情;如果大家熟悉 Docker Swarm 的話,就會發現 Docker Ambassador 其實就是 Sidecar。
如上所示,Service Consumer 和 Redis Provider 強耦合,部署在同一個節點上。如果這個時候,Redis Provider 出現問題,需要連接到另外一個 Redis 實例上,需要重新配置,并重啟 Service Provider。
那么在引入了 Ambassador 以后,問題變得相對簡單些,只需要重啟這里的 Redis Ambassador 即可,并不需要 Service Consumer 進行任何變動。
當然這種模式,還可以進行跨節點通信,比如下圖。這樣 Service Consumer 和 Redis Provider 就可以部署在不同的節點上。在某種程度上,很容易地就將兩種服務進行了解耦。
一般來講,Sidecar 容器可以:
事實上,Sidecar 越來越被大家接受,并且使用越來越廣泛。Sidecar 容器通常和業務容器(非 Sidecar 容器)部署在同一個 Pod 里,共享相同的生命周期,為業務容器提供輔助功能。這是一個非常好的模式,能夠極大程度解耦應用,并且支持異構組件,降低技術壁壘。
但目前 Kubernetes 對 Sidecar 的管理還不完善,越來越不滿足我們的使用,尤其是在生產環境中使用 Sidecar。
假設我們在一個 Pod 內注入了多個 Sidecar,但是 Sidecar 之間或者 Sidecar 和業務容器之間有相互依賴關系。如下這個例子,我們需要先啟動 proxy Sidecar 容器用于建立網絡連接,這樣 mysql client 才能連接到遠端的 mysql 集群,并在本地暴露服務。而后主的業務容器才能正常工作。
#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 等技術領域、聚焦云原生流行技術趨勢、云原生大規模的落地實踐,做最懂云原生開發者的技術圈。”
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。