iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
Kubernetes

從看得到到看得懂:30 天在自架 K8s 上實踐可觀測性與告警系列 第 5

Day 5:用 kind 在筆電上開一個能重現問題的 K8s 叢集

  • 分享至 

  • xImage
  •  

前面四天的觀念講完了,今天正式開始動手。

這篇的目標其實很小,就是把一個叢集開起來,然後說明為什麼是這樣開的。但是「為什麼」的部分比指令重要,網路上教你打 kind create cluster 的文章有幾百篇,我想寫的是那些設定值背後的取捨,像是為什麼要多開兩個節點、為什麼這個系列從頭到尾都用 port-forward。

為什麼是 kind

昨天列過理由了,這裡補一個比較實際的:kind 開出來的叢集,本體就是幾個 Docker 容器。

這代表我們可以直接用 docker ps 看到自己的「節點」,也代表砍掉重建只要幾十秒。而這 30 天我會砍掉重建非常多次,使用 kind 在這方面可以方便許多。

先把工具裝起來

# macOS
brew install kind kubectl helm
# Windows,用 PowerShell,Win10 / Win11 內建 winget
winget install Kubernetes.kind
winget install Kubernetes.kubectl
winget install Helm.Helm

Windows 的話要先把 Docker Desktop 裝好、而且 WSL2 後端要開著,kind 是靠它才跑得起來的。

裝完之後確認版本,然後把版本抄進自己的環境筆記:

kind version
kubectl version --client
docker version --format '{{.Server.Version}}'

以下是我撰寫文章時所採用的版本,這 30 天都會用這組版本:

工具 版本
kind v0.33.0(darwin/arm64)
Kubernetes(節點映像檔) kindest/node:v1.37.0
kubectl v1.37.0(Kustomize v5.8.1)
Helm v4.2.4
Docker 28.4.0

用設定檔描述我們要的叢集

最簡單的做法是直接下 kind create cluster ,會得到一個單節點的叢集。我這裡要設定不只一個節點,所以自己寫一個設定檔,也方便日後管理。

在專案根目錄新增一個檔案,取名 kind-config.yaml,檔名其實隨便取都可以,等一下用 --config 指定它就好:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: obs
nodes:
  - role: control-plane
  - role: worker
  - role: worker

一行一行解釋這個檔案:

這一行 意思
kind: Cluster 這裡的 kind 不是工具名稱,是「資源類型」的意思,我們要描述的東西是一個 Cluster。剛好跟工具同名,很容易誤會
apiVersion 這份設定檔是用哪個格式版本寫的,v1alpha4 是目前 kind 的設定檔格式
name: obs 叢集的名字。這個名字後面會一直用到,kubectl 的連線設定會叫 kind-obs,明天載入映像檔的時候要打 --name obs。取了就不要再改
nodes 底下列出要開幾個節點、每個是什麼角色
role: control-plane 控制平面節點,負責排程和維護整個叢集的狀態,後面幾天會拆解裡面到底跑了哪些東西
role: worker 兩個 工作節點,我們部署的 Pod 會被排到這裡

為什麼要開三個節點

單節點也能跑,但是我刻意多開兩個 worker,理由有三個:

  1. Pod 會被排到不同節點上。 之後看 trace 或 log 的時候,「跨節點」這件事是真的,不是假裝的
  2. node-exporter 會有三份。 後續講 USE 方法論的時候,可以真的去比較節點之間的差異
  3. 可以模擬節點層級的故障,例如把某一個 worker 的容器停掉,看叢集怎麼反應

代價就是記憶體。三個節點的 kind 叢集本身大概吃 1.5 到 2 GB,之後裝完整套觀測 stack 還會再加 5 到 6 GB。如果你的機器只有 8 GB,把 worker 減成一個,後面的內容都還是跑得動。

把叢集開起來

kind create cluster --config kind-config.yaml
kubectl cluster-info --context kind-obs
kubectl get nodes -o wide

第一次跑會花比較久,因為要下載節點的映像檔,之後重建就快很多了。

https://ithelp.ithome.com.tw/upload/images/20260905/20180570ArAagk7kBp.png

三個節點都是 Ready,obs-control-planeobs-workerobs-worker2,名字前面的 obs 就是設定檔裡取的叢集名字。

