iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Kubernetes

從零到一:使用 K8S + GitOps 打造異構技術棧的資料分析平台系列 第 8

[Day 8] K8S 入門:Deployment, Service 與 Namespace 的配置策略 —— 建立 K8S 基礎資源,規劃服務間的通訊路徑。

  • 分享至 

  • xImage
  •  

Day 8: K8S 入門:Deployment, Service 與 Namespace 的配置策略

建立 K8S 基礎資源,規劃服務間的通訊路徑。

開場先來個冷知識:Kubernetes 這個字有 10 個字母,K-u-b-e-r-n-e-t-e-s,掐頭(K)去尾(s)之後,中間剩下 8 個字母——「K」+「8」+「s」,K8S 的縮寫就是這樣來的,跟 i18n(internationalization,中間也是 18 個字母被縮成 18)是同一種命名套路,這種縮寫方式叫做 numeronym。今天正好是系列的 第 8 天,咱們就來講 K8S。

1. 為什麼需要 Kubernetes?

Day 7 我們用 Docker Compose 把整套系統在本機跑起來了,很爽。但生產環境呢?容器半夜掛了誰重啟?流量暴增誰擴容?節點掛掉服務要搬家怎麼辦?

這就是 Kubernetes (K8S) 登場的時刻。K8S 是容器編排的霸主,幫我們管理容器的生老病死。今天先在本機的 Docker Desktop K8S 練功(對,Docker Desktop 內建一個單節點叢集,練習超方便),Day 9 來聊聊「要不要現在就上雲」這個問題。

2. Docker Compose vs K8S:不是升級版,是不同量級的工具

在動手寫 K8S 的 YAML 之前,先把 Day 7 用的 Docker Compose 跟 K8S 放在一起比一比,不然直接跳資源定義會覺得莫名其妙——為什麼同一件事,K8S 要拆成好幾個檔案寫?

本質上的差異:Docker Compose 是單機的容器編排——所有服務都在同一台機器上,這台機器掛了,整套系統就跟著掛。K8S 是叢集的容器編排——服務可以分散在多台節點上,某個節點掛了,K8S 會把上面的 Pod 重新排程到其他節點,這也是 Day 8 稍後會實測的自癒能力,Compose 完全沒有這個概念。

寫法對照:Compose 把「這個服務要跑什麼 image、怎麼連網路、環境變數、要跑幾個」全部塞進同一個 services.<name> 區塊;K8S 把這些職責拆成好幾種獨立資源,各司其職:

Docker Compose 概念 K8S 對應資源 差異重點
services.<name>(一個區塊全包) Deployment K8S 把「怎麼跑」單獨拆成一個資源,管的是 Pod 的生命週期與副本數
image: / build: spec.containers[].image Compose 可以直接 build: 本機 Dockerfile;K8S 只吃已經 push 上 registry 的 image,不會幫你現場 build
ports:(host:container 直接打通) Service(ClusterIP/NodePort)+ containerPort Pod 的 IP 是動態的(重啟就換),K8S 多了 Service 這層穩定的「門牌」抽象,Compose 靠固定的容器名稱不用煩惱這件事
environment: env:envFrom: configMapRef / secretRef 概念相同(都是塞環境變數),但 K8S 多了 ConfigMap/Secret 這種獨立資源,可以被多個 Deployment 共用同一份設定
depends_on: condition: service_healthy 通常沒有原生對應,得用 initContainers 手動等 Compose 有內建的啟動順序控制;K8S 傾向讓服務自己有重試邏輯,或額外寫一個 initContainer 輪詢依賴服務(例如用 nc -z postgres-service 5432 等資料庫先就緒)
healthcheck: livenessProbe + readinessProbe Compose 只有一種健康檢查;K8S 拆成兩種語意——壞了要不要重啟(liveness)、好了沒可以導流量嗎(readiness),Day 14 會細講
.env 檔案 ConfigMap(非機密)/ Secret(機密) Compose 用一個 .env 檔案混著放所有變數;K8S 明確拆開,Secret 至少會 base64 編碼、能做存取控制(Day 13 會講這還不夠安全的地方)
docker compose up kubectl apply -f Compose 是「執行一次,啟動整個 stack」;K8S 的 apply 是「宣告期望狀態」,叢集會持續背景 reconcile——這就是為什麼等一下砍掉 Pod,K8S 會自動補回來,Compose 沒有這種行為

