集羣鏡像:實現高效的分佈式應用交付

簡介:Docker 解決了單個容器的鏡像化問題,而 sealer 經過把整個集羣打包,實現了分佈式軟件的 Build Share Run。

做者 | fanux.中弈node

什麼是集羣鏡像

顧名思義,和操做系統 .iso 鏡像或 Docker 鏡像相似,集羣鏡像是用必定的技術手段把整個集羣的全部文件以必定格式打成的一個資源包mysql

image

對比單機和集羣會發現一些的有趣現象:git

  • 單機有計算、存儲、網絡等驅動;集羣有 CNI/CSI/CRI 實現像是集羣的驅動。
  • 單機有 ubuntu centos 操做系統;集羣中能夠把 Kubernetes 當作雲操做系統。
  • 單機上能夠運行 docker 容器或虛擬機;至關於一個運行的實例,集羣上也有運行着 K8s 的實例。
  • 單機上有虛擬機鏡像,docker 鏡像;隨着雲計算技術的發展,集羣上也會抽象出相似的鏡像技術。

以基於 Kubernetes 的集羣鏡像爲例,裏面包含了除操做系統之外的全部文件:github

  • docker 依賴的二進制與 systemd 配置、dockerd 配置,以及一個私有的容器鏡像倉庫。
  • Kubernetes 核心組件二進制、容器鏡像、kubelet system 配置等。
  • 應用須要用到的 yaml 配置或 helm chart,以及應用的容器鏡像。
  • 其它腳本、配置與二進制工具等應用運行須要的全部依賴。

一樣,集羣鏡像運行時確定不是起一個容器或者裝在一臺機器上,而是這個鏡像能夠直接安裝到多臺服務器上或者直接對接到公有云的基礎設施上。golang

sealer 介紹

sealer是阿里巴巴開源的集羣鏡像的一個實現方式,項目地址:_https://github.com/alibaba/sealer_redis

Docker 解決了單個容器的鏡像化問題,而 sealer 經過把整個集羣打包,實現了分佈式軟件的 Build Share Run!!!sql

試想咱們要去交付一個 SaaS 應用,它依賴了 MySQL/ES/Redis 這些數據庫和中間件,全部東西都在 Kubernetes 上進行編排,若是沒有集羣鏡像時,要作以下操做:docker

  1. 找個工具去安裝 K8s 集羣
  2. helm install mysql es redis... 若是是離線環境可能還須要導入容器鏡像
  3. kubectl apply yoursaas

看似好像也沒那麼複雜,但其實從整個項目交付的角度來講,以上操做是面向過程極易出錯的。數據庫

如今若是提供另一個方式,只需一條命令就可解決上面的問題,你會不會用?ubuntu

sealer run your-saas-application-with-mysql-redis-es:latest

能夠看到,只須要 run 一個集羣鏡像,整個集羣就被交付了,細節複雜的操做都被屏蔽掉了,並且任何應用均可以使用相同的方式運行。這個集羣鏡像是怎麼來的呢?

image

如上圖所示:咱們只須要定義一個相似 Dockerfile 的文件,將其稱之爲 Kubefile, 而後執行 build 命令便可:

sealer build -t your-saas-application-with-mysql-redis-es:latest .

從單機和集羣兩個緯度進行對比,就能夠一目瞭然:

image.png

  • 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.yaml

build 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 具體能幫咱們作哪些事呢?下面列舉幾個主要場景:

安裝 Kubernetes 與集羣生命週期管理(升級/備份/恢復/伸縮)

這是個最簡單的場景,無論你是須要在單機上安裝個開發測試環境,仍是在生產環境中安裝一個高可用集羣;無論是裸機仍是對接公有云,或者各類體系結構操做系統,均可以使用 sealer 進行安裝,這裏只安裝 Kubernetes 的話就選擇個基礎鏡像便可。

與其它的安裝工具對比,sealer 優點在於:

  1. 簡單到使人髮指:sealer run 一條命令結束。
  2. 速度快到使人窒息:3min 裝完 6 節點,可能你使用別的工具時還沒下載完 sealer 就已經裝完了,不只如此,後續咱們還有黑科技優化到 2min 甚至 1min 之內。
  3. 兼容性與穩定性:兼容各類操做系統,支持 x86 arm 等體系結構。
  4. 一致性設計:會讓集羣保持 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 該層。

雲原生生態軟件的打包/安裝等,如 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 的官方鏡像倉庫中找到這些通用的集羣鏡像,直接使用便可。

SaaS 軟件總體打包/交付 專有云離線交付

從分佈式應用的視角看,一般從上往下,少則幾個多則上百的組件,現有總體交付方式大多都是面向過程的,中間須要不少進行干預的事,sealer 就能夠把這些東西通通打包在一塊兒進行一鍵交付。

可能你會問:咱們作個 tar.gz 再加個 ansible 腳本不也能一鍵化嗎?答案是確定的。就和 docker 鏡像出現以前,你們也經過 tar.gz 交付同樣,你會發現標準和技術的出現解決了人與人之間的協做問題, 有了集羣鏡像就能夠直接複用別人的成果,也能製做好東西供別人使用。

專有云場景就很是適合使用 sealer,不少客戶機房都是離線的,而集羣鏡像會把全部依賴打到鏡像中,只要鏡像製做得好,那麼全部局點都能以相同的方式進行一鍵交付,得到極佳的一致性體驗。

在公有云上實踐上述場景

sealer 自帶對接公有云屬性,不少狀況下對接公有云會有更好的使用體驗,好比安裝集羣時,只須要指定服務器數量和規格而不用關心 IP,伸縮直接修改 Clusterfile 中定義的數字便可。

