配置高可用K3s集羣完全攻略

前 言

在本文中,我們將簡要介紹在高可用性(HA)配置中設置K3s的參考架構。這意味着你的K3s集羣可以容忍故障,並保持啓動和運行,爲你的用戶提供流量。你的應用程序也應該針對高可用性進行構建和配置,但這部分內容不在本文的範圍內。

在本教程中,我們將使用CLI工具在DigitalOcean上配置一個HA K3s集羣。我們將使用MySQL進行數據存儲,並使用TCP負載均衡器爲Kubernetes API server提供一個穩定的IP地址。

那麼,爲什麼我們需要高可用?我們可以創建的K3s集羣是通過在一個有公共IP地址的虛擬機上部署一個K3s server。不幸的是,如果該虛擬機崩潰,我們的應用程序將會發生故障。通過添加多個server並配置它們協調工作,可以使得集羣容忍一個或多個節點的故障。這就是所謂的高可用性。

控制平面的高可用性

對於K3s 1.19版本來說,以下兩種方法都可以實現高可用:

  • SQL數據存儲:SQL數據庫可以用於存儲集羣狀態,但SQL數據庫也必須在高可用配置下運行纔有效。
  • 嵌入式etcd:與Kubernetes的傳統配置方式最爲類似,需要使用諸如kops和kubedam等工具

在本文中,我們將瞭解第一種方法,該方法中使用SQL數據庫來存儲狀態。我們之所以採用SQL的原因是單個數據庫可以擴展到支持多個集羣。

API Server的高可用

Kubernetes API server配置爲端口 6443 的 TCP 流量。外部流量(如來自kubectl客戶端的流量)使用KUBECONFIG文件中的IP地址或DNS條目連接到API server。

該配置引入了我們所有server之間的TCP負載均衡器的需求,因爲如果我們使用其中一臺server的IP地址,這臺server崩潰,我們將無法使用kubectl。Agent也是如此,需要連接到某個IP地址和端口6443的server上才能與集羣通信。

在這裏插入圖片描述

在上圖中,運行kubectl的用戶和兩個agent都連接到TCP 負載均衡器。負載均衡器使用私有IP地址列表來平衡三個server之間的流量。如果其中一個server崩潰,它將從IP地址列表中刪除。

Server使用SQL數據存儲來同步集羣的狀態。

前期準備

你也許需要一個DigtalOcean的賬號來進行以下步驟,不過以下大多數內容也可以從其他雲提供商中獲取,此前我們發佈過一篇使用阿里雲進行K3s高可用的教程,歡迎你參考:

  • 3個VM作爲K3s server運行
  • 2個VM作爲K3s agent運行
  • 託管的MySQL服務
  • 託管的TCP 負載均衡器

如果你正在使用沒有託管的TCP負載均衡器的雲服務,可以考慮使用keepalived或kube-vip等工具。這些工具是通過發佈“虛擬IP地址”來實現的,KUBECONFIG文件指向這個地址,而不是單個server。

這些說明需要與Windows上的Git Bash,MacOS Terminal,WSL1或2或Linux Terminal等終端一起運行。

確保您已下載並安裝:

  • DigitalOcean CLI (doctl)
  • Kubernetes CLI (kubectl)
  • K3sup:一個被廣泛使用的開源工具,用於通過SSH安裝K3s

以上3個CLI都可以通過arkade get NAME命令或使用brew install NAME來安裝。

Arkade:https://github.com/alexellis/arkade
brew:https://brew.sh/

如果你使用的是arkade,運行以下命令:

arkade get doctl
arkade get kubectl
arkade get k3sup

你安裝了doctl之後,你需要在DigitalOcean的儀表盤上創建一個帶有讀寫權限的API key,然後運行doctl auth init進行認證。

添加你的SSH key到你的Digital Ocean儀表盤上,然後查找SSH key的ID。當我們使用SSH來安裝K3s時,我們需要使用它。

如果這是你第一次使用SSH key或者如果你想了解如何配置它們,你可以訪問以下鏈接查看教程:
https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/

現在列出你的SSH key並複製以下ID:


 1. doctl compute ssh-key list
 2. ID             Name     FingerPrint
 3. 24824545       work e2:31:91:12:31:ad:c7:20:0b:d2:b1:f2:96:2a:22:da

運行以下命令:

export SSH_KEY='24824545'

詳細步驟

