內容概述
kind(Kubernetes IN Docker)是一個開源(Apache-2.0 授權)的工具,用 Docker 容器當作 Kubernetes 的「節點」,在一台電腦上就能建立完整的 Kubernetes 叢集。官方說明 kind 原本是為了測試 Kubernetes 本身而設計,也可以用在本機開發與 CI。
對個人開發者和中小企業的平台團隊來說,它解決的是「想練習或驗證 Kubernetes,卻不想先付雲端叢集費用」的問題:軟體免費,叢集約 30 秒建好,用完一個指令刪掉。本文以 kind v0.33.0、Kubernetes v1.37.0 實際操作,除了基本安裝,也把預設設定在資安上的盲點、網路模式踩到的坑,以及 ingress-nginx 退役後怎麼測 Ingress 與 Gateway API 都記錄下來。
讀完本文,您可以:
- 在自己的電腦建出 kind 叢集:下載並驗證執行檔、用設定檔建立固定版本的叢集,約 30 秒完成。
- 避開預設值的資安盲點:讓連接埠只綁在本機、妥善保管 kubeconfig,並知道哪些元件會開出無驗證的介面。
- 判斷 kind 適不適合您的用途:知道它能測什麼、不該拿來做什麼,以及碰到 NodePort 不通等問題時怎麼排查。
成本與風險摘要
先看這裡:
動手前先了解要花多少資源、風險在哪裡:
- 適用對象與規模:想學 Kubernetes 的個人、需要在本機驗證 YAML/Helm chart 的開發者與平台工程師;只適合用完即丟的測試叢集,正式環境請改用雲端託管或自建 Kubernetes。
- 成本(硬體、訂閱、授權):Apache-2.0,免費、沒有付費版本;單節點約 0.5~0.6 GB 記憶體、三節點約 0.9 GB,每個節點映像約 1.3 GB 磁碟;不需要訂閱。
- 維護時間:建立約 30 秒、刪除不到 1 秒;定期更新 kind 並驗證 SHA256,換 Kubernetes 版本要重建叢集並重新套用設定。
- 資安注意事項:extraPortMappings 寫
listenAddress: "127.0.0.1"(預設 0.0.0.0);kubeconfig 權限 600 不外流;節點是特權容器且沒有記憶體上限;cloud-provider-kind 的 envoy 管理介面開在 0.0.0.0 且無驗證,用完就停;kind export logs含主機名稱與內部 IP。 - 常見誤區:以為預設 iptables 模式到處都能用(精簡核心可能整個不通);以為改節點映像就能升級(其實是重建、資料清空);主機殘留的舊防火牆規則讓 Pod 拉不到映像,卻誤以為是 kind 的問題。
- 不建議使用的情況:正式服務、需要保存資料、需要讓其他電腦連入、有公開 IP 的共用伺服器;這些情況請改用正式的 Kubernetes 叢集。
- 測試日期與版本號:測試日期:2026-10-29;kind v0.33.0(測試環境:Debian 13、Linux kernel 6.12.x、8 vCPU/16 GB、Docker 29.9.2、kindest/node v1.37.0 與 v1.36.4、kubectl v1.37.2、cloud-provider-kind v0.12.0、Headlamp chart 0.46.0、helm v4.3.1;kube-proxy nftables 模式)。
第一部分:適不適合您
這一部分說明 kind 能做什麼、適合多大規模,以及哪些情況不該用;已經確定要用的讀者可以直接跳到第二部分。
應用場景
kind 適合「需要一個真的 Kubernetes,但不需要它一直存在」的情境,例如:
- 學習與教學:照著官方文件或書本練習 Deployment、Service、Ingress,做錯就刪掉重建。
- 本機開發驗證:在本機建置映像,載入叢集測試,不必經過網路或映像檔倉庫。
- 版本相容性測試:同一份 YAML 在 v1.36 和 v1.37 各建一次叢集試跑。
- 網路與流量規則實驗:測試 Ingress、Gateway API 的路徑、標頭與權重分流規則。
- CI 測試:官方說明 kind 也可以用在 CI;本文沒有實測 CI 流程。
技術特點
- 容器即節點:每個節點是一個 Docker 容器,裡面跑 kubelet、containerd 和 Kubernetes 元件。
- 多節點:用設定檔宣告 control-plane 與 worker 的數量,實測 1 個 control-plane 加 2 個 worker 約 26~28 秒建好。
- 指定 Kubernetes 版本:每個 kind 版本會公布一組預先建好的節點映像(v0.33.0 提供 v1.37.0、v1.36.4、v1.35.8、v1.34.11 等),建議用
@sha256:固定版本(官方 Quick Start 原文:「Please use the sha256 shasum」)。 - 本機映像載入:
kind load docker-image把本機建置好的映像直接放進節點,不用推到網路上。 - kube-proxy 模式可選:可設定 iptables(預設)、nftables(Kubernetes v1.31 以上)或 ipvs,也可以設成 none 改用其他方案(見第二部分的「kube-proxy 三種模式的差別」)。
- 沒有外掛系統:kind 不像 kubectl 有外掛機制(官方 RFC #1986 已關閉)。LoadBalancer、Ingress 這類功能由同一個 SIG 維護的獨立程式 cloud-provider-kind 提供。
適用規模與不適合的情況
kind 是「用完即丟」的測試叢集,不是正式環境。適合的用途見上方的應用場景;以下說明它需要多少資源,以及哪些情況不該用。
規模與維運成本:
- 硬體:單節點叢集約 0.5~0.6 GB 記憶體,三節點約 0.9 GB;每個節點映像約 1.3 GB 磁碟。8 vCPU/16 GB 的電腦跑三節點仍有餘裕(實測)。
- 時間:建立約 30 秒、刪除不到 1 秒;換 Kubernetes 版本等於重建。
- 維護工作:定期更新 kind 執行檔並驗證 SHA256;用完刪叢集、停 cloud-provider-kind;偶爾清掉不用的節點映像。授權與費用見上方「成本與風險摘要」。
不適合的情況:
- 正式環境、要給同事或客戶長期使用、要保存資料:沒有原地升級,重建就清空;節點是特權容器。請改用雲端託管的 Kubernetes 或自建叢集。
- 需要從其他電腦連進來的服務:kind 的網路設計是給本機用,硬把連接埠開到 0.0.0.0 會把測試叢集暴露出去。
- 共用或對外的伺服器:cloud-provider-kind 會開出無驗證的 envoy 管理介面,特權節點也會放大風險。
- 想測 eBPF 網路或特定核心功能:節點共用主機核心,主機缺什麼模組,叢集就缺什麼(本文的 iptables 與 Cilium 就是例子)。

第二部分:動手實測
這一部分是實際安裝與操作的完整紀錄,每個安裝步驟都附上實測輸出,讓您對照自己的結果;標示「進階」的段落預設收合,需要時再展開。
測試環境
| 項目 | 版本/規格 |
|---|---|
| 主機 | Debian 13,Linux kernel 6.12.x,8 vCPU/16 GB 記憶體 |
| 容器執行環境 | Docker 29.9.2 |
| kind | v0.33.0(2026-08-27 發佈,台北時間;SHA256 已驗證) |
| 節點映像 | kindest/node v1.37.0、v1.36.4(皆以 sha256 digest 固定) |
| kubectl | v1.37.2 |
| cloud-provider-kind | v0.12.0(tarball SHA256 已驗證) |
| Headlamp | Helm chart 0.46.0(helm v4.3.1) |
| kube-proxy 模式 | nftables(原因見「實測踩坑紀錄」) |
測試方式說明:本文的安裝、部署、多節點、版本切換、Ingress、Gateway API、Headlamp 等步驟皆為實測(2026-10-29),並在全新環境用同一份腳本把整套流程重跑一次,14 個檢查項目全部通過;標示「查核」的內容來自官方文件或原始碼;標示「未實測」的項目(例如 Cilium/eBPF、TLS)只依官方文件說明。文中的時間與記憶體數字都來自實測紀錄,兩次測試數字不同時會列出範圍。
安裝步驟
以下以 kind v0.33.0 為例(請以 GitHub Releases 頁面的最新版本為準)。kind 需要先安裝 Docker(官方也支援 Podman、nerdctl,本文未實測),以及 kubectl。
1. 下載並驗證 kind 執行檔
從 v0.33.0 Releases 頁面下載符合您平台的執行檔(本文為 kind-linux-amd64)和同名的 .sha256sum 檔,放到 PATH 中並命名為 kind。一定要比對 SHA256,確認下載的檔案沒有被竄改:
echo "aee6151561422756b764a4ae28e7f44cda5af5a9eead3cc9985112b1de8d8e0d $(command -v kind)" | sha256sum -c
kind version上面的雜湊值是 kind-linux-amd64 v0.33.0 的值,其他平台或版本請改用 Releases 頁面對應的 .sha256sum 檔。
成功時您會看到:驗證結果為 OK,版本為 kind v0.33.0(2026-10-29 全新環境重跑的紀錄):
kind v0.33.0 go1.26.7 linux/amd64
/usr/local/bin/kind: OK
2. 準備叢集設定檔
官方 Quick Start 的一行 kind create cluster 就能建出叢集,但預設值有兩個地方建議先改:連接埠預設綁在所有網路介面(0.0.0.0),以及 kube-proxy 預設用 iptables 模式(在部分核心上會整個不通,見踩坑紀錄)。本文實測用的設定檔 kind-config.yaml 如下(節錄,完整設定共 10 組連接埠):
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: jslab
networking:
kubeProxyMode: "nftables"
nodes:
- role: control-plane
image: kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5
labels:
ingress-ready: "true"
extraPortMappings:
- { containerPort: 30002, hostPort: 18002, listenAddress: "127.0.0.1", protocol: TCP }
- { containerPort: 30003, hostPort: 18003, listenAddress: "127.0.0.1", protocol: TCP }image加上@sha256::固定節點映像,避免同一個標籤日後指向不同內容。digest 請從 kind 的 Releases 頁面複製。listenAddress: "127.0.0.1":讓 NodePort 只在本機可以連。官方文件註明「0.0.0.0 is the current default」,不寫就會開在所有介面上。kubeProxyMode: "nftables":改用 nftables 模式;為什麼要改,見「實測踩坑紀錄」與「kube-proxy 三種模式的差別」。
注意:連接埠預設開在 0.0.0.0
沒有寫 listenAddress 的 extraPortMappings 會綁在主機的所有網路介面(官方文件:「0.0.0.0 is the current default」),同一個網路裡的其他電腦都連得到您的測試服務。每一組都寫上 listenAddress: "127.0.0.1",下一步建好叢集後再用步驟 4 確認。
這一步只是寫設定檔,沒有指令輸出;設定有沒有生效,會在步驟 3、4 確認。
3. 建立叢集並確認狀態
kind create cluster --name jslab --config kind-config.yaml --wait 120s
kubectl get nodes -o wide
kubectl wait --for=condition=Ready node --all --timeout=120s
kubectl -n kube-system logs ds/kube-proxy | grep -m1 'Using nftables Proxier'成功時您會看到:各步驟打勾、Ready after 秒數,最後 kube-proxy 紀錄出現 Using nftables Proxier(2026-10-29 實測紀錄節錄):
Creating cluster "jslab" ...
✓ Ensuring node image (kindest/node:v1.37.0) 🖼️
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
• Ready after 18s 💚
Set kubectl context to "kind-jslab"
I1029 00:41:05.655756 1 server_linux.go:231] "Using nftables Proxier"實測建立時間:節點映像已在本機時約 26~28 秒;第一次建立(含下載約 1.34 GB 的節點映像)為 35.7 秒(2026-10-28 實測)。單節點叢集的節點容器約使用 517~632 MiB 記憶體,刪除叢集不到 1 秒。最後一行看到 Using nftables Proxier,代表 kube-proxy 確實用 nftables 模式。

