你是否曾經想嘗試使用K3s的高可用模式?但是苦於沒有3個“備用節點”,或者沒有設置相同數量的虛擬機所需的時間?那么k3d這個方案也許你十分需要噢!
如果你對k3d尚不了解,它的名字或許可以給你一個了解它的切入口:K3s in Docker。k3d是一個輕量級封裝程序,用於在Docker中運行k3s。借助k3d,可以輕松在Docker內創建單節點或多節點的k3s集群,用於Kubernetes上的本地開發。
K3d允許你在短時間內啟動k3s集群。此外,你可以快速學會其少量但十分有用的命令。K3d運行在Docker內,這意味着你可以擴展或減少節點而不需要進行多余的設置。在本文中,我們將介紹如何使用k3d設置單節點K3s集群以及如何使用k3d在高可用模式下設置k3s。
本文的兩個主要目的是介紹k3d作為部署K3s集群的工具,以及展示K3s高可用性如何抵抗“節點退化(nodes degradation)”。而且,我們還將了解k3s默認在集群中部署了哪些組件。
前期准備
在操作系統(Linux、MacOS、Windows)方面,大家都有自己的偏好。所以在我們檢查用於本篇文章的設置之前,僅有兩個必要的要求:Docker和Linux shell。
如果你使用的系統是MacOS或者Windows,Docker Desktop是Dcoker的首選解決方案。對於Linux來說,你可以獲取Docker engine以及CLIs,詳細信息如下:
https://www.docker.com/products/docker-desktop
Linux shell、MacOS以及Linux都會有所涉及。對於Windows系統而言,最簡單快捷的解決方案是WSL2,我們也會在demo中用到它。
以下是我們將會用到的設置:
-
OS:Windows 10 version 2004(build:19041)
-
OS 組件:虛擬化機器平台以及Linux的Windows子系統
-
安裝步驟:
-
WLS2發行版:Ubuntu
-
Windows商店地址:
-
https://www.microsoft.com/en-us/p/ubuntu/9nblggh4msv6#activetab=pivot:overviewtab
-
【可選】使用的控制台:Windows Terminal
-
Windows商店地址:
-
https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701
Step1:從安裝開始
訪問下方鏈接即可了解如何安裝k3d:
在本文中,我們將以curl的方式安裝。
請注意:直接從URL運行腳本存在很嚴重的安全問題。所以在運行任意腳本之前,確保源是項目的網站或git在線repository。
以下是安裝步驟:
訪問:https://k3d.io/#installation
復制“curl“安裝命令並且在你的terminal內運行它:
curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
請注意:該截圖顯示了兩個命令:
-
k3d version:提供已安裝的k3d版本
-
k3d –help:列出可用於k3d的命令
現在k3d已經安裝完成並且准備開始使用。
Step2:從單節點集群開始
在我們創建一個HA集群之前,讓我們從單節點集群開始以理解命令(“grammar”)並且查看默認情況下k3d部署了什么。
首先,語法。在V3,k3d在命令的使用方式上做了很大的改變。我們不深入研究以前的命令是怎么做的,我們將使用V3的語法。
K3s遵循“名詞+動詞”的句法。首先指定我們要使用的東西(集群或節點),然后指定我們要應用的操作(create、delete、start、stop)。
創建一個單節點集群
我們將借助k3d使用默認值創建一個單節點集群:
**k3d cluster create
**
請注意:k3d cluster create命令的輸出建議運行另一條命令來檢查集群是否在運行並且可以訪問:kubectl cluster-info
現在集群已經啟動並且在運行啦!
窺視內部結構
我們還可以從不同的角度看看到底部署了什么。
讓我們從頭開始,看看K3s集群里面有什么(pods、服務、部署等):
kubectl get all --all-namespaces
我們可以看到,除了Kubernetes服務外,當我們使用默認值時,K3s還部署了DNS、metrics和ingress(traefik)服務。
現在讓我們從不同的視角查看節點。
首先,我們從集群的視角檢查它:
kubectl get nodes --output wide
如我們所料,僅看到了一個節點。現在讓我們從k3d的視角查看:
k3d node list
現在我們有兩個節點。這里有一個比較智能的實現是,當集群運行在它的節點k3d-k3s-default-server-0上時,有另一個“節點”作為負載均衡器。雖然這可能對單節點集群沒有太大作用,但在我們的HA集群中,它將為我們節省很多精力。
最后,我們從Docker看到兩個節點:docker ps
清理資源
我們的單節點集群可以幫助我們理解k3d的機制和命令。現在,我們需要在部署HA集群之前清理資源:k3d cluster delete
請注意:出於demo的目的,我們在上方截圖中添加了以下命令:
-
k3d cluster list:列出活躍的k3d集群
-
kubectl cluster-info:檢查集群的連接
-
docker ps:檢查活躍的容器
現在,我們已經使用k3d創建、檢查並刪除了一個單節點集群。下一步,我們開始嘗試HA。
Step3:歡迎來到HA的世界
在我們開啟命令行之前,讓我們對我們即將要部署的東西有一個基本的了解並且了解一些其他額外的要求。
首先,Kubernetes HA有兩個可能的設置:嵌入式或外部數據庫。我們將采用嵌入式數據庫的設置。
其次,K3s有兩種不同的技術用於嵌入式數據庫的HA:一種是基於dqlite(K3s v1.18),另一種是基於etcd(K3s v1.19+)。
這意味着etcd是當前K3s穩定版中的默認版本,也是本文將使用的版本。Dqlite已經棄用。
在撰寫本文時,k3d默認使用k3s v1.18.9-k3s1的版本。你可以通過k3d version來檢查:
那么這是否意味着我們需要重新安裝支持K3s v1.19的k3d嗎?當然不需要!
我們可以使用當前已經安裝的k3d版本並且依舊支持K3s v1.19,因為:
-
k3d可以讓我們指定一個特定的k3s docker鏡像來使用
-
所有的k3s版本都是以容器鏡像的形式發布的
基於以上原因,我們可以假設一個K3s v1.19作為一個容器鏡像存儲在Docker Hub中:
https://hub.docker.com/r/rancher/k3s/tags?page=1&name=v1.19
現在,讓我們用k3d創建第一個K3s HA集群。
三個控制平面
根據Kubernetes HA的最佳實踐,我們應該使用至少3個控制平面來創建一個HA集群。
在k3d中我們使用以下命令即可:
k3d cluster create --servers 3 --image rancher/k3s:v1.19.3-k3s2
了解命令:
基礎命令:k3d cluster create
選項:
-
server 3:請求用角色服務器創建三個節點。
-
image rancher/k3s:v1.19.3-k3s2:指定要使用的K3S鏡像
現在我們可以從不同的角度檢查我們已經創建的集群
kubectl get nodes --output wide
如你所見,我們從不同方面進行檢查以確保我們的節點正常運行。
如果我們看到組件已經部署完成,那么我們的daemonset現在有3個副本,而不是1個:
kubectl get all --all-namespaces
最后一項檢查是看pods在哪個節點上運行:
kubectl get podes --all-namespaces --output wide
現在我們有了HA集群的基礎。讓我們添加額外的控制平面節點,並故意對其進行破壞,看看集群的表現。
擴展集群
由於k3d以及我們的集群運行在頂部容器的事實,我們可以快速模擬在HA集群中增加另一個控制平面節點:
k3d node create extraCPnode --role=server --image=rancher/k3s:v1.19.3-k3s2
了解命令:
基礎命令:k3d node create
選項:
extraCPnode:k3d用於創建最終節點名稱的基本名稱。
role=server:設置節點的角色為控制平面。
image rancher/k3s:v1.19.3-k3s2:指定要使用的K3s鏡像。
從這里可以看出,我們從不同的角度進行檢查以確保新的控制平面節點正常運行。
增加了這個額外的節點之后,我們就可以進行最后的測試了:降低node0!
HA:重型裝甲防撞車
node0通常是我們的KUBECONFIG所指的節點(用IP或主機名表示),因此我們的kubectl應用程序試圖連接到它來運行不同的命令。
由於我們正在使用容器,所以“破壞“一個節點的最好方法是直接停止容器。
docker stop k3d-k3s-default-server-0
請注意:Docker和k3d命令會立即顯示狀態變化。然而,Kubernetes集群需要很短的時間才能看到狀態變化為NotReady。
此外,我們的集群仍然使用Kubectl響應我們的命令。
現在是時候再次參考負載均衡器k3d所用的時間,以及它對於讓我們繼續訪問K3s集群的重要性。
從外部連接的角度來看,雖然負載均衡器內部切換到了下一個可用節點,但我們仍使用相同的IP/主機。這種抽象為我們節省了很多經理,並且這是k3d最有用的功能之一。
讓我們看一下集群的狀態:
kubectl get all --all-namespaces
一切看起來正常。如果我們再具體看一下Pods,那么我們會發現,K3s通過在其他節點上重新創建運行在故障節點上的pods來自動自愈:
kubectl get pods --all-namespaces --output wide
最終,為了展示HA的強大以及k3s如何管理它,讓我們重啟node0,然后我們會看到它被重新納入集群,好像什么都沒有發生。
docker start k3d-k3s-default-server-0
我們的集群是穩定的並且所有節點都再次正常運行。
再次清理資源
現在我們可以刪除本地HA集群,因為它已經完成了它的使命。此外,我們知道我們可以輕松創建一個新的集群。
使用以下命令即可清理我們的HA集群:
k3d cluster delete
總 結
雖然我們在本地、容器中創建了單節點和HA集群,我們仍然可以看到K3s在新的etcd嵌入式DB下的表現,如果我們在裸機或虛擬機上部署K3s,其作用方式相同。
也就是說,k3d在管理方面幫助很大。它默認創建了一個負載均衡器,允許永久連接到K3s集群,同時抽象了所有的任務。如果它部署在容器外,我們需要手動完成這一步驟。
在本文中,我們已經看到了使用k3d設置高可用性K3s集群是多么容易。如果你尚未嘗試,強烈推薦你根據本教程進行實踐,它們都是開源且易用的。