配置我們在教程中所需要的資源最簡單的方式是使用DigitalOcean的儀表盤或CLI(doctl)進行配置。你完成了教程之後,你可能會需要使用類似Terraform的工具來自動化各種步驟。

你可以通過以下鏈接瞭解DigitalOcean的規模和區域選擇:
https://www.digitalocean.com/docs/apis-clis/doctl/reference/compute/droplet/create/

創建節點

創建三臺服務器,內存爲2GB,vCPU爲1:

 1. doctl compute droplet create --image ubuntu-20-04-x64 --size
    s-1vcpu-2gb --region lon1 k3s-server-1 --tag-names k3s,k3s-server
    --ssh-keys $SSH_KEY
 2. doctl compute droplet create --image ubuntu-20-04-x64 --size
    s-1vcpu-2gb --region lon1 k3s-server-2 --tag-names k3s,k3s-server
    --ssh-keys $SSH_KEY
 3. doctl compute droplet create --image ubuntu-20-04-x64 --size
    s-1vcpu-2gb --region lon1 k3s-server-3 --tag-names k3s,k3s-server
    --ssh-keys $SSH_KEY

使用相同的配置創建2個worker:

 1. doctl compute droplet create --image ubuntu-20-04-x64 --size
    s-1vcpu-2gb --region lon1 k3s-agent-1 --tag-names k3s,k3s-agent
    --ssh-keys $SSH_KEY
 2. doctl compute droplet create --image ubuntu-20-04-x64 --size
    s-1vcpu-2gb --region lon1 k3s-agent-2 --tag-names k3s,k3s-agent
    --ssh-keys $SSH_KEY

附帶的標籤會和負載均衡器一起使用,這樣我們就不用指定節點IP了,以後如果需要的話可以增加更多的server。

創建負載均衡器

 1. doctl compute load-balancer create --name k3s-api-server \
 2. --region lon1 --tag-name k3s-server \   --forwarding-rules
 3. entry_protocol:tcp,entry_port:6443,target_protocol:tcp,target_port:6443
    \   --forwarding-rules
 4. entry_protocol:tcp,entry_port:22,target_protocol:tcp,target_port:22
    \   --health-check
 5. protocol:tcp,port:6443,check_interval_seconds:10,response_timeout_seconds:5,healthy_threshold:5,unhealthy_threshold:3

我們需要爲Kubernetes API Server轉發6443端口,22端口給k3sup稍後使用,以獲取集羣的”join token“。

這條規則將接收LB的IP上的傳入流量,並將其轉發到帶有“k3s-server”標籤的虛擬機上。

記下你獲取的ID:

export LB_ID='da247aaa-157d-4758-bad9-3b1516588ac5'

接下來,查找負載均衡器的IP地址:

doctl compute load-balancer get $LB_ID

記下IP欄中的數值:

export LB_IP='157.245.29.149'

配置一個託管的SQL數據庫

doctl databases create k3s-data --region lon1 --engine mysql

以上命令將創建一個版本8的MySQL數據庫。

你還會看到輸出的URI與連接字符串,包括連接所需的密碼。


 1. export
    DATASTORE=mysql://doadmin:z42q6ovclcwjjqwq@tcpk3s-data-do-user-2197152-
 2. 0.a.db.ondigitalocean.com:25060/defaultdb&sslmode=require"

要使用K3s,我們需要修改字符串如下:

export
DATASTORE='mysql://doadmin:z42q6ovclcwjjqwq@tcp(k3s-data-do-user-2197152-0.a.db.ondigitalocean.com:25060)/defaultdb' INSTALL_K3S_VERSION='v1.19.1+k3s1'

我們移除了“?sslmode=require”後綴並在主機名和端口周圍添加了tcp()。

啓動集羣

圖片

讓我們使用k3sup來通過SSH啓動K3s。

在k3sup中最重要的兩個命令是:

  • install:安裝K3s到新server併爲集羣創建join token
  • join:從server上獲取“join token”,然後用它來安裝k3s到agent上。

與其他方法相比,使用k3sup的優勢在於它往往不那麼繁瑣,而且通過直觀的標誌更容易使用。

你可以通過運行:k3sup install --helpk3sup join --help 來找到這些標誌和附加選項。

安裝K3s到server

將channel設置到最新,撰寫本文時最新版本爲1.19

export CHANNEL=latest

在繼續之前,請檢查你的環境變量是否在之前被填充,如果沒有請回溯並填充它們。

 1. echo $DATASTORE
 2. echo $LB_IP
 3. echo $CHANNEL