注意:節點是特權容器
實測 kind 的節點容器以 Privileged 模式執行,seccomp 與 AppArmor 為 unconfined,也沒有記憶體上限(kind 的設計如此)。叢集裡跑的東西等於能碰到您的主機:不要在 kind 裡執行來路不明的映像,並替自己的工作負載設定記憶體上限。
注意:妥善保管 kubeconfig
官方說明沒有設定 KUBECONFIG 環境變數時,kind 會把連線設定寫進 ${HOME}/.kube/config。這個檔案等同叢集的管理員鑰匙,不要貼到聊天室、Issue 或 AI 工具裡。本文實測把它放在權限 600 的獨立檔案,可以這樣檢查:
stat -c '%a %U:%G %n' "$KUBECONFIG"
kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'4. 確認連接埠只綁在本機
ss -ltnH
docker port jslab-control-plane成功時您會看到:docker port 列出的每一組對應都是 127.0.0.1,ss 的結果裡沒有 0.0.0.0:180xx(2026-10-29 實測紀錄節錄):
80/tcp -> 127.0.0.1:18018
443/tcp -> 127.0.0.1:18019
6443/tcp -> 127.0.0.1:33005
30002/tcp -> 127.0.0.1:18002
30003/tcp -> 127.0.0.1:18003API server 的連接埠(上面的 6443)預設就只綁 127.0.0.1 的隨機連接埠;extraPortMappings 有寫 listenAddress: "127.0.0.1" 的連接埠也只會出現在 127.0.0.1。同樣的設定拿掉 listenAddress 再建一次,實測 18003 會變成 0.0.0.0:18003,同一個網路裡的其他電腦都連得到。


