iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0

昨天把 K8s 的架構全貌看完了,今天會先針對「宣告式思維」的核心概念說清楚,然後直接寫 Pod YAML,把 Todo App 的後端跑在 K8s 上 !


宣告式思維是什麼?

在學 YAML 之前,先說明一個概念,因為這會影響你怎麼理解後面所有的 K8s 操作。

  • 指令式(Imperative):告訴系統「去做什麼」
# 你說:「啟動一個 nginx container」
docker run nginx
  • 宣告式(Declarative):告訴系統「我要的結果是什麼」
# 你說:「我要一個跑著 nginx 的 Pod 存在」
apiVersion: v1
kind: Pod
spec:
  containers:
    - name: nginx
      image: nginx

差別在哪?

  • 指令式是你下命令、系統執行一次就結束。
  • 宣告式是你描述期望狀態,K8s 負責讓現實符合你的描述——現在是、之後也是,Pod 掛掉了它會重新建一個,Node 故障了它會搬到別的 Node。

Pod YAML 結構拆解

每一份 K8s YAML 都有四個必填欄位:

apiVersion: v1        # 這個資源屬於哪個 API 版本
kind: Pod             # 資源類型
metadata:             # 這個資源的描述資訊
  name: todo-api
spec:                 # 你期望這個資源長什麼樣子
  containers:
    - name: api
      image: yourname/todo-app-api:v1.0.0
  • apiVersion:K8s 的 API 有版本之分,Pod 用 v1,其他資源(例如 Deployment)會用 apps/v1
  • kind:資源類型,今天是 Pod
  • metadata:描述這個資源,name 是必填。
  • spec:核心內容,描述你期望的狀態,Pod 的 spec 主要是定義裡面跑哪些 Container。

實際操作

今天目標:寫第一份 Pod YAML,把 Todo App 的後端跑在 K8s 上,並用 port-forward 直接打 API 確認它真的活著。

Step1: 跑起 todo-api

  1. /Todo-APP/k8s目錄下,建立 todo-api-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: todo-api
spec:
  containers:
    - name: api
      image: yourname/todo-app-api:v1.0.0
      ports:
        - containerPort: 8000
      env:
        - name: DATABASE_URL
          value: "mysql+pymysql://user:password@mysql-service:3306/tododb"
  • ports.containerPort:宣告這個 Container 監聽哪個 port,這裡是 FastAPI 預設的 8000。注意這只是「宣告」,不等於外部可以連進來。
  • env:注入環境變數。這裡把 DATABASE_URL 設定為 MySQL 的連線字串,讓 Pod 知道要連哪個資料庫。

踩坑提醒:

  1. 請確認當前目錄是否正確( /Todo-App/k8s )
  2. todo-api-pod.yaml 中 image是否有調整成自己的 Docker hub name
# example
spec:
 containers:
   - name: api
     image: demo223561/todo-app-api:v1.0.0
     ports:
       - containerPort: 8000
  1. 套用:
# 進到k8s目錄
cd k8s

kubectl apply -f todo-api-pod.yaml
  1. 確認狀態:
kubectl get pods

https://ithelp.ithome.com.tw/upload/images/20260917/20183863dVcNbbjoom.png

STATUSRunningREADY1/1 就代表成功了。

  1. 看 Pod 詳細狀態:
kubectl describe pod todo-api

這個指令很常用,可以看到 Pod 的事件紀錄(Events),排查問題的時候會靠它。

  1. 看 Container 的 log:
kubectl logs todo-api

你會看到 FastAPI 啟動的輸出,確認應用程式有正常跑起來。

  1. 進到 Pod 裡面(選用)
kubectl exec -it todo-api -- bash

# 退出
exit

docker exec 一樣的概念,可以進到 Container 裡面看環境。

Step 2: 用 port-forward 暫時存取

  1. 目前 Pod 只在 Cluster 內部,外面連不進去。用 port-forward 暫時把 Pod 的 port 對應到本機:
kubectl port-forward pod/todo-api 8000:8000
  1. 開另一個 terminal 測試:
curl http://localhost:8000/todos

看到 API 回應就代表 Pod 正常運作了。

port-forward 只是開發和除錯用的,不是正式的對外方式。要讓服務真正對外,需要 Service + Ingress,之後會學到

Step 3: 清理 Pod

kubectl delete pod todo-api

# 或是用 YAML 刪除
kubectl delete -f todo-api-pod.yaml

延伸筆記:Pod 和 Container 的差異

  • Container 是應用程式的執行單位,由 Docker Image 跑起來的一個程序。

  • Pod 是 K8s 的最小調度單位,它是一個或多個 Container 的包裝。

Pod
├── Container A(主應用程式)
└── Container B(sidecar,選用)

大多數情況下,一個 Pod 裡只有一個 Container,所以很容易把兩者混淆。但 Pod 的設計允許多個 Container 共存,這些 Container 會:

  • 共用同一個網路空間(可以用 localhost 互相溝通)
  • 共用同一個儲存空間(可以掛載同一個 Volume)
  • 一起被調度、一起被啟動、一起被終止

最常見的是 Sidecar 模式:主 Container 跑應用程式,旁邊掛一個 Sidecar Container 負責 log 收集、代理、監控等輔助功能。對現在的 Todo App 來說,每個服務都是獨立的 Pod,各自一個 Container,這是最常見的做法。


小結

今天學了兩件事:

  • 宣告式思維:K8s 的 YAML 不是下指令,是描述期望狀態。你說「我要這個」,K8s 負責讓它成真並維持下去。
  • Pod YAML 的四個核心欄位apiVersionkindmetadataspec,後面的 K8s 資源都是這個結構。

常用指令

指令 說明
kubectl apply -f <file> 套用 YAML
kubectl get pods 看 Pod 列表
kubectl describe pod <name> 看 Pod 詳細狀態和事件
kubectl logs <name> 看 Container log
kubectl exec -it <name> -- bash 進到 Pod 裡面
kubectl delete pod <name> 刪除 Pod

明天會學 Label 和 Selector,它是 K8s 裡元件互相找到對方的機制,也是後續 Deployment 和 Service 的運作基礎 !


上一篇
Day 03|Kubernetes 架構全貌
下一篇
Day 05|Label 和 Selector
系列文
從零學 K8s|30 天核心概念 × 實作,新手也能真正掌握 Kubernetes6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言