Kubernetes 是什麼:從「跑容器」到「宣告你要的狀態」
· tech
很多人學 Kubernetes(K8s)覺得難,是因為一上來就被 kubectl、一堆 YAML 欄位、幾十種資源名詞淹沒。但其實 K8s 只有一個核心觀念,抓住它,後面全部都是同一句話的變形。這個系列就從這個觀念開始 —— 宣告式的期望狀態,加上一個不斷把現實拉過去的 reconcile loop。
先問:它到底解決什麼問題
假設你已經會用 Docker,手上有一個容器化的服務。上線時你會發現一堆麻煩事:
- 容器掛了,誰自動重啟它?
- 流量變大,誰多開幾個、流量小又收回來?
- 某台機器整台壞了,上面的容器搬去哪?
- 要出新版,怎麼不中斷服務滾動更新、出包了怎麼回滾?
手動一個個 docker run、壞了 SSH 上去救,幾台還行,幾十台就是災難。K8s 就是那個幫你顧容器的「容器編排器」 —— 把「一堆容器要跑在一堆機器上、還要活著、要擴縮、要換版」這件事自動化。
核心觀念:宣告期望,讓它自己收斂
但 K8s 真正聰明的地方,不是「功能多」,而是它達成這些的方式。你不會去下「重啟這個容器」「在那台機器開一個」這種一步步的指令;你只宣告你想要的最終狀態,K8s 自己想辦法達成、而且持續維持:
這個 reconcile loop 就是整個 K8s 的靈魂。 之後你會遇到的 Deployment、Service、每一種資源,背後都是同一件事:你宣告一個期望,某個 controller 不斷地把現實拉過去。這個系列每一篇,我都會回扣這句話。
命令式 vs 宣告式:為什麼這個差別很重要
換個角度看這個轉變:
| 命令式(過去) | 宣告式(K8s) | |
|---|---|---|
| 你做什麼 | 下一步步的指令:開這個、停那個 | 描述想要的結果:我要 3 個、跑這版 |
| 誰維持狀態 | 你(壞了要自己救) | 系統(自動收斂、自我修復) |
| 可重複 | 難(指令有先後、有副作用) | 冪等(套幾次結果一樣) |
| 能版控嗎 | 難 | 可以:一份 YAML 就是你的期望 |
宣告式最大的紅利,是你的「期望」變成一份可以版控的檔案。整個叢集該長什麼樣,寫在 Git 裡、能 review、能回溯 —— 這就是 GitOps 的基礎。
一份最小的「期望」長這樣:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3 # 我要 3 個
selector:
matchLabels: { app: web }
template:
metadata:
labels: { app: web }
spec:
containers:
- name: web
image: myrepo/web:1.0 # 跑這個映像檔
然後 kubectl apply -f web.yaml。你沒有叫它「開三個容器」,你只說「我要 3 個 web:1.0」—— 剩下的交給 reconcile loop。
叢集長什麼樣:大腦與工人
那「Controller 不斷收斂」這件事發生在哪?K8s 叢集分成兩半:
- Control Plane(大腦):
kubectl apply送到唯一入口 API Server;Scheduler 決定新 pod 排到哪台;Controller Manager 跑那些 reconcile loop;etcd 存下整個叢集的狀態。 - Worker Node(工人):真正跑你 Pod 的機器,每台一個 kubelet 負責照顧本機的 pod。
這些元件的細節不用現在背 —— Pod、Node、Scheduler 是下一篇的主角。這篇你只要先把那個迴圈刻進腦子。
反思
K8s 難,常常是因為學的順序反了
我看很多人(包括當年的我)學 K8s 是從 API 背起 —— 背 kubectl 指令、背 YAML 欄位、背一堆資源類型,結果學得很痛、又串不起來。後來我才想通:應該先抓住那個 reconcile loop,再回頭看每個資源。 一旦你知道「所有東西都是:你宣告期望、controller 把現實拉過去」,那些看似無關的名詞——Deployment、ReplicaSet、Service、HPA——瞬間都變成同一個模式的不同套用。先有心智模型,細節才掛得上去,這跟我讀 資料工程生命週期的體會一模一樣。
「宣告式 + 版控」是我最欣賞 K8s 的地方
真正讓我覺得 K8s 漂亮的,不是它能自動重啟容器,而是它把「叢集該長什麼樣」變成一份可版控的檔案。整個系統的期望狀態寫在 Git 裡、能 review、能回溯、能一鍵重建 —— 這跟 dbt 把資料轉換變成版控程式碼、是同一種工程紀律的勝利:把「會變的東西」從人的腦袋與臨時操作裡,搬進可追蹤的宣告。 命令式的世界靠「某個人記得怎麼救」,宣告式的世界靠「一份大家都看得到的期望」。
但別為了潮而上 K8s
最後照例潑冷水:K8s 很強,但它本身是一座要人維運的大山。服務還只有一兩個、團隊也沒有 K8s 底子時,硬上只是把「顧容器」的麻煩換成「顧容器 + 顧 K8s」的雙倍麻煩。我的順位一直是 先確認痛點,再上重武器:先問「我是不是真的多到、雜到需要一個編排器」,再決定要不要走進這座山。看懂它的價值,和判斷自己該不該用它,是兩件事 —— 這個系列幫你做到前者,後者的判斷還是得回到你的痛點。