sealer背后实现整个集群一键交付的奥秘 | 龙蜥技术
簡介:解讀集群鏡像“開箱即用”神器——sealer!
編者按:集群鏡像把整個集群看成一臺服務器,把 k8s 看成云操作系統,實現整個集群的鏡像化打包和交付,為企業級軟件提供一種“開箱即用”的應用封裝技術。本文整理自龍蜥大講堂技術直播第11期,由龍蜥社區集群鏡像 SIG 核心成員、sealer項目發起人方海濤分享——通過 sealer 實現整個集群 Build&Share&Run。
以下是本期龍蜥大講堂直播回顧文:
什么是鏡像集群
顧名思義,和操作系統 .iso 鏡像或 Docker 鏡像類似,集群鏡像是用一定的技術手段把整個集群的所有文件以一定格式打成的一個資源包。
對比單機和集群會發現一些的有趣現象:
- 單機有計算、存儲、網絡等驅動;集群有 CNI/CSI/CRI 實現像是集群的驅動。
- 單機有 ubuntu centos 操作系統;集群中可以把 Kubernetes 看成云操作系統。
- 單機上可以運行 docker 容器或虛擬機;相當于一個運行的實例,集群上也有運行著 K8s 的實例。
- 單機上有虛擬機鏡像,docker 鏡像;隨著云計算技術的發展,集群上也會抽象出類似的鏡像技術。
以基于 Kubernetes 的集群鏡像為例,里面包含了除操作系統以外的所有文件:
- docker 依賴的二進制與 systemd 配置、dockerd 配置,以及一個私有的容器鏡像倉庫。
- Kubernetes 核心組件二進制、容器鏡像、kubelet system 配置等。
- 應用需要用到的 yaml 配置或 helm chart,以及應用的容器鏡像。
- 其它腳本、配置與二進制工具等應用運行需要的所有依賴。
同樣,集群鏡像運行時肯定不是起一個容器或者裝在一臺機器上,而是這個鏡像可以直接安裝到多臺服務器上或者直接對接到公有云的基礎設施上。
sealer 介紹
sealer 是阿里巴巴開源的集群鏡像的一個實現方式(開源項目地址見文末)。
Docker 解決了單個容器的鏡像化問題,而 sealer 通過把整個集群打包,實現了分布式軟件的 Build Share Run!!!
試想我們要去交付一個 SaaS 應用,它依賴了 MySQL/ES/Redis 這些數據庫和中間件,所有東西都在 Kubernetes 上進行編排,如果沒有集群鏡像時,要做如下操作:
1)找個工具去安裝 K8s 集群
2)helm install mysql es redis... 如果是離線環境可能還需要導入容器鏡像
3)kubectl apply yoursaas
看似好像也沒那么復雜,但其實從整個項目交付的角度來說,以上操作是面向過程極易出錯的。現在如果提供另外一個方式,只需一條命令就可解決上面的問題,你會不會用?
sealer run your-saas-application-with-mysql-redis-es:latest
如上圖所示:我們只需要定義一個類似 Dockerfile 的文件,將其稱之為 Kubefile, 然后執行 build 命令即可:
sealer build -t your-saas-application-with-mysql-redis-es:latest .
從單機和集群兩個緯度進行對比,就可以一目了然:
- docker 通過 Dockerfile 構建一個 docker 鏡像,使用 compose 就可以運行容器。
- sealer 通過 Kubefile 構建一個 CloudImage,使用 Clusterfile 啟動整個集群。
快速體驗
下面我們一起制作和運行一個 Kubernetes dashboard 的集群鏡像,來體驗一個完整的流程。編寫 Kubefile:
# 基礎鏡像,已經被制作好了里面包含所有的kubernetes啟動相關的依賴 FROM registry.cn-qingdao.aliyuncs.com/sealer-io/cloudrootfs:v1.16.9-alpha.7 # 下載官方的dashboard yaml編排文件,已經下載了可以使用COPY指令 RUN wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml # 指定運行方式,可以使用kubectl helm kustomiz等 CMD kubectl apply -f recommended.yamlbuild dashboard 集群鏡像:
sealer build -t kubernetes-with-dashobard:latest .
運行集群鏡像:
# 下面命令會在服務器上安裝k8s集群并apply dashboard, passwd指定服務器ssh密碼,也可以使用密鑰 sealer run kubernetes-with-dashobard:latest \--master 192.168.0.2,192.168.0.3,192.168.0.4 \--node 192.168.0.5,192.168.0.6 \--passwd xxx # 檢查pod kubectl get pod -A |grep dashboard把制作好的鏡像推送到鏡像倉庫,兼容 docker registry:
sealer tag kubernetes-with-dashobard:latest docker.io/fanux/dashobard:latest sealer push docker.io/fanux/dashobard:latest這樣就可以把制作好的鏡像交付出去或者提供給別人復用。
使用場景
sealer 具體能幫我們做哪些事呢?下面列舉幾個主要場景:
1. 安裝 Kubernetes 與集群生命周期管理(升級/備份/恢復/伸縮)
這是個最簡單的場景,不管你是需要在單機上安裝個開發測試環境,還是在生產環境中安裝一個高可用集群;不管是裸機還是對接公有云,或者各種體系結構操作系統,都可以使用 sealer 進行安裝,這里只安裝 Kubernetes 的話就選擇個基礎鏡像即可。與其它的安裝工具對比,sealer 優勢在于:
- 簡單到令人發指:sealer run 一條命令結束。
- 速度快到令人窒息:3min 裝完 6 節點,可能你使用別的工具時還沒下載完 sealer 就已經裝完了,不僅如此,后續我們還有黑科技優化到 2min 甚至 1min 以內。
- 兼容性與穩定性:兼容各種操作系統,支持 x86 Arm 等體系結構。
- 一致性設計:會讓集群保持 Clusterfile 中的定義狀態,以升級為例,只需要改一下 Clusterfile 中的版本號即可實現升級。
速度快是因為首先是 golang 實現,意味著我們可以對眾多很細致的地方做并發的處理,這相比 ansible 就有了更多優勢;而且還可以做更細致的錯誤處理,然后在鏡像分發上拋棄以前 load 的方式;后續在文件分發上也會做優化,達到安裝性能上的極致。
兼容性上,docker kubelet 采用了二進制+systemd 安裝核心組件全容器化,這樣不用再去依賴 yum/apt 這類感知操作系統的安裝工具。Arm 和 x86 采用不同的鏡像支持與 sealer 本身解耦開,對公有云的適配也抽離單獨模塊進行實現,這里我們沒去對接 terraform,原因還是為了性能。在我們的場景下,terraform 啟動基礎設施將近 3min,而我們通過退避重試把基礎設施啟動優化到了 30s 以內,除此之外,在集群鏡像場景下,不需要這么復雜的基礎設施管理能力,我們不想讓 sealer 變重也不想依賴一個命令行工具。
一致性的設計理念是 sealer 中值得一提的,集群鏡像與 Clusterfile 決定了集群是什么樣子,相同的鏡像與 Clusterfile 就能 run 出個一樣的集群。變更要么變更 Clusterfile,如增加節點、改變節點規格或者換鏡像,換鏡像時,由于集群鏡像也是分層結構,所以 hash 值不變的 layer 不會發生變更,而 hash 發生變化會幫助重新 apply 該層。
2. 云原生生態軟件的打包/安裝等,如 prometheus mysql 集群
sealer run prometheus:latest 就可以創建一個帶有 prometheus 的集群,或者在一個已有的集群中安裝 prometheus。那么問題來了:它和 helm 啥區別?
1)sealer 不關心編排,更注重打包,上面例子 prometheus 可以用 helm 編排,sealer 會把 chart 和 chart 里需要的所有容器鏡像打包起來,這是在 build 的過程中通過黑科技做到的,因為 build 過程會像 docker build 一樣起臨時的 Kubernetes 集群,然后我們就知道集群依賴了哪些容器鏡像,最后把這些容器鏡像打包。
2)和 Kubernetes 一起打包,拿了一個 chart 它未必能安裝成功,比如使用了廢棄的 api 版本,但是做成鏡像把 Kubnernetes 也包在一起了,只要 build 沒問題,run 就沒問題,這點和 docker 把操作系統 rootfs 打包在一起有異曲同工之妙。
3)集成性,集群鏡像更關注整個分布式應用集群整體打包,如把 prometheus ELK mysql 集群做成一個鏡像服務與業務。
所以 sealer 與 helm 是協作關系,分工明確。后續可以在 sealer 的官方鏡像倉庫中找到這些通用的集群鏡像,直接使用即可。
3. SaaS 軟件整體打包/交付 專有云離線交付
從分布式應用的視角看,通常從上往下,少則幾個多則上百的組件,現有整體交付方式大多都是面向過程的,中間需要很多進行干預的事,sealer 就可以把這些東西統統打包在一起進行一鍵交付。
可能你會問:我們做個 tar.gz 再加個 ansible 腳本不也能一鍵化嗎?答案是肯定的。就和 docker 鏡像出現之前,大家也通過 tar.gz 交付一樣,你會發現標準和技術的出現解決了人與人之間的協作問題, 有了集群鏡像就可以直接復用別人的成果,也能制作好東西供別人使用。
專有云場景就非常適合使用 sealer,很多客戶機房都是離線的,而集群鏡像會把所有依賴打到鏡像中,只要鏡像制作得好,那么所有局點都能以相同的方式進行一鍵交付,獲得極佳的一致性體驗。
4. 在公有云上實踐上述場景
sealer 自帶對接公有云屬性,很多情況下對接公有云會有更好的使用體驗,比如安裝集群時,只需要指定服務器數量和規格而不用關心 IP,伸縮直接修改 Clusterfile 中定義的數字即可。
技術原理簡介
1. 寫時復制
集群鏡像的存儲也是通過寫時復制的方式實現的。這樣做有兩個好處:我們可以把同一集群中不同的分布式軟件打在不同層,以實現復用;還可以實現直接把集群鏡像 push 到 docker 鏡像倉庫中。
2. 容器鏡像緩存
build 的過程中 sealer 是如何知道待構建的集群鏡像里有哪些容器鏡像,以及怎么把容器鏡像存儲下來呢?其中有一些難點問題:
- 如何知道分布式軟件中有哪些容器鏡像?因為我們需要把這些鏡像緩存下來,不管是掃描用戶的 yaml 文件還是用 helm template 之后掃描都是不完美的。首先不能確定用戶的編排方式是什么,其次有些軟件不把鏡像地址寫在編排文件中,而是通過自己的程序去拉起,無法保證 build 成功運行就一定沒問題。
- 容器鏡像是需要被存儲到私有倉庫中打包在集群鏡像里,那容器鏡像倉庫地址勢必和編排文件中寫的不一樣,特別是怎么保證用戶 alwayPull 的時候還是能夠在私有倉庫中下載到鏡像?
如上圖所示,這樣就可以保證用戶依賴的所有鏡像都被打包進去,無論用戶使用什么樣的編排方式。第二個問題,我們打包容器鏡像到私有鏡像倉庫中,怎樣使用這個私有鏡像也是個難題,假設私有鏡像倉庫名為 localhost:5000,肯定會和編排文件中寫的不一致,對此我們有兩種方式解決:
- 第一種是 hack 和 docker,做了一個只要私有鏡像倉庫中有就直接從私有鏡像中拉取,沒有才去公網拉取鏡像的能力。
- 第二種方案是無侵入 docke r的 proxy,把 docker 請求全部打給代理,讓代理去決定如果私有倉庫有就從私有倉庫拉取。同時我們還增強了 registry 的能力讓 registry 可以 cache 多個遠程倉庫的能力。
sealer 的這種方案完美解決了離線場景鏡像打包的問題。
3. 負載均衡
sealer 的集群高可用使用了輕量級的負載均衡 lvscare。相比其它負載均衡,lvscare 非常小僅有幾百行代碼,而且 lvscare 只做 ipvs 規則的守護,本身不做負載非常穩定,直接在 node 上監聽 apiserver,如果跪了就移除對應的規則,重新起來之后會自動加回,相當于是一個專用的負載均衡器,在 sealos 項目中也用了兩年多,有廣泛的實踐。
4. 運行時
運行時就是支撐應用運行的環境,像 base on Kuberentes 的運行時 sealer 就可以透明地支持非常簡單,以 istio 為例,用戶只需要:
FROM kubernetes:v1.18.3RUN curl -L https://istio.io/downloadIstio | sh -就可以 build 出一個 istio 的運行時供自己應用使用。對于不是 base on
Kuberentes 的運行時,如 k0s k3s,可以擴展 sealer.Runtime 中的接口,這樣以后就可以:
FROM kubernetes:v1.18.3 RUN curl -L https://istio.io/downloadIstio | sh -更牛的擴展比如擴展 ACK 的 runtime:
FROM k3s:v1.18.3 RUN curl -L https://istio.io/downloadIstio | sh -這種鏡像會直接幫助用戶應用運行到 ACK 上。以上有些能力在 roadmap 中。
5. 基礎設施
現在很多用戶都希望在云端運行自己的集群鏡像,sealer 自帶對接公有云能力,sealer 自己實現的基礎設施管理器,得益于我們更精細的退避重試機制,30s 即可完成基礎設施構建(阿里云 6 節點)性能是同類工具中的佼佼者,且 API 調用次數大大降低,配置兼容 Clusterfile。
總結
sealer 未來的一些愿景與價值體現:
- sealer 可以以極其簡單的方式讓用戶自定義集群,解決分布式軟件制作者與使用者的協作問題。
- 極其簡單友好的 User Interface,能屏蔽和兼容各種底層技術細節,到處運行。
- 生態建設,官方倉庫里將會涵蓋常用的分布式軟件。
最后我們總結下:
- 如果你要整體交付你的分布式 SaaS,請用 sealer。
- 如果你要集成多個分布式服務在一起,如數據庫消息隊列或者微服務運行時,請用 sealer。
- 如果你要安裝一個分布式應用如 mysql 主備集群,請用 sealer。
- 如果你需要安裝/管理一個 Kubernetes 高可用集群,請用 sealer。
- 如果你要初始化多個數據中心,保持多個數據中心狀態強一致,請用 sealer。
- 如果你需要在公有云上實現上述場景,請用 sealer。
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。?
總結
以上是生活随笔為你收集整理的sealer背后实现整个集群一键交付的奥秘 | 龙蜥技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Cloud Gateway
- 下一篇: 阿里巴巴超大规模Kubernetes基础