sealer,“集群”版本的 Docker,交付復(fù)雜度的終結(jié)者
背景
隨著時代的發(fā)展,單機上跑的單體應(yīng)用已經(jīng)越來越少了,分布式應(yīng)用幾乎已經(jīng)無處不在。Docker 很好的對單機應(yīng)用進行了鏡像化的封裝,實現(xiàn)在單機上 Build Ship Run, 從此單機上應(yīng)用的運行沒有什么是一個 docker run 解決不了的。
docker 對比 rpm 之類的工具顯然一致性好很多,原因是 docker 把 rootfs 同樣封裝到了鏡像之中,也就是所有的依賴都在鏡像中。
再看集群和分布式應(yīng)用,以前 IaaS 主導(dǎo)的云計算只對資源進行了抽象,顯然一個操作系統(tǒng)是承上啟下的作用,向上需要有很好的應(yīng)用管理能力,kubernetes 很符合這一定義。
所以現(xiàn)在假設(shè) kubernetes 是管理所有服務(wù)器的操作系統(tǒng),在這個前提下我們要設(shè)計一個 “集群” 版本的 Docker,這就是我們今天的主角 sealer。
目前 sealer 也捐獻(xiàn)給了 CNCF 基金會,項目地址:https://github.com/sealerio/sealer
(點擊文末閱讀原文可直接跳轉(zhuǎn)哦~)
快速開始
聯(lián)想一下 Docker 我們需要啟動一個 centos 容器:
docker run centos所以要用 sealer 啟動一個 kubernetes 集群,只需要:
sealer run kubernetes:v1.19.8 \--masters 192.168.0.2,192.168.0.3,192.168.0.4 \--nodes 192.168.0.5,192.168.0.6,192.168.0.7 --passwd xxx
這樣一個六節(jié)點的集群就起來了,當(dāng)然 sealer 同樣支持單節(jié)點。
同理,我們可以運行分布式軟件如:
sealer run mysql-cluster:8.0sealer run redis:5.0
各種分布式軟件一鍵安裝交付。
交付的痛點
想象沒有 sealer 交付的故事是什么樣的?假設(shè)你已經(jīng)使用了 kubernetes helm 這些工具,當(dāng)然沒使用的只會比以下步驟更痛苦。
找一個能在離線環(huán)境中安裝 kubernetes 本身的工具 加載你事先打包好的所有 docker 鏡像 啟動一個私有鏡像倉庫 把所有鏡像推送到私有鏡像倉庫中 修改編排文件中鏡像倉庫地址 執(zhí)行所有的 helm chart
而使用 sealer 交付故事是:
加載集群鏡像 sealer run [集群鏡像]
如果的交付文檔很長,整個交付面向過程,那就很適合使用 sealer,可以在整個集群一致性上保證交付成功。
那么如何去構(gòu)建一個自定義的集群鏡像呢?
Build 集群鏡像
sealer 運行分布式應(yīng)用很簡單,同樣要去自定義一個集群鏡像也需要很簡單,這里采用與 Docker 鏡像幾乎相同的方式進行構(gòu)建。
這里以構(gòu)建一個 dashboard 的集群鏡像為例子:
編寫一個類似 Dockerfile 的文件,我們叫 Kubefile
FROM kubernetes:v1.19.8RUN wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yamlCMD kubectl apply -f recommended.yaml
第一行?FROM kubernetes:v1.19.8?可以選擇你想要的基礎(chǔ)鏡像。
RUN 指令只會在 Build 的時候執(zhí)行,去下載 dashboard 的 yaml 文件。
CMD 指令會在集群啟動后執(zhí)行,所以這里并不關(guān)心用戶使用什么編排工具,比如 sealer 可以很好的與 helm 搭配使用。
build
sealer build -t dashboard:latest .這里 sealer 不僅只是把 RUN 命令執(zhí)行了一下,還會去掃描里面包含的所有 docker 鏡像并緩存到集群鏡像中,這樣啟動的時候會直接從緩存的私有鏡像倉庫中去下載鏡像。
Run
sealer run dashboard:latest --masters 192.168.0.2 --passwd xxxkubectl get pod -A|grep dashboard
現(xiàn)在我們就可以運行這個集群鏡像,sealer 會先拉起一個 kubernetes 集群,再在其上面部署 dashboard。
這里神奇的地方是雖然 dashboard 編排文件里面寫的是 gcr 倉庫的鏡像地址,sealer 并不會從公網(wǎng)去拉取,而會檢測私有鏡像倉庫是是否存在該鏡像,有的話直接從私有鏡像倉庫中拉取。如此 即便在離線環(huán)境中也可以正常拉到鏡像,而且整個過程什么也不需要修改。
Push
sealer push registry.cn-qingdao.aliyuncs.com/sealer-io/dashboard:latest可以把剛才的集群鏡像 push 到任意的 registry 中,比如 docker hub。
配置管理
看到上面你可能會感覺確實簡單,但是功能好像不太滿足,因為一次交付,幾乎會有非常多的配置文件需要管理與調(diào)整,這在 sealer 里面如何處理?
sealer 對這塊的設(shè)計也有充分考慮,答案是使用 Clusterfile。
Clusterfile 說白了是就告訴 sealer 啟動整個集群需要的配置是怎樣的。
apiVersion: sealer.cloud/v2kind: Clustermetadata:name: default-kubernetes-clusterspec:image: kubernetes:v1.19.8ssh:passwd: xxxhosts:- ips: [ 192.168.0.2,192.168.0.3,192.168.0.4 ]roles: [ master ]- ips: [ 192.168.0.5 ]roles: [ node ]
sealer apply -f Clusterfile?即可啟動整個集群。
常見需求,比如想修改一個 podsubnet, sealer 支持 merge 所有 kubeadm 配置文件:
---apiVersion: kubeadm.k8s.io/v1beta2kind: ClusterConfigurationnetworking:podSubnet: 100.64.0.0/10
你不需要把所有配置寫全,只需要寫你關(guān)心的字段,會自動合并到默認(rèn)配置中。
業(yè)務(wù)配置使用更通用的做法:
---apiVersion: sealer.aliyun.com/v1alpha1kind: Configmetadata:name: mysql-configspec:path: etc/mysql.yamldata: |mysql-user: rootmysql-passwd: xxx
data 里面的內(nèi)容會覆蓋鏡像內(nèi)部的 path, 指定的文件,同樣支持是直接覆蓋還是合并等一些策略,那么這里的內(nèi)容就很適合是 helm values.
sealer 同樣支持用環(huán)境變量管理少量配置:
apiVersion: sealer.cloud/v2kind: Clustermetadata:name: my-clusterspec:image: kubernetes:v1.19.8env:docker-dir: /var/lib/dockerhosts:- ips: [ 192.168.0.2 ]roles: [ master ] # add role field to specify the node roleenv: # overwrite some nodes has different env configdocker-dir: /data/docker- ips: [ 192.168.0.3 ]roles: [ node ]
鏡像內(nèi)部的腳本就可以直接使用 docker-dir 環(huán)境變量:
echo $docker-dir
插件機制
插件可以幫助用戶做一些之外的事情,比如更改主機名,升級內(nèi)核,或者添加節(jié)點標(biāo)簽等……
主機名插件
如果你在 Clusterfile 后添加插件配置并應(yīng)用它,sealer 將幫助你更改所有的主機名:
apiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: hostnamespec:type: HOSTNAMEdata: |192.168.0.2 master-0192.168.0.3 master-1192.168.0.4 master-2192.168.0.5 node-0192.168.0.6 node-1192.168.0.7 node-2
Hostname Plugin 將各個節(jié)點在安裝集群前修改為對應(yīng)的主機名。
腳本插件
如果你在 Clusterfile 后添加 Shell 插件配置并應(yīng)用它,sealer 將幫助你執(zhí)行 shell 命令 (執(zhí)行路徑為鏡像 Rootfs 目錄):
apiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: shellspec:type: SHELLaction: PostInstall'on': node-role.kubernetes.io/master=data: |kubectl taint nodes node-role.kubernetes.io/master=:NoSchedule
action : [PreInit| PostInstall] # 指定執(zhí)行shell的時機在初始化之前執(zhí)行命令 | action: PreInit在添加節(jié)點之前執(zhí)行命令 | action: PreJoin在添加節(jié)點之后執(zhí)行命令 | action: PostJoin在執(zhí)行Kubefile CMD之前 | action: PreGuest在安裝集群之后執(zhí)行命令 | action: PostInstall在清理集群前執(zhí)行命令 | action: PreClean在清理集群后執(zhí)行命令 | action: PostClean組合使用 | action: PreInit|PreJoinon : #指定執(zhí)行命令的機器為空時默認(rèn)在所有節(jié)點執(zhí)行在所有master節(jié)點上執(zhí)行 | 'on': master在所有node節(jié)點上執(zhí)行 | 'on': node在指定IP上執(zhí)行 | 'on': 192.168.56.113,192.168.56.114,192.168.56.115,192.168.56.116在有連續(xù)IP的機器上執(zhí)行 | 'on': 192.168.56.113-192.168.56.116在指定label節(jié)點上執(zhí)行(action需為PostInstall或PreClean) | 'on': node-role.kubernetes.io/master=data : #指定執(zhí)行的shell命令
標(biāo)簽插件
如果你在 Clusterfile 后添加 label 插件配置并應(yīng)用它,sealer 將幫助你添加 label:
apiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: labelspec:type: LABELaction: PreGuestdata: |192.168.0.2 ssd=true192.168.0.3 ssd=true192.168.0.4 ssd=true192.168.0.5 ssd=false,hdd=true192.168.0.6 ssd=false,hdd=true192.168.0.7 ssd=false,hdd=true
節(jié)點 ip 與標(biāo)簽之前使用空格隔開,多個標(biāo)簽之間使用逗號隔開。
集群檢測插件
由于服務(wù)器以及環(huán)境因素 (服務(wù)器磁盤性能差) 可能會導(dǎo)致 sealer 安裝完 kubernetes 集群后,立即部署應(yīng)用服務(wù),出現(xiàn)部署失敗的情況。cluster check 插件會等待 kubernetes 集群穩(wěn)定后再部署應(yīng)用服務(wù)。
apiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: checkClusterspec:type: CLUSTERCHECKaction: PreGuest
污點插件
如果你在 Clusterfile 后添加 taint 插件配置并應(yīng)用它,sealer 將幫助你添加污點和去污點:
apiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: taintspec:type: TAINTaction: PreGuestdata: |192.168.56.3 key1=value1:NoSchedule192.168.56.4 key2=value2:NoSchedule-192.168.56.3-192.168.56.7 key3:NoSchedule192.168.56.3,192.168.56.4,192.168.56.5,192.168.56.6,192.168.56.7 key4:NoSchedule192.168.56.3 key5=:NoSchedule192.168.56.3 key6:NoSchedule-192.168.56.4 key7:NoSchedule-
data 寫法為?
ips taint_argument?ips ?: 多個 ip 通過?,?連接,連續(xù) ip 寫法為 首 ip - 末尾 ip taint_argument: 同 kubernetes 添加或去污點寫法 (key=value:effect #effect 必須為:NoSchedule, PreferNoSchedule 或 NoExecute)。
插件使用步驟
Clusterfile 內(nèi)容:
apiVersion: sealer.aliyun.com/v1alpha1kind: Clustermetadata:name: my-clusterspec:image: registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8provider: BAREMETALssh:# ssh的私鑰文件絕對路徑,例如/root/.ssh/id_rsapk: xxx# ssh的私鑰文件密碼,如果沒有的話就設(shè)置為""pkPasswd: xxx# ssh登錄用戶user: root# ssh的登錄密碼,如果使用的密鑰登錄則無需設(shè)置passwd: xxxnetwork:podCIDR: 100.64.0.0/10svcCIDR: 10.96.0.0/22certSANS:- aliyun-inc.com- 10.0.0.2masters:ipList:- 192.168.0.2- 192.168.0.3- 192.168.0.4nodes:ipList:- 192.168.0.5- 192.168.0.6- 192.168.0.7---apiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: hostnamespec:type: HOSTNAMEdata: |192.168.0.2 master-0192.168.0.3 master-1192.168.0.4 master-2192.168.0.5 node-0192.168.0.6 node-1192.168.0.7 node-2---apiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: taintspec:type: SHELLaction: PostInstallon: node-role.kubernetes.io/master=data: |kubectl taint nodes node-role.kubernetes.io/master=:NoSchedule
sealer apply -f Clusterfile #plugin僅在安裝時執(zhí)行,后續(xù)apply不生效。執(zhí)行上述命令后 hostname,shell plugin 將修改主機名并在成功安裝集群后執(zhí)行 shell 命令。
在 Kubefile 中定義默認(rèn)插件
很多情況下在不使用 Clusterfile 的情況下也能使用插件,本質(zhì)上 sealer 會先把 Clusterfile 中的插件配置先存儲到 rootfs/plugins 目錄,再去使用,所以我們可以在制作鏡像時就定義好默認(rèn)插件。
插件配置文件 shell.yaml:
apiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: taintspec:type: SHELLaction: PostInstallon: node-role.kubernetes.io/master=data: |kubectl get nodesapiVersion: sealer.aliyun.com/v1alpha1kind: Pluginmetadata:name: SHELLspec:action: PostInstalldata: |if type yum >/dev/null 2>&1;thenyum -y install iscsi-initiator-utilssystemctl enable iscsidsystemctl start iscsidelif type apt-get >/dev/null 2>&1;thenapt-get updateapt-get -y install open-iscsisystemctl enable iscsidsystemctl start iscsidfi
Kubefile:
FROM kubernetes:v1.19.8COPY shell.yaml plugin
構(gòu)建一個包含安裝 iscsi 的插件 (或更多插件) 的集群鏡像:
sealer build -m lite -t kubernetes-iscsi:v1.19.8 .通過鏡像啟動集群后插件也將被執(zhí)行,而無需在 Clusterfile 中定義插件:?sealer run kubernetes-iscsi:v1.19.8 -m x.x.x.x -p xxx
總結(jié)
以上對 sealer 的核心能力有了一個整體的介紹,目前 sealer 已經(jīng)在多家企業(yè)中生產(chǎn)落地,阿里內(nèi)部也有非常多的實踐,sealer 未來會重點在性能上做進一步突破,加強生態(tài)集群鏡像制作,幫助企業(yè)和開發(fā)者更快進行交付。
往期推薦
想要了解Go更多內(nèi)容,歡迎掃描下方???關(guān)注?公眾號,回復(fù)關(guān)鍵詞 [實戰(zhàn)群]? ,就有機會進群和我們進行交流~
分享、在看與點贊,至少我要擁有一個叭~




