iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
Cloud Native

EKS in Practice:IaC × GitOps 實戰 30 天系列 第 23

[Day 23] 三大基礎介面:CRI / CNI / CSI 打造 Kubernetes 的積木基座

  • 分享至 

  • xImage
  •  

前言

在 Kubernetes 剛誕生的時候,它的核心目標就已經很明確:負責調度與管理,但不要自己下去做「跑容器、拉網路線、搬磁碟」這些體力活。不過問題馬上出現了:

  • 容器 Runtime:一開始大家都用 Docker,但後來出現了 containerd、CRI-O,甚至各家雲商還想自己搞一套。如果 K8s 每多一個 Runtime 就得改一次程式,維護團隊鐵定會崩潰。
  • 網路:有的環境希望 Pod 直接用 VPC IP,有的環境只能用 Overlay,有人追求簡單,有人追求高效能安全。K8s 不可能只支援一種方案。
  • 存儲:磁碟和檔案系統更是百花齊放,EBS、EFS、Ceph、NFS,各家都有自己的 API。要 K8s 全都寫死在核心,根本不可能。

於是,Kubernetes 團隊做了一個聰明的決定,那就是把這三塊最容易變動、最依賴環境的能力切分出來,設計成三個「標準插槽」:

  • CRI (Container Runtime Interface):誰要負責跑容器?透過 CRI 插槽統一呼叫。
  • CNI (Container Network Interface):誰要幫 Pod 拉網路?用 CNI 插槽替換。
  • CSI (Container Storage Interface):誰要幫 Pod 搬磁碟?交給 CSI 插槽實作。

Kubernetes 自己只專注在「我要一個 Pod」,至於「Pod 裡的容器怎麼跑、怎麼上網、怎麼掛磁碟」,全都交給這三大介面後面的 plugin 來解決。

這也是為什麼今天我們可以在 AWS 上跑 VPC CNI + EBS CSI,換到自建環境又能用 Cilium + Ceph CSI,而 Kubernetes 本身完全不用修改 —— 真正做到可插拔的雲原生平台

接下來,我們就來看看這三個插槽各自負責什麼角色。


CRI:容器要怎麼被跑起來?

在最初期的 Kubernetes,大家都是用 Docker 來跑容器。但隨著時間發展,Kubernetes 不想被某一個特定 Runtime 綁死 —— 於是設計了 CRI (Container Runtime Interface),讓不同的 Runtime 都能插進來,實現一樣的功能。

CRI 解決的問題是

  • Kubernetes API Server 只會下指令:「我要一個 Pod,裡面有三個容器。」
  • 真正要把容器建起來,交給 Runtime(例如 containerd)。
  • CRI 定義了一個通用 API,讓 Kubelet 可以跟不同 Runtime 溝通,而不用知道每個 Runtime 的細節。

常見的 Runtime

  • containerd:目前最主流,EKS、GKE 都採用它。
  • CRI-O:專門為 Kubernetes 打造,OpenShift 預設使用。
  • Docker (dockershim):已經被移除,因為它不是完全符合 CRI 的介面,需要額外 shim。

👉 實際案例

當我們在 EKS 下 kubectl apply -f nginx.yaml,其實流程是這樣:

  1. Kubelet 收到「跑一個 nginx Pod」的請求。
  2. 透過 CRI 呼叫 containerd。
  3. containerd 去拉 image、建 namespace、建立容器。
  4. Pod 最後出現在 Node 上。

所以 CRI 是 Kubernetes 跟「容器工人」之間的溝通語言。


CNI:Pod 要怎麼彼此連線?

有了容器,下一個問題是:這些容器要怎麼彼此連線?

光是建立 Pod 還不夠,如果 Pod 之間沒有網路,就像蓋了一堆房子卻沒拉網路線。

這就是 CNI (Container Network Interface) 的角色:它負責在 Pod 啟動的時候,自動幫 Pod 插上網卡、分配 IP、設定路由。