在下面的命令中,用Public IPv4一欄填寫下面的IP地址:

 1. doctl compute droplet ls --tag-name k3s
 2. export SERVER1=134.209.16.225
 3. export SERVER2=167.99.198.45
 4. export SERVER3=157.245.39.44
 5. export AGENT1=161.35.32.107
 6. export AGENT2=161.35.36.40

既然你已經填充了環境變量,請運行以下命令:

 k3sup install --user root --ip $SERVER1 \
 2. --k3s-channel $CHANNEL \
 3. --print-command \
 4. --datastore='${DATASTORE}' \
 5. --tls-san $LB_IP
 6. List item
 7. k3sup install --user root --ip $SERVER2 \
    --k3s-channel $CHANNEL \
 8. --print-command \
 9. --datastore='${DATASTORE}' \
 10. --tls-san $LB_IP
 11. k3sup install --user root --ip $SERVER3 \
 12. List item
 13. --k3s-channel $CHANNEL \
 14. List item
 15. --print-command \
 16. --datastore='${DATASTORE}' \
 17. --tls-san $LB_IP
 18. k3sup join --user root --server-ip $LB_IP --ip $AGENT1 \
 19. List item
 20. --k3s-channel $CHANNEL \
 21. --print-command
 22. List item
 23. k3sup join --user root --server-ip $LB_IP --ip $AGENT2 \
 24. List item
 25. --k3s-channel $CHANNEL \
 26. --print-command

檢查節點是否加入

1. export KUBECONFIG=`pwd`/kubeconfig
 2. List item
 3. NAME STATUS ROLES AGE VERSION
 4. k3s-server-2   Ready    master    18m    v1.19.3+k3s1
 5. k3s-server-3   Ready    master    18m    v1.19.3+k3s1
 6. k3s-agent-1    Ready    <none>    2m39s  v1.19.3+k3s1
 7. k3s-server-1   Ready    master    23m    v1.19.1+k3s1
 8. k3s-agent-2    Ready    <none>    2m36s  v1.19.3+k3s1

打開KUBECONFIG文件,找到IP地址,應該是負載均衡器的地址。

片刻之後,你可以在DigitalOcean的儀表盤上看到負載均衡器的狀態。

圖片

模擬故障

要模擬故障,需要在一個或多個k3s server上停止K3s服務,然後運行kubectl get nodes命令:

 1. ssh root@SERVER1 'systemctl stop k3s'
 2. ssh root@SERVER2 'systemctl stop k3s'

此時,第三個server將會接管。

kubectl get nodes

然後在其他兩個server上重啓服務:

 1. ssh root@SERVER1 'systemctl start k3s'
 2. ssh root@SERVER2 'systemctl start k3s'

如果你還想了解更多關於Kubernetes如何處理節點中斷的信息,請查看以下鏈接:
https://kubernetes.io/docs/concepts/workloads/pods/disruptions/

此時,你可以使用集羣來部署一個應用程序,或者繼續清理你配置的資源,這樣你就不會因爲任何額外的使用而被收取費用。

清理

刪除droplets

doctl compute droplet rm --tag-name k3s

對於負載均衡器和數據庫,你需要獲取ID,然後使用刪除命令。

 1. doctl compute load-balancer list/delete
 2. doctl databases list/delete

總 結

我們現在已經配置了一個容錯、高可用性的K3s集羣,併爲用戶提供了一個TCP負載均衡器,這樣即使其中一臺服務器宕機或崩潰,用戶也可以訪問kubectl。使用 "tag "也意味着我們可以添加更多的服務器,而不用擔心必須手動更新負載平衡器的IP列表。

我們在這裏使用的工具和技術也可以應用於其他支持託管數據庫和託管負載均衡器的雲平臺,如AWS、谷歌雲和Azure。

正如你可能已經從我們所經歷的步驟中所注意到的那樣,高可用性是一個需要花費一些時間和思考才能夠進行正確配置。如果你打算創建許多HA K3s集羣,那麼使用Terraform自動化步驟可能會有好處。

你也可以使用k3sup使用嵌入式etcd,而不是託管數據庫來配置HA K3s集羣。這降低了成本,但增加了服務器的負載。

如果你想進一步瞭解K3s,歡迎查看以下文檔:
https://docs.rancher.cn/k3s/

你也可以從GitHub上的倉庫中找到更多關於k3sup如何工作的信息,包括使用etcd進行HA的替代方法:
https://k3sup.dev/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章