哪些東西是共用的:不是砍掉重練,很多 Day 3~5 已經做好的東西直接搬過來就能用:

  • Dockerfile 完全共用——K8S 跑的就是同一批 image,不用為了上 K8S 另外寫一份 Dockerfile,這也是為什麼容器化要先做(Day 3~5),K8S 化才有東西可以部署
  • 環境變數的「名字」共用——POSTGRES_HOSTJWT_SECRET 這些 key 兩邊都一樣,差別只在「怎麼餵進去」(Compose 用 .env,K8S 用 ConfigMap/Secret)
  • 服務間呼叫的心智模型共用——Compose 靠容器名稱當 DNS(http://postgres:5432),K8S 靠 Service 名稱當 DNS(http://wafer-backend-svc:8000),「用名字互相找對方」這個概念完全沒變,只是底層機制從 Compose 的內建網路換成 K8S 的 Service。

搞懂這張對照表,接下來的 Namespace、Deployment、Service 就不是三個憑空冒出來的新名詞,而是把 Compose 那個「一個檔案全包」的區塊,拆成三塊各自負責的積木。

3. Namespace:環境隔離的結界

我們定義了 k8sdemo 這個 Namespace,把 Wafer BI 的所有資源與其他系統隔開,避免名稱衝突與權限越界:

apiVersion: v1
kind: Namespace
metadata:
  name: k8sdemo

4. Deployment:確保服務永不掉線

k8s/base/wafer-bi-deployment.yaml 中定義後端的 Deployment(簡化版):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wafer-backend
  namespace: k8sdemo
spec:
  replicas: 2  # 隨時維持兩個實例,高可用
  selector:
    matchLabels:
      app: wafer-backend
  template:
    metadata:
      labels:
        app: wafer-backend
    spec:
      containers:
      - name: backend
        image: wafer-bi-backend:ironman
        ports:
        - containerPort: 8000
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"
          limits:
            memory: "512Mi"
            cpu: "500m"

resources 區塊先埋個伏筆:requests 是跟 K8S「預訂」的資源,limits 是天花板,Day 28 效能調優會深入。

還有一件事現在看不出來、但之後會很重要:改掉 image 那行再 apply 一次,K8S 不會把兩個 Pod 全砍了重開,而是一個一個換(先起新的、確認健康、再關舊的),這叫滾動更新 (Rolling Update),是 Deployment 的預設行為。換得多快、中途容許少幾個 Pod、換壞了怎麼退回去——Day 20 專門講這件事。

5. Service:微服務間的通訊橋樑

Pod 的 IP 是會變的(重啟就換一個),所以需要 Service 提供固定的門牌:

apiVersion: v1
kind: Service
metadata:
  name: wafer-backend-svc
  namespace: k8sdemo
spec:
  selector:
    app: wafer-backend
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000
  type: ClusterIP

這樣 API Gateway 只要呼叫 http://wafer-backend-svc:8000 就能穩定找到後端,Service 還自帶負載均衡。

6. 實測:部署 + 刪 Pod 看它自己復活

紙上談兵不如實際跑一次。apply 之後兩個 Pod 順利 Running,接著做一件壞壞的事——手動刪掉其中一個 Pod:

https://ithelp.ithome.com.tw/upload/images/20260810/20182549qvmgZcHl1o.png

▲ kubectl apply 部署、刪除 Pod 後 2 秒 K8S 自動補新 Pod

看最後一段:刪掉 9pn9b 之後兩秒內,K8S 就補上了新的 Pod m9nxq(AGE 2s)。這就是 Deployment 的自癒能力——它的職責是「讓現實世界永遠符合你聲明的期望狀態 (Desired State)」,你說要 2 個,它就想辦法永遠維持 2 個。

第一次親手刪 Pod 看它復活的時候,真的會忍不住多刪幾次(誤)。

7. 小結

Namespace、Deployment、Service 是 K8S 的三塊基石。本機練功告一段落,接下來就要面對「這套東西要跑在哪裡」的問題。

雲端選項很多,這個系列不做橫向比較——我當初挑的是 Oracle Cloud (OCI),理由很單純:它的 Always Free 方案給的免費額度在同類服務裡算大方,看起來很適合拿來跑一個練習用的叢集。明天就來記錄實際去開這座叢集的過程,以及「免費額度」這四個字在真正動手時的樣子。


上一篇
[Day 7] 本地開發:使用 Docker Compose 模擬微服務環境 —— 在開發機上一鍵啟動整套異構系統的技巧。
下一篇
[Day 9] 雲端評估:Always Free 額度的真實限制,以及我們決定先留在本機的理由 —— 免費不等於沒有代價,這篇記錄一次評估雲端部署、最後決定暫緩的完整過程。
系列文
從零到一:使用 K8S + GitOps 打造異構技術棧的資料分析平台17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言