CNI 解決的問題是

  • Pod 要有一個獨立的 IP,才能在叢集內被找到。
  • Pod 之間要能互通,還要能跟外部世界交談。
  • 網路策略(誰能連誰,誰不能)也需要統一入口控制。

常見的 CNI Plugin

  • Amazon VPC CNI:EKS 預設,Pod 直接拿 VPC IP,看起來就像 EC2。
  • Calico:老牌方案,以路由和 iptables 為主,支援 NetworkPolicy。
  • Flannel:最簡單的 overlay 網路,用 VXLAN 封包包起來。
  • Cilium:新一代解法,基於 eBPF,提供高效能封包處理與進階安全策略。

👉 實際案例

假設你有兩個 Pod:

  • Pod A: 10.0.1.5
  • Pod B: 10.0.2.8

當 Pod A 要連 Pod B:

  1. CNI 在建立 Pod 時,給它一個虛擬網卡與 IP。
  2. 在 Node 的路由表 / iptables / eBPF rule 中,寫下對應規則。
  3. 封包就能找到正確的目的地。

如果沒有 CNI,Pod 雖然啟動了,但你會發現它沒有 IP,什麼網路都不能用。


CSI:Pod 的資料要存去哪裡?

最後一個問題是:資料要怎麼存?

容器是短命的,Pod 被刪掉後,裡面的檔案也會消失。但我們不可能讓資料庫每次重啟就歸零,所以需要一個方式讓 Pod 可以掛載持久化儲存。

這就是 CSI (Container Storage Interface)

CSI 解決的問題是

  • Kubernetes 不自己管理磁碟,而是交給外部 Storage Provider。
  • CSI 提供一個標準 API,讓不同儲存系統都能被掛進 Pod。

常見的 CSI Plugin

  • Amazon EBS CSI Driver:適合單一 Node 使用的磁碟(像 MySQL)。
  • Amazon EFS CSI Driver:提供共享檔案系統,適合多個 Pod 同時讀寫(像 WordPress)。
  • Ceph/Rook:開源分散式儲存,許多私有雲環境會採用。

👉 實際案例:建立一個 PVC 時,會有以下的設定:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

背後 CSI Driver 會幫你在 AWS 建一顆 EBS Volume,並自動掛到運行這個 Pod 的 Node 上,Pod 就能把資料寫進去,即使重啟也不會消失。


總結:Pod 啟動完整流程(CRI × CNI × CSI 串起來)

   kubectl apply
        │
        ▼
     Kubelet
        │
        ▼
       CRI   → 建立容器 (containerd / CRI-O)
        │
        ▼
       CNI   → 分配 IP、插上網卡、設定路由
        │
        ▼
       CSI   → (若有 PVC) 掛載持久化存儲
        │
        ▼
       Pod   → 容器可運行、有網路、有存儲

這張圖可以幫助理解:

  • CRI 先讓容器活過來。
  • CNI 幫容器插上網路線,拿到 IP。
  • CSI 幫容器接上磁碟,能持久化資料。

三者合力,才讓 Pod 真正「能工作」。


明日預告

今天我們認識了 CRI / CNI / CSI 這三個 Kubernetes 的核心介面,分別負責容器的運行、網路的建立與存儲的掛載。它們就像三根支柱,讓 Kubernetes 能真正支撐起應用運行的需求。

接下來的安排會是:

  • Day 24–25:先拆解 Kubernetes 網路通訊原理,從 Pod ↔ Pod 到 Service / Ingress,理解封包是如何流動的。
  • Day 26–27:進一步探討 Cilium,看看它如何利用 eBPF 改進原生 CNI 的限制,並帶來更強大的網路能力。
  • Day 28:最後再介紹 Istio,了解 Service Mesh 如何在網路基礎之上,提供更進階的流量治理與可觀察性。

這樣的脈絡能幫助我們由下而上,從基礎到進階,逐步建立對 Kubernetes 網路的完整認知 🚀


上一篇
[Day 22] 安全通道:Transit Gateway 與 GitLab Runner 串接的秘密
系列文
EKS in Practice:IaC × GitOps 實戰 30 天23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言