5. 部署範例並從主機連線
範例 k8s-hello.yaml 是一個 nginx Deployment(設定記憶體上限 64Mi)加上 NodePort 30002 的 Service,對應到主機的 127.0.0.1:18002:
kubectl apply -f k8s-hello.yaml
kubectl rollout status deploy/hello --timeout=120s
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:18002/成功時您會看到:三個資源建立、rollout 完成(以下為 2026-10-29 全新環境重跑的 kubectl 輸出節錄),接著最後一行 curl 印出 200:
configmap/hello-html created
deployment.apps/hello created
service/hello created
Waiting for deployment "hello" rollout to finish: 0 of 1 updated replicas are available...
deployment "hello" successfully rolled out實測從 kubectl apply 到回應 HTTP 200 約 2.7 秒。

多節點叢集
在設定檔的 nodes 加上兩個 worker(映像同樣以 digest 固定)就是 1 個 control-plane 加 2 個 worker:
- role: worker
image: kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5
- role: worker
image: kindest/node:v1.37.0@sha256:a1ed56cfb0e7b93589bdf97c8cd566405a265939e3620fc4f5de89adff580ae5kind create cluster --name jslab --config kind-config-3node.yaml --wait 120s
kubectl get nodes
kubectl scale deploy/hello --replicas=3
kubectl get pods -o wide實測建立約 26.1~27.5 秒,記憶體用量 control-plane 約 545~600 MiB、每個 worker 約 119~182 MiB。
- inotify 上限:測試主機維持預設上限(instances 128),三節點時 root 已用 91 個 instance(control-plane 約 45 個、每個 worker 約 18 個),還沒出現「too many open files」。依這個幅度推估,再多約兩個 worker 就可能碰到上限;官方 Known Issues 建議調成
fs.inotify.max_user_watches=524288、fs.inotify.max_user_instances=512。 - 實際用量:可用
cat /proc/sys/fs/inotify/max_user_instances查看目前上限。

