本文首發於:微信公眾號「運維之美」,公眾號 ID:Hi-Linux。
「運維之美」是一個有情懷、有態度,專注於 Linux 運維相關技術文章分享的公眾號。公眾號致力於為廣大運維工作者分享各類技術文章和發布最前沿的科技信息。公眾號的核心理念是:分享,我們認為只有分享才能使我們的團體更強大。如果你想第一時間獲取最新技術文章,歡迎關注我們!
公眾號作者 Mike,一個月薪 3000 的雜工。從事 IT 相關工作 15+ 年,熱衷於互聯網技術領域,認同開源文化,對運維相關技術有自己獨特的見解。很願意將自己積累的經驗、心得、技能與大家分享交流,篇篇干貨不要錯過喲。如果你想聯系到我,可關注公眾號獲取相關信息。
前段時間,我們在 「使用 Kind 在 5 分鍾內快速部署一個 Kubernetes 高可用集群」一文中介紹了如何使用 Kind
這個開箱即可快速部署 Kubernetes
高可用集群的神器,相信不少同學用上這個神器后大大的降低了 Kubernetes
集群的部署難度和提高了 Kubernetes
集群的部署速度。不過有一點比較遺憾的是 Kind
當前僅僅支持在本地快速構建一個開發或者測試環境,目前暫時還是不支持在生產環境中部署 Kubernetes
高可用集群的。
今天,我們就要給大家介紹另一款可以支持在生產環境中部署 Kubernetes
高可用集群的利器 Sealos
。
什么是 Sealos ?
Sealos
是一個 Go 語言開發的簡單干凈且輕量的 Kubernetes
集群部署工具,Sealos
能很好的支持在生產環境中部署高可用的 Kubernetes
集群。
Sealos
架構圖
Sealos 特性與優勢
-
支持離線安裝,工具與部署資源包分離,方便不同版本間快速升級。
-
證書有效期默認延期至 99 年。
-
工具使用非常簡單。
-
支持使用自定義配置文件,可靈活完成集群環境定制。
-
使用內核進行本地負載,穩定性極高,故障排查也極其簡單。
Sealos 設計原則和工作原理
1. 為什么不使用 Ansilbe 實現
Sealos 1.0
版本時是使用 Ansible
實現的,這樣在使用時就必須先安裝 Ansible
及一些 Python
的依賴包和進行一些必須的相關環境配置,使用起來還是比較復雜的。
為了解決這個問題,目前新版本的 Sealos
采用二進制文件方式提供。新版本 Sealos
沒有任何依賴,開箱即用。
文件分發與遠程命令都通過調用對應
SDK
實現,不依賴其它任何環境。
2. 為什么不用 KeepAlived 和 HAProxy 實現集群高可用
無論是通過 KeepAlived
還是 HAProxy
進行高可用集群調度都會存在以下一些劣勢。
-
軟件源不一致可能導致容器中安裝的軟件版本也不一致,進而會引起相應檢查腳本不生效等故障。
-
可能因為系統依賴庫問題,在某些特定環境下就直接無法完成安裝。
-
只依靠檢測
HAProxy
進程是否存活是無法保證集群高可用的,正確的檢測方式應該是判斷ApiServer
是否healthz
狀態。 -
Keepalived
可能存在Cpu
占滿的情況。
3. 本地負載為什么不使用 Envoy 或者 Nginx 實現
Sealos
高可用實現是通過本地負載方式完成的。本地負載實現方式有多種,比如:IPVS
、Envoy
、Nginx
等,而 Sealos
采用的是通過內核 IPVS
來實現的。
本地負載:在每個
Node
節點上都啟動一個負載均衡,同時監聽集群中的多個Master
節點。
Sealos
選擇通過內核 IPVS
來實現主要有以下幾個原因:
-
如果使用
Envoy
等需要在每個節點上都跑一個進程,消耗更多資源。雖然IPVS
實際上也會多跑一個lvscare
進程 ,但是lvscare
只是負責管理IPVS
規則,原理和Kube-Proxy
類似。真正的流量直接從內核層面走,不需要把數據包先走到用戶態中去處理。 -
使用
Envoy
存在啟動優先級的問題,比如:Join 集群時,如果負載均衡沒有建立,Kubelet 就會啟動失敗。使用IPVS
則不會存在這樣的問題,因為我們可以在 Join 集群前先建立好轉發規則。
3.1 本地內核負載工作原理
Sealos
通過本地內核負載的方式實現每個 Node
節點負載均衡訪問所有 Master
節點,具體參見下圖。
+----------+ +---------------+ virturl server: 127.0.0.1:6443
| mater0 |<----------------------| ipvs nodes | real servers:
+----------+ |+---------------+ 10.103.97.200:6443
| 10.103.97.201:6443
+----------+ | 10.103.97.202:6443
| mater1 |<---------------------+
+----------+ |
|
+----------+ |
| mater2 |<---------------------+
+----------+
在所有 Node
節點上啟動一個包含 lvscare
進程的 Static Pod
對 IPVS
進行守護。 如果檢測到 ApiServer
不可用時,Sealos
會自動清理掉所有 Node
節點上對應的主節點 IPVS
轉發規則。直到 Master
節點恢復正常時,再自動生成對應規則。為了實現以上功能,我們在 Node
節點上增加了下面這些內容。
# 增加了一個 lvscare 的 Static Pod
$ cat /etc/kubernetes/manifests
# 自動創建的一些 IPVS 規則
$ ipvsadm -Ln
# 增加了對虛擬 IP 的地址解析
$ cat /etc/hosts
4. 為什么要定制 Kubeadm
-
解決默認證書有效期只有一年的問題。
-
更方便的實現本地負載。
-
核心的功能均集成到 Kubeadm 中了,Sealos 只管分發和執行上層命令,相對就更輕量了。
5. Sealos 執行流程
-
通過
SFTP
或者Wget
命令把離線安裝包拷貝到目標機器上,包括所有Master
和Node
節點。 -
在
Master 0
節點上執行kubeadm init
命令。 -
在其它
Master
節點上執行kubeadm join
命令並設置控制面。這個過程中多個Master
節點上的Etcd
會自動組成一個Etcd
集群,並啟動相應控制組件。 -
所有
Node
節點都加入到集群中,這個過程中會在Node
節點上進行IPVS
轉發規則和/etc/hosts
配置。
Node
節點對ApiServer
的訪問均是通過域名進行的。因為Node
節點需要通過虛擬 IP
連接到多個Master
上,但是每個Node
節點的Kubelet
與Kube-Proxy
訪問ApiServer
的地址是不同的,所以這里使用域名來解析每個節點上ApiServer
不同的IP
地址。
使用 Sealos 部署高可用 Kubernetes 集群
1. 安裝相關環境依賴
通過 Sealos
進行 Kubernetes
集群部署,你需要先准備好以下環境。
-
在所有要部署的機器上,先完成
Docker
的安裝和啟動。 -
下載
Kubernetes
離線安裝包。 -
下載最新版本
Sealos
。 -
對所有服務器進行時間同步。
Sealos 項目地址:https://github.com/fanux/sealos/releases
Kubernetes 離線安裝包:https://github.com/sealstore/cloud-kernel/releases/
2. 通過 Sealos 部署高可用 Kubernetes 集群
目前 Sealos
已經支持最新版本 Kubernetes 1.16.0
的高可用集群安裝。
2.1 Sealos 常用參數說明
--master Master 節點服務器地址列表
--node Node 節點服務器地址列表
--user 服務器 SSH 用戶名
--passwd 服務器 SSH 用戶密碼
--pkg-url 離線包所在位置,可以是本地目錄,也可以是一個 HTTP 地址
--version 指定需要部署的 Kubernetes 版本
--pk 指定 SSH 私鑰所在位置,默認為 /root/.ssh/id_rsa
Other flags:
--kubeadm-config string kubeadm-config.yaml 用於指定自定義 kubeadm 配置文件
--vip string virtual ip (default "10.103.97.2") 本地負載時虛擬 IP ,不推薦修改,集群外不可訪問
2.2 部署一個單主節點的 Kubernetes 集群
通過 Sealos
部署 Kubernetes
集群是非常簡單的 ,通常只需以下兩條指令就可以完成安裝。
$ wget https://github.com/fanux/sealos/releases/download/v2.0.7/sealos && \
chmod +x sealos && mv sealos /usr/bin
$ sealos init --passwd YOUR_SERVER_PASSWD \
--master 192.168.0.2 --master 192.168.0.3 --master 192.168.0.4 \
--node 192.168.0.5 \
--pkg-url https://sealyun.oss-cn-beijing.aliyuncs.com/cf6bece970f6dab3d8dc8bc5b588cc18-1.16.0/kube1.16.0.tar.gz \
--version v1.16.0
如果你的服務器已經配置了 SSH
免密登陸,你可以直接使用對應密鑰進行部署。
$ sealos init --master 192.168.0.2 \
--node 192.168.0.3 \
--pkg-url https://YOUR_HTTP_SERVER/kube1.15.0.tar.gz \
--pk /root/kubernetes.pem \
--version v1.16.0
如果你需要其它 Kubernetes
版本離線包,可到 Sealos
官網 http://store.lameleg.com/ 進行下載。
2.3 部署一個多主節點的高可用 Kubernetes 集群
$ sealos init --master 192.168.0.2 \
--master 192.168.0.3 \
--master 192.168.0.4 \
--node 192.168.0.5 \
--user root \
--passwd your-server-password \
--version v1.16.0 \
--pkg-url /root/kube1.16.0.tar.gz
2.4 驗證部署是否成功
$ kubectl get node
NAME STATUS ROLES AGE VERSION
izj6cdqfqw4o4o9tc0q44rz Ready master 2m25s v1.16.0
izj6cdqfqw4o4o9tc0q44sz Ready master 119s v1.16.0
izj6cdqfqw4o4o9tc0q44tz Ready master 63s v1.16.0
izj6cdqfqw4o4o9tc0q44uz Ready <none> 38s v1.16.0
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-5cbcccc885-9n2p8 1/1 Running 0 3m1s
kube-system calico-node-656zn 1/1 Running 0 93s
kube-system calico-node-bv5hn 1/1 Running 0 2m54s
kube-system calico-node-f2vmd 1/1 Running 0 3m1s
kube-system calico-node-tbd5l 1/1 Running 0 118s
kube-system coredns-fb8b8dccf-8bnkv 1/1 Running 0 3m1s
kube-system coredns-fb8b8dccf-spq7r 1/1 Running 0 3m1s
kube-system etcd-izj6cdqfqw4o4o9tc0q44rz 1/1 Running 0 2m25s
kube-system etcd-izj6cdqfqw4o4o9tc0q44sz 1/1 Running 0 2m53s
kube-system etcd-izj6cdqfqw4o4o9tc0q44tz 1/1 Running 0 118s
kube-system kube-apiserver-izj6cdqfqw4o4o9tc0q44rz 1/1 Running 0 2m15s
kube-system kube-apiserver-izj6cdqfqw4o4o9tc0q44sz 1/1 Running 0 2m54s
kube-system kube-apiserver-izj6cdqfqw4o4o9tc0q44tz 1/1 Running 1 47s
kube-system kube-controller-manager-izj6cdqfqw4o4o9tc0q44rz 1/1 Running 1 2m43s
kube-system kube-controller-manager-izj6cdqfqw4o4o9tc0q44sz 1/1 Running 0 2m54s
kube-system kube-controller-manager-izj6cdqfqw4o4o9tc0q44tz 1/1 Running 0 63s
kube-system kube-proxy-b9b9z 1/1 Running 0 2m54s
kube-system kube-proxy-nf66n 1/1 Running 0 3m1s
kube-system kube-proxy-q2bqp 1/1 Running 0 118s
kube-system kube-proxy-s5g2k 1/1 Running 0 93s
kube-system kube-scheduler-izj6cdqfqw4o4o9tc0q44rz 1/1 Running 1 2m43s
kube-system kube-scheduler-izj6cdqfqw4o4o9tc0q44sz 1/1 Running 0 2m54s
kube-system kube-scheduler-izj6cdqfqw4o4o9tc0q44tz 1/1 Running 0 61s
kube-system kube-sealyun-lvscare-izj6cdqfqw4o4o9tc0q44uz 1/1 Running 0 86s
2.5 最簡單粗暴的視頻教程
如果你覺得上面的教程還是不夠直觀,現在就給你一個更簡單粗暴的學習方式。猛擊這里的視頻,開始吧!
2.6 升級 Kubernetes 集群版本
Kubernetes
集群目前處於一個高速迭代期,每個新版本的發布都提供了不少新的特性。升級 Kubernetes
集群版本也就成了家常便飯,Sealos
也為大家提供非常方便的功能來幫助大家快速完成 Kubernetes
集群升級。Kubernetes
集群升級大致需要以下幾個步驟:
-
升級所有節點的
Kubeadm
並導入新的鏡像。 -
升級
Master
節點上的Kubelet
。 -
升級其它
Master
節點。 -
升級
Node
節點。 -
驗證集群狀態。
2.6.1 升級 Kubeadm
這一步主要用於更新 Kubeadm
、Kubectl
、Kubelet
等二進制文件,並導入新版本的鏡像。升級方法很簡單,只需復制離線包到所有節點並執行以下命令。
$ cd kube/shell && sh init.sh
2.6.2 升級 Master 節點上的 Kubelet
升級 Kubelet
還是很簡單的,只需要把新版本的 Kubelet
復制到 /usr/bin
目錄下替換舊版本,然后重啟 Kubelet
服務即可。
$ kubeadm upgrade plan
$ kubeadm upgrade apply v1.16.0
# 重啟 Kubelet
$ systemctl restart kubelet
其中最重要的 kubeadm upgrade apply
命令主要完成以下一些操作。
-
驗證集群是否可升級並執行版本升級策略。
-
確認離線包中相關鏡像是否可用。
-
對控制組件的容器進行升級,失敗就回滾。
-
對
Kube-DNS
和Kube-Proxy
進行升級。 -
創建新的證書文件並備份舊的證書文件。
2.6.3 升級其它 Master 節點
$ kubeadm upgrade apply
2.6.4 升級 Node 節點
升級 Node
節點前,首先要驅逐節點。
$ kubectl drain $NODE --ignore-daemonsets
其次,是更新 Kubelet
的配置文件和升級 Node
節點的 Kubelet
。
$ kubeadm upgrade node config --kubelet-version v1.16.0
# 同樣是替換二進制文件並重啟 Kubelet
$ systemctl restart kubelet
最后,恢復 Node
節點為可調度狀態。
$ kubectl uncordon $NODE
2.6.5 驗證集群是否升級成功
$ kubectl get nodes
如果輸出的節點的版本信息是和升級的版本一致的話,一切就搞定了!
3. 集群清理
如果你需要快速清理已部署的 Kubernetes
集群環境,你可以使用下面的命令快速完成。
$ sealos clean \
--master 192.168.0.2 \
--master 192.168.0.3 \
--master 192.168.0.4 \
--node 192.168.0.5 \
--user root \
--passwd your-server-password
至此,使用 Sealos
快速部署一個生產級別的 Kubernetes
高可用集群的基本方法就介紹完了。如果你對 Sealos
非常的感興趣,你還可以去官網探索更多高級功能喲!
對於在生產環境中快速部署 Kubernetes
高可用集群,你還有哪些更好用高效的方法呢?歡迎大家在留言討論喲!