下面那半是 docker ps,可以看到這三個節點在 Docker 眼裡就是三個容器,映像檔都是 kindest/node:v1.37.0。開頭說「kind 的叢集本體就是幾個 Docker 容器」,指的就是這件事。

叢集開起來之後,kubectl 自己跟我說版本不對

上面那張版本表其實不是我一開始的狀態。叢集開起來之後我又跑了一次 kubectl version,這次沒有加 --client,結果多了一行警告:

Client Version: v1.34.1
Kustomize Version: v5.7.1
Server Version: v1.37.0
Warning: version difference between client (1.34) and server (1.37) exceeds the supported minor version skew of +/-1

我的 kubectl 是 v1.34.1,但是 kind 開出來的叢集是 v1.37.0,差了三個版號。Kubernetes 官方只保證 kubectl 跟 API server 相差一個 minor 版本以內,超過就不保證,可能哪天某個指令就怪怪的。

原因是我的 kubectl 根本不是自己裝的。macOS 上只要裝了 Docker Desktop,它會附一份 kubectl 丟在 /usr/local/bin,版本跟著 Docker Desktop 走,跟我們用 kind 開的叢集完全沒關係。所以我另外裝了一份:

brew install kubernetes-cli

Homebrew 裝在 /opt/homebrew/bin,這個路徑在 PATH 裡面排在 /usr/local/bin 前面,所以裝完就會用到新的那份,Docker Desktop 那份還在但被蓋掉了。再跑一次 kubectl version,警告就消失了。

沒有 LoadBalancer,所以這個系列一律用 port-forward

在 kind 裡面建立 type: LoadBalancer 的 Service,EXTERNAL-IP 會永遠停在 <pending>,因為沒有雲端供應商幫我們生一個 IP 出來。這件事等我們裝完 Grafana、想打開它的畫面時就會第一次遇到。

所以現在先把做法定下來,這個系列一律用 port-forward

kubectl port-forward svc/grafana 3000:80

這行拆開來看是這樣:

  • port-forward 是叫 kubectl 在我們自己電腦上開一個埠,然後把送到這個埠的流量,透過 Kubernetes 的 API server 轉進叢集裡面。它不需要 LoadBalancer、也不需要 ingress,因為它根本不是從叢集外面連進去的,而是借用 kubectl 本來就有的那條連線。
  • svc/grafana 是要轉去哪裡,svc 就是 Service 的縮寫,後面接名字。這裡也可以寫成 pod/某個poddeploy/某個deployment
  • 3000:80 是兩個埠,左邊是我們自己電腦的埠,右邊是叢集裡面那個 Service 的埠,順序很容易寫反。所以整行的意思就是:瀏覽器打開 localhost:3000,實際上連到的是叢集裡 grafana 這個 Service 的 80 埠。

有兩件事需要特別注意。第一,這個指令要一直開著,按了 Ctrl+C 連線就斷了,所以通常會另外開一個終端機視窗放它。第二,它預設只綁在 127.0.0.1,也就是只有自己這台電腦連得到,同一個區網的其他人是連不進來的,在這裡只是用於練習與示範所以沒有關係。

因為我的主軸是可觀測性而不是流量入口,所以這裡不裝 ingress、也不裝 MetalLB。

砍掉重來

kind delete cluster --name obs

這行指令這 30 天會用非常多次。遇到無法排除的錯誤,可以直接砍掉叢集從頭開始,這是本機叢集最方便的地方,也是最後幾天要講的 IaC 的好處:如果重建只要幾十秒,我們就不會捨不得砍。

小結

今天做完的事情:

  • 裝好 kind、kubectl、helm,版本記進筆記
  • 用設定檔開了一個三節點的叢集
  • 知道 kind 沒有 LoadBalancer,這個系列一律用 port-forward 開畫面

明天 Day 6 要部署示範服務,並且故意在裡面埋三個故障。這三個故障是整個系列的主線,後面會分別用 logs、traces 和告警把它們挖出來。


上一篇
Day 4:這 30 天要裝的工具
系列文
從看得到到看得懂:30 天在自架 K8s 上實踐可觀測性與告警5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言