常用指令
以下指令都在本次實測中執行過:
| 指令 | 用途 |
|---|---|
kind version | 顯示 kind 版本 |
kind create cluster --name <名稱> --config <設定檔> --wait 120s | 建立叢集,等待節點就緒 |
kind get clusters | 列出所有 kind 叢集 |
kind get nodes --name <名稱> | 列出叢集的節點容器 |
kind load docker-image <映像> --name <名稱> | 把本機映像載入叢集節點 |
kind export logs <目錄> --name <名稱> | 匯出除錯紀錄 |
kind delete cluster --name <名稱> | 刪除叢集(資料一併刪除) |
實測踩坑紀錄
點選每個症狀可以展開原因與解法:
Pod 正常,但從主機連 NodePort 被重設(connection reset)
原因:預設 iptables 模式需要核心的 statistic 擴充(CONFIG_NETFILTER_XT_MATCH_STATISTIC),測試主機的核心沒有,kube-proxy 整批規則寫入失敗
解法:改用 kubeProxyMode: "nftables"(核心需 5.13 以上)

沒寫 listenAddress,連接埠開在 0.0.0.0
原因:官方預設值就是 0.0.0.0
解法:每組 extraPortMappings 都寫 listenAddress: "127.0.0.1"
Pod 一直卡在 ContainerCreating、rollout 逾時,預設 bridge 網路卻正常
原因:主機殘留舊的 iptables-legacy DOCKER 規則(FORWARD 預設 DROP),擋掉 kind 自訂網路的對外連線
解法:先檢查自己環境的防火牆現況(見下方),確認規則來源後再處理
先確認自己環境的防火牆現況:如果您的主機曾經切換過 iptables 與 nftables,或裝過其他防火牆工具,建立 kind 叢集前可以先做兩個檢查。第一行檢查有沒有殘留的 iptables-legacy DOCKER 規則(ip6tables-legacy 也照樣檢查),第二行從 kind 網路連 Docker Hub,回應 401 代表網路是通的(只是沒有登入):
sudo -n iptables-legacy -S | grep -q -- '-N DOCKER' && echo "有殘留的 iptables-legacy DOCKER 規則"
docker run --rm -m 64m --network kind nginx:1.30.6-alpine wget -q -O /dev/null -T 8 https://registry-1.docker.io/v2/第二行要在 kind 建立過 kind 網路之後才能執行(刪除叢集後這個網路會保留)。發現殘留規則時,請先備份並確認是哪個工具建立的,不要直接清除整個防火牆;在共用主機或公司電腦上,請先和管理者確認。
多節點建好、rollout 完成,第一次 curl 卻回 000
原因:新 Pod 的轉送規則還沒同步完成
解法:等 1~5 秒再試,或在腳本中加重試
重啟節點容器後,local-path-provisioner 顯示 Error
原因:它比 API server 先啟動、連不上而退出
解法:會自動重啟恢復,不需處理
kubectl top 無法使用
原因:kind 預設沒有安裝 metrics-server
解法:改用 docker stats 看節點容器的資源用量
升級 Kubernetes 版本後,之前建的資源都不見了
原因:kind 沒有原地升級,換版本=刪掉重建
解法:把 YAML、Helm 指令保存在 Git,重建後重新套用
執行 kind 或 docker 指令出現權限錯誤
原因:使用者不在 docker 群組
解法:加入 docker 群組;注意 Docker 官方提醒 docker 群組等同 root 權限
kube-proxy 三種模式的差別
kube-proxy 負責把 Service 的流量轉送到 Pod,它有幾種實作方式。這是 kube-proxy 的模式,不是容器網路介面(CNI);kind 預設的 CNI 是 kindnet,本文沒有更換。
| 模式 | 官方狀態 | 核心需求 | 本次實測 |
|---|---|---|---|
| iptables | Kubernetes v1.37 與 kind 的預設 | 需要 iptables 擴充模組(含 statistic) | 失敗:測試核心缺少 statistic,NodePort 不通 |
| nftables | Kubernetes v1.33 起為穩定版(GA),官方表示未來會改成預設 | Linux 核心 5.13 以上 | 成功,本文全程使用 |
| ipvs | v1.35 起棄用,v1.40 起預設停用,v1.43 移除 | 需要 IPVS 模組 | 未實測(已棄用) |
| 不用 kube-proxy(eBPF,例如 Cilium) | kind 可設 kubeProxyMode: "none" 並停用預設 CNI | Cilium 需核心 5.10 以上與多項模組 | 未實測(原因見下方) |
- nftables 與 iptables 的行為差異:官方說明 iptables 模式的 NodePort 預設在節點所有 IP 上都能連,nftables 模式則預設只在節點的主要 IP 上(
--nodeport-addresses primary)。從主機透過 extraPortMappings 連127.0.0.1:18002不受影響(實測正常)。 - 從 iptables 改成 nftables:kind 叢集直接在設定檔改
kubeProxyMode後重建即可;正式叢集要切換,請先讀官方的遷移說明,因為部分防火牆互動行為不同。 - 為什麼沒有實測 Cilium:查核時 Cilium 穩定版 v1.20.4 的支援清單只到 Kubernetes v1.36,還沒有列 v1.37;測試主機的精簡核心也缺少 Cilium 預設設定需要的 VXLAN/GENEVE、ipset 等模組,要為這台主機改多個設定值,結果不具代表性,所以只依官方文件說明。
【進階】Ingress 與 Gateway API(ingress-nginx 退役後)
很多舊教學會在 kind 上裝 ingress-nginx,但 Kubernetes 官方部落格已宣布 ingress-nginx 在 2026 年 3 月退役、停止維護;官方的 Ingress 文件也寫明 Ingress API 已凍結,建議改用 Gateway API。kind 官方的 Ingress 文件目前改用 cloud-provider-kind(從 v0.9.0 起原生支援 Ingress,不必另外安裝 Ingress 控制器),它會在主機上執行,替 LoadBalancer、Ingress 和 Gateway 建立 envoy 容器。
這一段需要另外執行 cloud-provider-kind,並會在主機開出無驗證的管理介面,和主線無關的讀者可以先略過;需要時點開下方的完整步驟。
【進階】展開:cloud-provider-kind、Ingress 與 Gateway API 實測步驟

