sealer,“集羣” 版本的 Docker,交付複雜度的終結者
背景
隨着時代的發展,單機上跑的單體應用已經越來越少了,分佈式應用幾乎已經無處不在。Docker 很好的對單機應用進行了鏡像化的封裝,實現在單機上 Build Ship Run, 從此單機上應用的運行沒有什麼是一個 docker run 解決不了的。
docker 對比 rpm 之類的工具顯然一致性好很多,原因是 docker 把 rootfs 同樣封裝到了鏡像之中,也就是所有的依賴都在鏡像中。
再看集羣和分佈式應用,以前 IaaS 主導的雲計算只對資源進行了抽象,顯然一個操作系統是承上啓下的作用,向上需要有很好的應用管理能力,kubernetes 很符合這一定義。
所以現在假設 kubernetes 是管理所有服務器的操作系統,在這個前提下我們要設計一個 “集羣” 版本的 Docker,這就是我們今天的主角 sealer。
目前 sealer 也捐獻給了 CNCF 基金會,項目地址:https://github.com/sealerio/sealer
快速開始
聯想一下 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
這樣一個六節點的集羣就起來了,當然 sealer 同樣支持單節點。
同理,我們可以運行分佈式軟件如:
sealer run mysql-cluster:8.0
sealer run redis:5.0
各種分佈式軟件一鍵安裝交付。
交付的痛點
想象沒有 sealer 交付的故事是什麼樣的?假設你已經使用了 kubernetes helm 這些工具,當然沒使用的只會比以下步驟更痛苦。
-
找一個能在離線環境中安裝 kubernetes 本身的工具
-
加載你事先打包好的所有 docker 鏡像
-
啓動一個私有鏡像倉庫
-
把所有鏡像推送到私有鏡像倉庫中
-
修改編排文件中鏡像倉庫地址
-
執行所有的 helm chart
而使用 sealer 交付故事是:
-
加載集羣鏡像
-
sealer run [集羣鏡像]
如果的交付文檔很長,整個交付面向過程,那就很適合使用 sealer,可以在整個集羣一致性上保證交付成功。
那麼如何去構建一個自定義的集羣鏡像呢?
Build 集羣鏡像
sealer 運行分佈式應用很簡單,同樣要去自定義一個集羣鏡像也需要很簡單,這裏採用與 Docker 鏡像幾乎相同的方式進行構建。
這裏以構建一個 dashboard 的集羣鏡像爲例子:
- 編寫一個類似 Dockerfile 的文件,我們叫 Kubefile
FROM kubernetes:v1.19.8
RUN wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
CMD kubectl apply -f recommended.yaml
第一行 FROM kubernetes:v1.19.8
可以選擇你想要的基礎鏡像。
RUN 指令只會在 Build 的時候執行,去下載 dashboard 的 yaml 文件。
CMD 指令會在集羣啓動後執行,所以這裏並不關心用戶使用什麼編排工具,比如 sealer 可以很好的與 helm 搭配使用。
- build
sealer build -t dashboard:latest .
這裏 sealer 不僅只是把 RUN 命令執行了一下,還會去掃描裏面包含的所有 docker 鏡像並緩存到集羣鏡像中,這樣啓動的時候會直接從緩存的私有鏡像倉庫中去下載鏡像。
- Run
sealer run dashboard:latest --masters 192.168.0.2 --passwd xxx
kubectl get pod -A|grep dashboard
現在我們就可以運行這個集羣鏡像,sealer 會先拉起一個 kubernetes 集羣,再在其上面部署 dashboard。
這裏神奇的地方是雖然 dashboard 編排文件裏面寫的是 gcr 倉庫的鏡像地址,sealer 並不會從公網去拉取,而會檢測私有鏡像倉庫是是否存在該鏡像,有的話直接從私有鏡像倉庫中拉取。如此 即便在離線環境中也可以正常拉到鏡像,而且整個過程什麼也不需要修改。
- Push
sealer push registry.cn-qingdao.aliyuncs.com/sealer-io/dashboard:latest
可以把剛纔的集羣鏡像 push 到任意的 registry 中,比如 docker hub。
配置管理
看到上面你可能會感覺確實簡單,但是功能好像不太滿足,因爲一次交付,幾乎會有非常多的配置文件需要管理與調整,這在 sealer 裏面如何處理?
sealer 對這塊的設計也有充分考慮,答案是使用 Clusterfile。
Clusterfile 說白了是就告訴 sealer 啓動整個集羣需要的配置是怎樣的。
apiVersion: sealer.cloud/v2
kind: Cluster
metadata:
name: default-kubernetes-cluster
spec:
image: kubernetes:v1.19.8
ssh:
passwd: xxx
hosts:
- 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/v1beta2
kind: ClusterConfiguration
networking:
podSubnet: 100.64.0.0/10
你不需要把所有配置寫全,只需要寫你關心的字段,會自動合併到默認配置中。
業務配置使用更通用的做法:
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Config
metadata:
name: mysql-config
spec:
path: etc/mysql.yaml
data: |
mysql-user: root
mysql-passwd: xxx
data 裏面的內容會覆蓋鏡像內部的 path, 指定的文件,同樣支持是直接覆蓋還是合併等一些策略,那麼這裏的內容就很適合是 helm values.
sealer 同樣支持用環境變量管理少量配置:
apiVersion: sealer.cloud/v2
kind: Cluster
metadata:
name: my-cluster
spec:
image: kubernetes:v1.19.8
env:
docker-dir: /var/lib/docker
hosts:
- ips: [ 192.168.0.2 ]
roles: [ master ] # add role field to specify the node role
env: # overwrite some nodes has different env config
docker-dir: /data/docker
- ips: [ 192.168.0.3 ]
roles: [ node ]
鏡像內部的腳本就可以直接使用 docker-dir 環境變量:
#!/bin/bash
echo $docker-dir
插件機制
插件可以幫助用戶做一些之外的事情,比如更改主機名,升級內核,或者添加節點標籤等……
主機名插件
如果你在 Clusterfile 後添加插件配置並應用它,sealer 將幫助你更改所有的主機名:
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: hostname
spec:
type: HOSTNAME
data: |
192.168.0.2 master-0
192.168.0.3 master-1
192.168.0.4 master-2
192.168.0.5 node-0
192.168.0.6 node-1
192.168.0.7 node-2
Hostname Plugin 將各個節點在安裝集羣前修改爲對應的主機名。
腳本插件
如果你在 Clusterfile 後添加 Shell 插件配置並應用它,sealer 將幫助你執行 shell 命令 (執行路徑爲鏡像 Rootfs 目錄):
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: shell
spec:
type: SHELL
action: PostInstall
'on': node-role.kubernetes.io/master=
data: |
kubectl taint nodes node-role.kubernetes.io/master=:NoSchedule
action : [PreInit| PostInstall] # 指定執行shell的時機
在初始化之前執行命令 | action: PreInit
在添加節點之前執行命令 | action: PreJoin
在添加節點之後執行命令 | action: PostJoin
在執行Kubefile CMD之前 | action: PreGuest
在安裝集羣之後執行命令 | action: PostInstall
在清理集羣前執行命令 | action: PreClean
在清理集羣后執行命令 | action: PostClean
組合使用 | action: PreInit|PreJoin
on : #指定執行命令的機器
爲空時默認在所有節點執行
在所有master節點上執行 | 'on': master
在所有node節點上執行 | 'on': node
在指定IP上執行 | 'on': 192.168.56.113,192.168.56.114,192.168.56.115,192.168.56.116
在有連續IP的機器上執行 | 'on': 192.168.56.113-192.168.56.116
在指定label節點上執行(action需爲PostInstall或PreClean) | 'on': node-role.kubernetes.io/master=
data : #指定執行的shell命令
標籤插件
如果你在 Clusterfile 後添加 label 插件配置並應用它,sealer 將幫助你添加 label:
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: label
spec:
type: LABEL
action: PreGuest
data: |
192.168.0.2 ssd=true
192.168.0.3 ssd=true
192.168.0.4 ssd=true
192.168.0.5 ssd=false,hdd=true
192.168.0.6 ssd=false,hdd=true
192.168.0.7 ssd=false,hdd=true
節點 ip 與標籤之前使用空格隔開,多個標籤之間使用逗號隔開。
集羣檢測插件
由於服務器以及環境因素 (服務器磁盤性能差) 可能會導致 sealer 安裝完 kubernetes 集羣后,立即部署應用服務,出現部署失敗的情況。cluster check 插件會等待 kubernetes 集羣穩定後再部署應用服務。
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: checkCluster
spec:
type: CLUSTERCHECK
action: PreGuest
污點插件
如果你在 Clusterfile 後添加 taint 插件配置並應用它,sealer 將幫助你添加污點和去污點:
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: taint
spec:
type: TAINT
action: PreGuest
data: |
192.168.56.3 key1=value1:NoSchedule
192.168.56.4 key2=value2:NoSchedule-
192.168.56.3-192.168.56.7 key3:NoSchedule
192.168.56.3,192.168.56.4,192.168.56.5,192.168.56.6,192.168.56.7 key4:NoSchedule
192.168.56.3 key5=:NoSchedule
192.168.56.3 key6:NoSchedule-
192.168.56.4 key7:NoSchedule-
data 寫法爲
ips taint_argument
ips : 多個 ip 通過,
連接,連續 ip 寫法爲 首 ip - 末尾 ip taint_argument: 同 kubernetes 添加或去污點寫法 (key=value:effect #effect 必須爲:NoSchedule, PreferNoSchedule 或 NoExecute)。
插件使用步驟
Clusterfile 內容:
apiVersion: sealer.aliyun.com/v1alpha1
kind: Cluster
metadata:
name: my-cluster
spec:
image: registry.cn-qingdao.aliyuncs.com/sealer-io/kubernetes:v1.19.8
provider: BAREMETAL
ssh:
# ssh的私鑰文件絕對路徑,例如/root/.ssh/id_rsa
pk: xxx
# ssh的私鑰文件密碼,如果沒有的話就設置爲""
pkPasswd: xxx
# ssh登錄用戶
user: root
# ssh的登錄密碼,如果使用的密鑰登錄則無需設置
passwd: xxx
network:
podCIDR: 100.64.0.0/10
svcCIDR: 10.96.0.0/22
certSANS:
- aliyun-inc.com
- 10.0.0.2
masters:
ipList:
- 192.168.0.2
- 192.168.0.3
- 192.168.0.4
nodes:
ipList:
- 192.168.0.5
- 192.168.0.6
- 192.168.0.7
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: hostname
spec:
type: HOSTNAME
data: |
192.168.0.2 master-0
192.168.0.3 master-1
192.168.0.4 master-2
192.168.0.5 node-0
192.168.0.6 node-1
192.168.0.7 node-2
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: taint
spec:
type: SHELL
action: PostInstall
on: node-role.kubernetes.io/master=
data: |
kubectl taint nodes node-role.kubernetes.io/master=:NoSchedule
sealer apply -f Clusterfile #plugin僅在安裝時執行,後續apply不生效。
執行上述命令後 hostname,shell plugin 將修改主機名並在成功安裝集羣后執行 shell 命令。
在 Kubefile 中定義默認插件
很多情況下在不使用 Clusterfile 的情況下也能使用插件,本質上 sealer 會先把 Clusterfile 中的插件配置先存儲到 rootfs/plugins 目錄,再去使用,所以我們可以在製作鏡像時就定義好默認插件。
插件配置文件 shell.yaml:
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: taint
spec:
type: SHELL
action: PostInstall
on: node-role.kubernetes.io/master=
data: |
kubectl get nodes
---
apiVersion: sealer.aliyun.com/v1alpha1
kind: Plugin
metadata:
name: SHELL
spec:
action: PostInstall
data: |
if type yum >/dev/null 2>&1;then
yum -y install iscsi-initiator-utils
systemctl enable iscsid
systemctl start iscsid
elif type apt-get >/dev/null 2>&1;then
apt-get update
apt-get -y install open-iscsi
systemctl enable iscsid
systemctl start iscsid
fi
Kubefile:
FROM kubernetes:v1.19.8
COPY shell.yaml plugin
構建一個包含安裝 iscsi 的插件 (或更多插件) 的集羣鏡像:
sealer build -m lite -t kubernetes-iscsi:v1.19.8 .
通過鏡像啓動集羣后插件也將被執行,而無需在 Clusterfile 中定義插件: sealer run kubernetes-iscsi:v1.19.8 -m x.x.x.x -p xxx
總結
以上對 sealer 的核心能力有了一個整體的介紹,目前 sealer 已經在多家企業中生產落地,阿里內部也有非常多的實踐,sealer 未來會重點在性能上做進一步突破,加強生態集羣鏡像製作,幫助企業和開發者更快進行交付。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/81Gl0b8s3OfWWVCLR_SmLQ