技術原理簡介

寫時複製

集羣鏡像的存儲也是經過寫時複製的方式實現的。這樣作有兩個好處:咱們能夠把同一集羣中不一樣的分佈式軟件打在不一樣層,以實現複用;還能夠實現直接把集羣鏡像 push 到 docker 鏡像倉庫中。

容器鏡像緩存

build 的過程當中 sealer 是如何知道待構建的集羣鏡像裏有哪些容器鏡像,以及怎麼把容器鏡像存儲下來呢?其中有一些難點問題:

  1. 如何知道分佈式軟件中有哪些容器鏡像?由於咱們須要把這些鏡像緩存下來,無論是掃描用戶的 yaml 文件仍是用 helm template 以後掃描都是不完美的。首先不能肯定用戶的編排方式是什麼,其次有些軟件不把鏡像地址寫在編排文件中,而是經過本身的程序去拉起,沒法保證 build 成功運行就必定沒問題。
  2. 容器鏡像是須要被存儲到私有倉庫中打包在集羣鏡像裏,那容器鏡像倉庫地址勢必和編排文件中寫的不同,特別是怎麼保證用戶 alwayPull 的時候仍是可以在私有倉庫中下載到鏡像?

對待第一個問題,sealer 解決方式是:sealer build 的過程當中和 Docker build 同樣,會拉起一個臨時的 Kubernetes 集羣,並執行用戶在 Kubefile 中定義的 apply 指令。

image.png

如上圖所示,這樣就能夠保證用戶依賴的全部鏡像都被打包進去,不管用戶使用什麼樣的編排方式。

第二個問題,咱們打包容器鏡像到私有鏡像倉庫中,怎樣使用這個私有鏡像也是個難題,假設私有鏡像倉庫名爲 localhost:5000,確定會和編排文件中寫的不一致,對此咱們有兩種方式解決:

  • 第一種是 hack 和 docker,作了一個只要私有鏡像倉庫中有就直接從私有鏡像中拉取,沒有才去公網拉取鏡像的能力。
  • 第二種方案是無侵入 docke r的 proxy,把 docker 請求所有打給代理,讓代理去決定若是私有倉庫有就從私有倉庫拉取。同時咱們還加強了 registry 的能力讓 registry 能夠 cache 多個遠程倉庫的能力。

image.png

sealer 的這種方案完美解決了離線場景鏡像打包的問題。

負載均衡

sealer 的集羣高可用使用了輕量級的負載均衡 lvscare。相比其它負載均衡,lvscare 很是小僅有幾百行代碼,並且 lvscare 只作 ipvs 規則的守護,自己不作負載很是穩定,直接在 node 上監聽 apiserver,若是跪了就移除對應的規則,從新起來以後會自動加回,至關因而一個專用的負載均衡器,在 sealos 項目中也用了兩年多,有普遍的實踐。

image.png

運行時

運行時就是支撐應用運行的環境,像 base on Kuberentes 的運行時 sealer 就能夠透明地支持很是簡單,以 istio 爲例,用戶只須要:

FROM kubernetes:v1.18.3
RUN curl -L https://istio.io/downloadIstio | sh -

就能夠 build 出一個 istio 的運行時供本身應用使用。

對於不是 base on Kuberentes 的運行時,如 k0s k3s,能夠擴展 sealer.Runtime 中的接口,這樣之後就能夠:

FROM k3s:v1.18.3
RUN curl -L https://istio.io/downloadIstio | sh -

更牛的擴展好比擴展 ACK 的 runtime:

FROM aliyum.com/ACK:v1.16.9
RUN curl -L https://istio.io/downloadIstio | sh -

這種鏡像會直接幫助用戶應用運行到 ACK 上。以上有些能力在 roadmap 中。

基礎設施

如今不少用戶都但願在雲端運行本身的集羣鏡像,sealer 自帶對接公有云能力,sealer 本身實現的基礎設施管理器,得益於咱們更精細的退避重試機制,30s 便可完成基礎設施構建(阿里雲 6 節點)性能是同類工具中的佼佼者,且 API 調用次數大大下降,配置兼容 Clusterfile。

總結

sealer 將來的一些願景與價值體現:

  • sealer 能夠以極其簡單的方式讓用戶自定義集羣,解決分佈式軟件製做者與使用者的協做問題。
  • 極其簡單友好的 User Interface,能屏蔽和兼容各類底層技術細節,處處運行。
  • 生態建設,官方倉庫裏將會涵蓋經常使用的分佈式軟件。

最後咱們總結下:

  • 若是你要總體交付你的分佈式 SaaS,請用 sealer。
  • 若是你要集成多個分佈式服務在一塊兒,如數據庫消息隊列或者微服務運行時,請用 sealer。
  • 若是你要安裝一個分佈式應用如 mysql 主備集羣,請用 sealer。
  • 若是你須要安裝/管理一個 Kubernetes 高可用集羣,請用 sealer。
  • 若是你要初始化多個數據中心,保持多個數據中心狀態強一致,請用 sealer。
  • 若是你須要在公有云上實現上述場景,請用 sealer。

sealer 將會在近期宣佈開源,有興趣的能夠關注:_https://github.com/alibaba/sealer_

本文內容由阿里雲實名註冊用戶自發貢獻,版權歸原做者全部,阿里雲開發者社區不擁有其著做權,亦不承擔相應法律責任。具體規則請查看《阿里雲開發者社區用戶服務協議》和《阿里雲開發者社區知識產權保護指引》。若是您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將馬上刪除涉嫌侵權內容。
相關文章
相關標籤/搜索