前情提要:昨天我們成功安裝了 KinD 並建立了第一個 Kubernetes 集群。今天我們要深入了解這個集群內部到底有什麼,以及如何用 YAML 來描述我們的應用。
作為一個習慣使用 Docker Compose 的後端開發者,今天你將學會:
如果讀這篇的你昨天已經刪除了Cluster,讓我們重新建立:
# 檢查現有Cluster
kind get clusters
# 如果沒有Cluster,建立一個新的
kind create cluster --name learning
# 確認Cluster運作正常
kubectl cluster-info
你應該會看到類似這樣的輸出:
Kubernetes control plane is running at https://127.0.0.1:xxxxx
CoreDNS is running at https://127.0.0.1:xxxxx/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
現在讓我們看看這個Cluster裡面到底有什麼。就像你用 docker ps
查看運行的容器一樣,我們用以下命令查看 Kubernetes 的組件:
# 查看所有命名空間中的 Pod(類似 docker ps -a)
kubectl get pods --all-namespaces
# 簡寫形式
kubectl get pods -A
💡 小白提示:Pod 是 Kubernetes 中最小的部署單位,你可以把它想像成一個或多個緊密相關的容器的組合。
你會看到類似這樣的輸出:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-674b8bbfcf-mkk29 1/1 Running 34 (131m ago) 20d
kube-system coredns-674b8bbfcf-sgwx5 1/1 Running 34 (131m ago) 20d
kube-system etcd-learning-control-plane 1/1 Running 34 (131m ago) 20d
kube-system kindnet-cnhrt 1/1 Running 34 (131m ago) 20d
🤔 這些都是什麼?別擔心,我們接下來會一一解釋每個組件的作用!
為了更容易理解,我用公司組織來類比 Kubernetes 的架構:
# 查看 API Server 的詳細資訊
kubectl describe pod -n kube-system kube-apiserver-learning-control-plane
作用:
類比 Docker Compose:
如果 docker-compose up
是直接命令,那 kubectl
就是通過 API Server 這個「櫃台」來下達命令
# 查看 etcd 狀態
kubectl describe pod -n kube-system etcd-learning-control-plane
作用:
類比 Docker Compose:
就像你的 docker-compose.yml 檔案,但是是即時更新的動態版本,記錄著「現在應該有什麼服務」和「實際運行什麼服務」
親和性,待後續幾篇在解釋
# 查看 Scheduler
kubectl describe pod -n kube-system kube-scheduler-learning-control-plane
作用:
類比 Docker Compose:
Docker Compose 只能在一台機器上運行,Scheduler 就像是決定「這個服務要放在哪台伺服器上」的 AI 系統
# 查看 Controller Manager
kubectl describe pod -n kube-system kube-controller-manager-learning-control-plane
作用:
類比 Docker Compose:
類似 docker-compose up 的 --restart=always
功能,但更聰明:如果你說要 3 個副本,它會確保始終有 3 個在運行
作用:
類比 Docker Compose:
類似每台機器上的 Docker Engine,但會主動與總部(API Server)保持聯繫
# 查看 kube-proxy
kubectl get pods -n kube-system | grep kube-proxy
作用:
類比 Docker Compose:
類似 Docker Compose 的網路功能,但可以跨多台機器進行服務發現和負載均衡
作用:
類比 Docker Compose:
就是 Docker Engine 本身,在 Kubernetes 中被 kubelet 管理和調用
讓我們實際看看這些組件在做什麼:
# 建立一個測試 Pod 來產生事件
kubectl run test-pod --image=nginx:1.21 --restart=Never
# 查看節點資訊
kubectl get nodes -o wide
# 查看節點詳細資訊
kubectl describe node learning-control-plane
# 查看系統 Pod 的資源使用
kubectl top pods -n kube-system 2>/dev/null || echo "需要安裝 metrics-server"
# 查看集群事件(類似系統日誌)
kubectl get events --sort-by=.metadata.creationTimestamp
事件的生命週期
Kubernetes 事件有時間限制:
如果你熟悉 Docker Compose,那你已經知道 YAML 的基本語法了:
# 這是註解
key: value # 鍵值對
list: # 列表
- item1
- item2
nested: # 巢狀結構
subkey: subvalue
multiline: | # 多行文字
這是第一行
這是第二行
Namespace(命名空間),待後續幾篇在解釋
每個 Kubernetes 資源都遵循相同的基本結構:
apiVersion: <API版本> # 類似 Docker Compose 的 version
kind: <資源類型> # 類似 Docker Compose 的 services/volumes/networks
metadata: # 資源的基本資訊
name: <資源名稱>
namespace: <命名空間> # 類似資料夾概念,預設是 default
labels: # 標籤,用於選擇和組織
app: myapp
version: v1
annotations: # 註解,用於存放額外資訊
description: "這是我的應用"
spec: # 資源的具體規格(你想要什麼)
# 這裡的內容根據 kind 而不同
status: # 資源的當前狀態(系統維護,通常不需要寫)
# Kubernetes 自動填寫
YAML 檢查工具:
# 驗證 YAML 語法
kubectl apply --dry-run=client -f your-file.yaml
# 查看實際會建立什麼
kubectl apply --dry-run=server -f your-file.yaml
這是學習 Kubernetes YAML 的最佳工具,就像查閱 API 文件一樣:
# 了解 Pod 的基本結構
kubectl explain pod
# 深入了解 Pod 的 spec 部分
kubectl explain pod.spec
# 查看 Pod 容器的配置選項
kubectl explain pod.spec.containers
# 了解 Deployment
kubectl explain deployment
kubectl explain deployment.spec
# 查看所有可用的資源類型
kubectl api-resources
💡 小白提示:每當你不確定某個欄位怎麼寫時,就用 kubectl explain 查詢!
讓我們建立第一個 Pod,就像你第一次寫 docker run 命令一樣:
# first-pod.yaml
apiVersion: v1 # Pod 是 v1 API 的一部分
kind: Pod # 資源類型是 Pod
metadata:
name: hello-pod # Pod 的名稱
labels:
app: hello # 標籤,方便後續選擇
environment: learning # 環境標籤
spec:
containers: # 容器列表(一個 Pod 可以有多個容器)
- name: hello-container # 容器名稱
image: nginx:1.29.0-otel # 映像檔,就像 Docker 一樣
ports:
- containerPort: 80 # 容器內部埠號
env: # 環境變數
- name: ENVIRONMENT
value: "learning"
resources: # 資源限制(Docker Compose 也有類似功能)
requests: # 最少需要的資源
memory: "64Mi"
cpu: "250m" # 250 milliCPU = 0.25 CPU
limits: # 最多能使用的資源
memory: "128Mi"
cpu: "500m"
# 這個 Pod 相當於以下 Docker 命令:
docker run -d \
--name hello-container \
-p 80:80 \
-e ENVIRONMENT=learning \
--memory=128m \
--cpus=0.5 \
nginx:1.29.0-otel
# 建立 Pod
kubectl apply -f first-pod.yaml
# 查看 Pod 狀態
kubectl get pods
# 查看詳細資訊
kubectl describe pod hello-pod
# 查看 Pod 日誌(類似 docker logs)
kubectl logs hello-pod
# 進入 Pod 內部(類似 docker exec)
kubectl exec -it hello-pod -- /bin/bash
# 在容器內測試
curl localhost
exit
# 從外部訪問 Pod(類似 docker port-forward)
kubectl port-forward pod/hello-pod 8080:80
打開另一個 Terminal 或瀏覽器測試:
curl http://localhost:8080
你應該會看到 Nginx 的歡迎頁面!
# 刪除 Pod
kubectl delete pod hello-pod
# 或者使用檔案刪除
kubectl delete -f first-pod.yaml
透過比喻的手法,讓一開始接觸 K8s 的我能有更具體的想像來理解各組件之間的職責與關係。再從熟稔的 docker compose 設計的角度做個對比,我覺得自己熟悉的切入學習能更有想像的關聯。
學習成果
kubectl cluster-info
kubectl get pods -A
kubectl get events
kubectl explain
學習資源結構kubectl api-resources
kubectl apply -f first-pod.yaml
kubectl port-forward