這應該是最適合國內使用者的K3s HA方案
前 言
在面向生產環境的實踐中,高可用是我們無法避免的問題,K3s本身也歷經多個版本的迭代,HA方案也進行了不斷優化,形成了目前的比較穩定的HA方案。
目前官方提供兩種HA方案:
-
嵌入式DB的高可用(實驗)
-
使用外部資料庫實現高可用
嵌入式DB的高可用目前還是實驗性的,本文不過多介紹,請參考:
https://rancher.com/docs/k3s/latest/en/installation/ha-embedded/
使用外部資料庫實現高可用需要搭建一個高可用的外接資料庫,目前,K3s支援SQLite/etcd/MySQL/PostgreSQL/DQLite等datastore,不同的datastore面向不同的使用場景。
目前國內使用最多的公有云環境應該就是阿里雲了,我們可以在阿里雲上利用虛擬機器搭建K3s HA,然後對接到阿里雲的RDS,這樣可以免去單獨維護一套資料庫的麻煩。本文選擇大家熟知的MySQL來做HA的實踐,PostgreSQL與MySQL類似,本文不再贅述。
架構圖
如上圖,終端使用者訪問SLB,SLB將流量分別轉發到後端的兩臺K3s master HA。兩臺 K3s master 節點連線同一個RDS 建立的外接資料庫。
建立阿里雲實例
K3s 需要至少兩臺例項去組成HA,所以在阿里雲上建立至少兩臺例項用作演示:
配置阿里雲RDS
1、建立RDS例項,例項型別要選擇MySQL 5.7
,該版本是K3s官方支援的版本,其他引數根據自身需求設定即可。
2、設定白名單,白名單的內容設定為你的K3s 例項的內網IP即可。設定成功後,我們將得到一個內網地址用作資料庫連線:rm-2ze64ke7q33bkq3yt.mysql.rds.aliyuncs.com
3、建立賬號,使用普通賬號(ksd)
即可
4、建立資料庫,設定資料庫名稱(k3s),授權賬號(ksd)
之前在使用docker啟動的mysql時,不需要提前建立資料庫,因為啟動k3s的時候會自動建立。但在阿里雲RDS上,必須先在UI上建立K3s所需的資料庫。
5、修改資料庫引數
我們需要把資料引數innodb_large_prefix
設定為ON
,否則啟動K3s的時候會報錯:
Jul 29 20:08:06 iZ2zed0v8rqape974mz8suZ systemd[1]: k3s.service: Service hold-off time over, scheduling restart. Jul 29 20:08:06 iZ2zed0v8rqape974mz8suZ systemd[1]: k3s.service: Scheduled restart job, restart counter is at 11. Jul 29 20:08:06 iZ2zed0v8rqape974mz8suZ systemd[1]: Stopped Lightweight Kubernetes. Jul 29 20:08:06 iZ2zed0v8rqape974mz8suZ systemd[1]: Starting Lightweight Kubernetes... Jul 29 20:08:07 iZ2zed0v8rqape974mz8suZ k3s[24934]: time="2020-07-29T20:08:07.145963348+08:00" level=info msg="Starting k3s v1.18.6+k3s1 (6f56fa1d)" Jul 29 20:08:07 iZ2zed0v8rqape974mz8suZ k3s[24934]: time="2020-07-29T20:08:07.159363656+08:00" level=fatal msg="starting kubernetes: preparing server: creating storage endpoint: building kine: Error 1071: Specified key was too long; max key length is 767 bytes" Jul 29 20:08:07 iZ2zed0v8rqape974mz8suZ systemd[1]: k3s.service: Main process exited, code=exited, status=1/FAILURE Jul 29 20:08:07 iZ2zed0v8rqape974mz8suZ systemd[1]: k3s.service: Failed with result 'exit-code'. Jul 29 20:08:07 iZ2zed0v8rqape974mz8suZ systemd[1]: Failed to start Lightweight Kubernetes.
將innodb_large_prefix
修改為ON
之後,點選右上角【提交引數】即可完成修改。
以上步驟操作成功後,K3s要求的外接資料庫就已經準備完成,下面我們來啟動K3s HA。
實現 K3s HA
在k3s-master-1
和k3s-master-2
上執行相同的命令:
curl -sfL https://docs.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
K3S_DATASTORE_ENDPOINT='mysql://ksd:your_password@tcp(rm-2ze64ke7q33bkq3yt.mysql.rds.aliyuncs.com:3306)/k3s' \
sh -s - server
稍等片刻,一個K3s HA的環境就已經啟動完成了:
如果在阿里雲上pull K3s的映象比較慢的話,可以配置mirror或者 從 http://mirror.cnrancher.com 下載對應版本的離線包,然後參考下面連結匯入映象:https://rancher.com/docs/k3s/latest/en/installation/airgap/#prepare-the-images-directory-and-k3s-binary
root@k3s-master-2:~# kubectl get pods -A -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system local-path-provisioner-6d59f47c7-tshfx 1/1 Running 0 16m 10.42.0.5 k3s-master-1 <none> <none>
kube-system metrics-server-7566d596c8-mrc94 1/1 Running 0 16m 10.42.0.2 k3s-master-1 <none> <none>
kube-system coredns-8655855d6-sxn7v 1/1 Running 0 16m 10.42.0.4 k3s-master-1 <none> <none>
kube-system helm-install-traefik-cmmsr 0/1 Completed 2 16m 10.42.0.3 k3s-master-1 <none> <none>
kube-system svclb-traefik-z6vlb 2/2 Running 0 11m 10.42.0.6 k3s-master-1 <none> <none>
kube-system svclb-traefik-f89x6 2/2 Running 0 11m 10.42.1.2 k3s-master-2 <none> <none>
kube-system traefik-758cd5fc85-chnbc 1/1 Running 0 11m 10.42.1.3 k3s-master-2 <none> <none>
root@k3s-master-2:~#
root@k3s-master-2:~# kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k3s-master-1 Ready master 16m v1.18.6+k3s1 172.17.207.15 <none> Ubuntu 18.04.4 LTS 4.15.0-106-generic containerd://1.3.3-k3s2
k3s-master-2 Ready master 16m v1.18.6+k3s1 172.17.207.16 <none> Ubuntu 18.04.4 LTS 4.15.0-106-generic containerd://1.3.3-k3s2
通過阿里雲SLB提供統一訪問入口
現在我們已經擁有了高可用的MySQL和K3s,但現在還缺一個為多個K3s server提供一個統一的訪問入口,這可以使用以下方式實現:
-
L4層負載均衡器
-
Round-robin DNS
-
VIP或者彈性IP
所以,我們可以直接使用阿里雲的SLB做L4層負載均衡,將6443埠轉發到後端的兩臺K3s master。
接下來,我們可以把k3s master節點的/etc/rancher/k3s/k3s.yaml
複製到本地的~/.kube/config
目錄,然後將server地址修改為server: https://39.106.185.201:6443
(SLB的公網IP)
然後可以通過kubectl get nodes
測試下是否可以通過SLB將流量轉發到K3s master:
ksd@Hailong-MacBook-Pro ~ kubectl get nodes
Unable to connect to the server: x509: certificate is valid for 10.43.0.1, 127.0.0.1, 172.17.207.15, 172.17.207.16, not 39.106.185.201
這個錯誤是因為K3s mster啟動時自動建立的證書不信任39.106.185.201
這個SLB的公網IP,為了解決這個問題,可以更新K3s master,新增引數--tls-san 39.106.185.201
:
curl -sfL https://docs.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
K3S_DATASTORE_ENDPOINT='mysql://ksd:your_password@tcp(rm-2ze64ke7q33bkq3yt.mysql.rds.aliyuncs.com:3306)/k3s' \
sh -s - server \
--tls-san 39.106.185.201
最後,再回到本地機器上,再次執行kubectl get nodes
,不出意外的話,就應該可以獲取到節點資訊了。
ksd@Hailong-MacBook-Pro ~ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-master-2 Ready master 65m v1.18.6+k3s1
k3s-master-1 Ready master 65m v1.18.6+k3s1
後 記
本文只介紹瞭如何藉助阿里雲的SLB、RDS來實現K3s的HA,其他公有云的操作基本大同小異,雖然沒做過詳細的測試,但理論上應該都是支援的。如果是非公有云環境,可以根據自身的需求選擇適合的datastore以及對應的HA方式。