步驟 1:下載、驗證並啟動 cloud-provider-kind
curl -fsSL -o cloud-provider-kind_0.12.0_linux_amd64.tar.gz https://github.com/kubernetes-sigs/cloud-provider-kind/releases/download/v0.12.0/cloud-provider-kind_0.12.0_linux_amd64.tar.gz
echo "5716aca8f01a85172c12f3b6329c70f151bec02c91b6f600c9f230845ee138e6 cloud-provider-kind_0.12.0_linux_amd64.tar.gz" | sha256sum -c
tar xzf cloud-provider-kind_0.12.0_linux_amd64.tar.gz cloud-provider-kind
./cloud-provider-kind --gateway-channel standard > cpk.log 2>&1 &成功時您會看到:tarball 驗證結果為 OK(2026-10-29 實測紀錄):
cloud-provider-kind_0.12.0_linux_amd64.tar.gz: OK危險:envoy 管理介面外露
cloud-provider-kind 的 envoy 管理介面(admin)會被 Docker 的 --publish-all 發佈到主機的 0.0.0.0 隨機連接埠,而且沒有驗證。實測連到 /server_info 直接回 HTTP 200;這個行為寫在 cloud-provider-kind 的程式碼裡,沒有選項可以關掉。另外,它和 envoy 溝通的 XDS 服務會在 Docker 預設網橋 172.17.0.1 上開一個隨機連接埠;envoy 容器也沒有設定記憶體上限。
雜湊值是 v0.12.0 Linux amd64 tarball 的值(來自 Releases 頁面的 checksums)。cloud-provider-kind 需要存取 Docker,官方說明它需要開連接埠與連線容器執行環境的權限。啟動後會自動安裝 Gateway API 的 CRD、預設的 IngressClass 和名為 cloud-provider-kind 的 GatewayClass;第一次使用時還會下載 envoy 映像(約 261 MB)。
步驟 2:用 Ingress 依路徑分流
這裡直接套用 kind 官方文件的 Ingress 範例(ingress-usage.yaml:/foo 和 /bar 分到兩個 Pod)。官方範例沒有設定資源上限,所以先套用一份 LimitRange,替 default 命名空間的容器加上預設記憶體上限 64Mi:
kubectl apply -f limitrange-default.yaml -f ingress-usage.yaml
kubectl wait --for=condition=Ready pod/foo-app pod/bar-app --timeout=180s
IP=$(kubectl get ingress example-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://$IP/foo
kubectl get ingressclass,gatewayclass實測從套用到 Ingress 取得 IP 約 2~4.9 秒,/foo、/bar 都分流正確。這個 IP(實測為 172.18.0.3)位在 Docker 的 kind 網路上,只有本機連得到。cloud-provider-kind 內部會把 Ingress 轉成 Gateway 與 HTTPRoute 來處理。

步驟 3:用 Gateway API 做路徑、標頭與權重分流
Gateway API 把「入口」(Gateway)和「路由規則」(HTTPRoute)分開。下面節錄自本文的 gateway-usage.yaml,後端同樣是 foo、bar 兩個 Pod:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: { name: jslab-gw }
spec:
gatewayClassName: cloud-provider-kind
listeners:
- { name: http, protocol: HTTP, port: 80, allowedRoutes: { namespaces: { from: Same } } }
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: { name: canary-header }
spec:
parentRefs: [ { name: jslab-gw } ]
rules:
- matches: [ { path: { type: PathPrefix, value: /app }, headers: [ { name: X-Canary, value: "true" } ] } ]
backendRefs: [ { name: bar-service, port: 8080 } ]
- matches: [ { path: { type: PathPrefix, value: /app } } ]
backendRefs: [ { name: foo-service, port: 8080 } ]
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: { name: weighted }
spec:
parentRefs: [ { name: jslab-gw } ]
rules:
- matches: [ { path: { type: PathPrefix, value: /split } } ]
backendRefs:
- { name: foo-service, port: 8080, weight: 80 }
- { name: bar-service, port: 8080, weight: 20 }kubectl apply -f limitrange-default.yaml -f gateway-usage.yaml
kubectl wait --for=condition=Programmed gateway/jslab-gw --timeout=120s
GW=$(kubectl get gateway jslab-gw -o jsonpath='{.status.addresses[0].value}')
curl -H 'X-Canary: true' http://$GW/app成功時您會看到:Gateway 的 PROGRAMMED 為 True,並取得 kind 網路上的 IP(2026-10-29 全新環境重跑的紀錄節錄):
gateway.gateway.networking.k8s.io/jslab-gw condition met
NAME CLASS ADDRESS PROGRAMMED AGE
jslab-gw cloud-provider-kind 172.18.0.3 True 1s實測結果:帶 X-Canary: true 標頭的請求分到 bar,沒帶的分到 foo;對 /split 送 200 次請求,兩次測試分別為 155/45 與 157/43,接近設定的 80/20。從套用到 /foo 有回應約 2.3~3.0 秒。

步驟 4:Ingress 與 Gateway API 怎麼選
| 比較項目 | Ingress | Gateway API |
|---|---|---|
| 官方狀態 | API 已凍結,不再加新功能 | 官方建議的新方式 |
| 本次範例 | 官方範例 5 個物件、77 行 | 8 個物件、73 行(多了標頭與權重兩條規則) |
| 標頭、權重分流 | 標準欄位沒有,要靠各控制器的註解 | 標準欄位就支援(實測可用) |
| 實測反應時間 | 套用到可連線約 3.5~4.9 秒 | 約 2.3~3.0 秒 |
| 資源用量(實測) | envoy 約 17~19 MiB,cloud-provider-kind 約 68~75 MiB | 相同 |
簡單來說:維護既有的 Ingress YAML,kind 上用 cloud-provider-kind 一樣能測;新寫的設定建議直接用 Gateway API。TLS 本次未實測。
步驟 5:用完記得停止 cloud-provider-kind
- 用完就停:用
kill -TERM <PID>停止 cloud-provider-kind,它會自動移除 envoy 容器,實測停止後管理介面和 XDS 連接埠都不再監聽。 - 不要在有公開 IP 或不受信任網路的主機上執行:如果一定要用,請先用主機防火牆擋掉這些隨機連接埠。

【進階】本機開發流程:載入映像、換版本、匯出紀錄、重啟節點
開發時常用的四個操作:把本機建置的映像載入叢集、換 Kubernetes 版本(等於重建)、匯出除錯紀錄,以及重啟節點容器(資料會保留)。只想先把叢集跑起來的讀者可以跳過。
【進階】展開:載入映像、換版本、匯出紀錄、重啟節點
操作 1:載入本機建置的映像
在本機建置映像後用 kind load 放進節點,Deployment 要設定 imagePullPolicy: IfNotPresent,否則 Kubernetes 會試著從網路拉這個不存在的映像:
docker build -q -t jslab/hello:0.1 hello-image
kind load docker-image jslab/hello:0.1 --name jslab
docker exec jslab-control-plane crictl images | grep jslab/hello
kubectl apply -f hello-local.yaml
curl -s http://127.0.0.1:18003/成功時您會看到:映像載入節點、rollout 完成,curl 回應映像的內容(2026-10-29 全新環境重跑的紀錄節錄;叢集名稱為驗證腳本自動產生):
Image: "jslab/hello:0.1" with ID "sha256:c055315a1273180fbbfb7239cdfd1a217274369b38d0f61599999e56a5b70cab" not yet present on node "jslab-verify-20261029-132930-control-plane", loading...
docker.io/jslab/hello 0.1 b9c27d8cf5504 26.1MB
deployment "hello-local" successfully rolled out
hello from jslab/hello:0.1 (kind load) via 18003實測建置加載入約 3.3 秒,Pod 事件顯示「already present on machine」,代表映像沒有從網路下載。

操作 2:指定舊版 Kubernetes,以及「升級=重建」
把設定檔中的節點映像換成 kindest/node:v1.36.4@sha256:099e049362a1526b2db71494e1947aae99bd16290d7c895f2b7ea312e3cbfaed 就能建立 v1.36.4 叢集(實測 26.1~26.6 秒)。kind 沒有原地升級,要換版本就是刪掉重建:
kind delete cluster --name jslab
kind create cluster --name jslab --config kind-config.yaml --wait 120s
kubectl version -o json實測從 v1.36.4 重建成 v1.37.0 約 27.3~31.4 秒,舊叢集裡建立的 ConfigMap 不在了。kubectl v1.37.2 連 v1.36.4 叢集沒有出現警告,符合官方「kubectl 與 API server 相差一個次版本以內」的版本差異政策;更舊的叢集請換對應版本的 kubectl。

操作 3:匯出除錯紀錄
kind export logs ./kind-logs --name jslab成功時您會看到:匯出目錄的路徑(2026-10-29 實測紀錄;實測時匯出到 /tmp 底下的目錄):
Exporting logs for cluster "jslab" to:
/tmp/jslab-kc/kind-logs實測 0.2 秒匯出 32 個檔案(約 712 KB~784 KB)。
注意:分享前請先檢查內容
實測匯出的紀錄包含主機名稱與多個內部 IP,貼到 Issue 或論壇前要先遮蔽。
操作 4:重啟節點容器,資料會保留
和「重建」不同,重新啟動節點容器不會清空叢集:
kubectl create configmap restart-marker --from-literal=before=restart
docker restart jslab-control-plane
kubectl get --raw /readyz實測 docker restart 約 11.4~11.5 秒,API server 約 17 秒後恢復,範例服務 18002 在 17.0~35.4 秒間恢復,ConfigMap 與節點 IP 都沒變。期間 local-path-provisioner 會短暫顯示 Error,之後自動恢復。


【進階】用 Headlamp 看叢集(取代已封存的 Kubernetes Dashboard)
Kubernetes Dashboard 已在 2026-01-21 封存,官方文件建議新安裝改用 Headlamp。以下用 Helm 安裝在叢集內,只透過 127.0.0.1 的 port-forward 存取。只想先把叢集跑起來的讀者可以跳過。
【進階】展開:Headlamp 安裝、短效 token 登入與清除
helm repo add headlamp https://kubernetes-sigs.github.io/headlamp/
helm repo update headlamp
helm install headlamp headlamp/headlamp --version 0.46.0 -n kube-system --set resources.limits.memory=256Mi --set resources.requests.memory=64Mi --wait --timeout 180s
kubectl -n kube-system create serviceaccount jslab-headlamp-admin
kubectl create clusterrolebinding jslab-headlamp-admin --clusterrole=cluster-admin --serviceaccount=kube-system:jslab-headlamp-admin
( umask 077; kubectl -n kube-system create token jslab-headlamp-admin --duration=30m > hl.token )
kubectl -n kube-system port-forward --address 127.0.0.1 service/headlamp 18010:80注意:cluster-admin 權限很大
範例替 Headlamp 建立 cluster-admin 權限的 ServiceAccount,只適合本機實驗叢集;token 用短效(30 分鐘),只走 127.0.0.1 的 port-forward,token 檔不要截圖或分享。
開啟 http://127.0.0.1:18010/,貼上 hl.token 的內容登入。實測安裝(含等待 Pod 就緒)約 22 秒,Headlamp Pod 約 16~22 MB 記憶體;用 token 呼叫 API 回 200,沒有 token 回 403。
- token 用短效:
create token --duration=30m產生 30 分鐘後失效的 token,不要建立長效的 Secret token。 - 用完清除:依序執行
shred -u hl.token、helm uninstall headlamp -n kube-system --wait、刪除 clusterrolebinding 與 serviceaccount、helm repo remove headlamp。



安全檢查清單與清理
預設值偏方便
kind 是開發工具,很多預設值是為了方便,不是為了安全。各步驟旁的提示框已說明細節,這裡是使用前後的總整理清單:
- 驗證下載的檔案:kind 執行檔、cloud-provider-kind tarball 都比對 SHA256;節點映像用
@sha256:固定。 - 連接埠只綁本機:extraPortMappings 一律寫
listenAddress: "127.0.0.1",用ss -ltnH確認沒有 0.0.0.0。 - 保管 kubeconfig:權限 600,不要分享
kind get kubeconfig的輸出。 - 知道節點是特權容器:實測節點容器以 Privileged 模式執行、seccomp 與 AppArmor 為 unconfined、沒有記憶體上限。不要在 kind 裡跑來路不明的映像,並自行替工作負載設定記憶體上限。
- cloud-provider-kind 用完就停:envoy 管理介面開在 0.0.0.0 且無驗證。
- 分享紀錄前先遮蔽:
kind export logs會包含主機名稱與內部 IP。 - Headlamp 用短效 token,只走 127.0.0.1 的 port-forward。
用完後清理:
kind delete cluster --name jslab
kind get clusters
docker image rm jslab/hello:0.1刪除叢集後,Docker 的 kind 網路會保留(下次建立會沿用);節點映像每個約 1.3 GB,不再需要時可用 docker image rm 移除。
第三部分:評價與延伸
這一部分是實測後的評價、使用小技巧與延伸資源。
優缺點
優點:
- 免費又快:不需要雲端帳號,約 30 秒就有一個真的 Kubernetes 叢集。
- 重現性高:設定檔加上固定 digest,換一台電腦也能建出一樣的叢集。
- 貼近正式 Kubernetes:用上游的 kubeadm 與元件,可以測多節點、版本差異、Gateway API。
- 官方維護:Kubernetes SIG 專案,更新跟著 Kubernetes 版本走。
缺點:
- 預設值偏方便、不偏安全:連接埠預設 0.0.0.0、Quick Start 的安裝指令沒有 SHA256 驗證步驟、節點是特權容器。
- 和主機核心綁在一起:本文就碰到預設 iptables 模式在精簡核心上整個不通。
- 沒有升級:換版本就清空資料。
- 周邊功能要另外裝:LoadBalancer、Ingress、metrics-server、Dashboard 都不是內建,cloud-provider-kind 還有 envoy 管理介面外露的問題。
綜合評價

文字版評分與理由:
- 社群活躍度:★★★★☆(4) GitHub 15,580 星、1,825 個 fork,近 90 天 39 個 commit、10 位非機器人作者,屬 Kubernetes SIG 專案。(GitHub API,2026-10-29)
- 安裝難易度:★★★★☆(4) 一個執行檔加 Docker,叢集約 26~28 秒建好(實測);扣一顆星是因為預設 0.0.0.0、iptables 模式在部分核心不通,要自己改設定檔。
- 更新頻率:★★★☆☆(3) 近 12 個月 3 個版本(v0.31.0、v0.32.0、v0.33.0),每版附新 Kubernetes 版本的節點映像;最近一次 commit 為 2026-10-22。(GitHub Releases/API,2026-10-29)
- 升級方式:★★★☆☆(3) 換執行檔很簡單,但叢集沒有原地升級,重建約 27~31 秒且資料清空(實測)。
- 計費模式:★★★★★(5) Apache-2.0 授權,完全免費、沒有付費版本;成本只有本機的記憶體與磁碟。(GitHub LICENSE)
小技巧
- 設定檔放進 Git:kind 設定、YAML、Helm 指令都保存在儲存庫,重建時幾分鐘就能回到原狀。
- NodePort 固定對應:在設定檔預留一段 NodePort(例如 30002~30009 對應 18002~18009),測試服務時就不用每次改設定重建。
- 本機映像載入失敗時:本文沒有重現官方 Issue #3795 描述的載入失敗;如果您遇到,可依 Known Issues 改用
docker image save --platform linux/amd64存成檔案,再用kind load image-archive載入(實測可用)。 - 定期更新:更新 kind 前先看 Releases 頁面的 Breaking Changes,換新執行檔後再驗證一次 SHA256;叢集要換版本就照「升級=重建」流程。
結語與下一步
kind 讓您不用付雲端費用,約 30 秒就在自己的電腦上有一個真的 Kubernetes 叢集;只要先把連接埠綁在本機、改用 nftables 模式並保管好 kubeconfig,就能放心拿來學習與驗證設定。它的定位是用完即丟的測試環境,正式服務請改用正式的 Kubernetes 叢集。
下一步,您可以:
- 把服務搬到正式叢集:參考 MetalLB:裸機 Kubernetes 叢集的負載平衡解決方案 與 Harbor:自架容器映像檔倉庫,準備負載平衡與映像檔倉庫。
- 導入時需要協助:歡迎透過聯絡我們詢問。
NotebookLM 互動問答
想針對本文或官方文件提問,可以使用我們整理的 NotebookLM 筆記:kind 互動問答(NotebookLM)。筆記的來源只收錄 kind、Kubernetes、cloud-provider-kind、Gateway API 與 Headlamp 的官方網站、官方文件與 GitHub 儲存庫,回答內容仍請以官方文件為準。
參考連結
- kind 官方網站
- kind GitHub 儲存庫
- kind v0.33.0 版本說明(Release notes)
- kind 設定檔說明(Configuration)
- kube-proxy 模式說明(Virtual IPs and Service Proxies)
- ingress-nginx 退役公告(Kubernetes 官方部落格)
本文僅供學習參考,請在您自己的環境自行評估風險,詳見免責與揭露聲明。
本文寫作方式:本文的測試計劃與審稿由強哥負責,實測操作、紀錄整理與初稿由 AI 助理協作完成,所有數字皆來自實測紀錄或官方來源;封面與示意圖為原創繪製(未使用 AI 生成圖片),截圖為實測畫面。
