
POV(示意情境):你把 Day 24 那份 YAML 原封不動 kubectl apply 到 AKS,Pod 卡在 ImagePullBackOff。YAML 裡的 image 沒寫錯,錯的是它指向的 registry 有沒有授權給這個叢集,而那件事不寫在 YAML 裡。
第六週把視線從 GCP 轉到 Azure。先講立場:我同時是 Google Developer Expert 跟 Microsoft MVP,所以這週刻意用「對照」而不是「比較誰好」的角度寫。也先老實說,這週的深度刻意比 GCP 那週淺,能查到官方文件的我查,查不到的不硬掰。
Day 24 的 agent-api 已經在 GKE 上跑起來,Day 27 會把幾乎同一份 YAML 搬去 AKS。要讓「幾乎同一份」成立,今天得先把兩邊的名詞對齊,不然你在 Azure Portal 裡找 GCP 的對應物,會找到懷疑人生。
順便講一個我在 Day 25 提過的小習慣:換平台前先確認你要的功能在那邊存在。我當初評估 Whisper 時,先查各家轉寫 API 有沒有給 word-level 時間戳,沒有的直接排除,省下一輪白工。名詞對照做的是同一件事,只是對象從功能換成概念。
| 你想做的事 | GCP / GKE | Azure / AKS | AI 工程師要知道的差別 |
|---|---|---|---|
| 把資源圈起來一起管、一起刪 | Project(上面還有 folder 與 organization) | Resource Group(上面還有 Subscription) | 兩邊都不是最上層;Resource Group 只是資源容器,刪掉它只會刪裡面的東西,registry 或網路放在別的 Resource Group 就不會跟著走,做實驗前先想清楚放哪 |
| 叢集的大腦 | GKE control plane(代管) | AKS control plane(代管) | 兩邊都不用自己養 |
| 放 Pod 的機器 | node pool;Autopilot 可以完全不管節點 | node pool,分 system pool 與 user pool | 名詞一樣;Autopilot 的對應物是 AKS Automatic,節點由 AKS 代管,我還沒實際用過 |
| 放 image | Artifact Registry | Azure Container Registry(ACR) | 都是 registry,差在授權方式(下一列) |
| 讓叢集有權拉 image | 節點的 service account 有 Artifact Registry 讀取權 | 叢集的 kubelet Managed Identity 拿 ACR 的 AcrPull | 兩邊都是「節點身分」,開頭那個 POV 就卡在這 |
| 讓 Pod 有權讀雲端資源 | Workload Identity Federation 綁 K8s service account | Workload ID 綁 K8s service account | 跟上一列是兩套機制,別混在一起查 |
| 對外開服務 | Service + Ingress,GKE 內建 controller | Service + Ingress,AKS 有 application routing add-on(代管 NGINX) | 標準欄位可攜;ingressClassName 與 annotations 跟 controller 走,要改 |
| 放 secret | Secret Manager | Key Vault,透過 Secrets Store CSI driver 掛進 Pod | 最小集兩邊一樣:先用 K8s 原生 Secret,進階再串雲端的 |
| 不想要 K8s,只想跑容器 | Cloud Run | Azure Container Apps(ACA) | 定位相當:request-driven、scale-to-zero、免管叢集;Day 27 講 ACA 與 AKS 的分界 |
表裡大部分是「名字不同、概念相通」。這篇先聚焦三個最容易卡住的地方,其他列的差異 Day 27 動手時再碰。
一、Identity,而且要分兩層。 拉 image 用的是節點的身分:AKS 上是 kubelet 的 Managed Identity,官方的 AKS 與 ACR 整合就是把 AcrPull 角色給這個身分;GKE 上是節點的 service account 對 Artifact Registry 的讀取權。Pod 自己要讀雲端資源(例如 Key Vault)才是另一套:AKS 的 Workload ID、GKE 的 Workload Identity Federation,都是把雲端身分綁到 K8s 的 service account 上。開頭那個 ImagePullBackOff 查的是第一層,別跑去設第二層。
二、Ingress 的底層。 Ingress 是 K8s 標準物件,rules、defaultBackend 這些標準欄位可以直接搬;但 ingressClassName 跟 annotations 是 controller 專屬的,GKE 內建 controller 直接開 Application Load Balancer,AKS 要嘛用 application routing add-on 拿到代管的 NGINX,要嘛自己裝一個,這些欄位搬過去就要改。另外 Day 24 那份沒加任何設定的 Ingress 在 GKE 上會開外部 LB;AKS 上用 add-on 時預設也是對外,兩邊都可以透過 class 或 annotations 改成內部,不要假設它一定公開或一定私有,apply 前看一眼。
三、Registry 授權。 image 放 ACR 時,AKS 得有拉取權限,這又繞回第一層的 Identity;建叢集時可以直接用 --attach-acr 綁。GCP 那邊,Artifact Registry 官方文件寫明:用預設設定建的 GKE 節點,對同一個 Project 裡的 Artifact Registry 有拉取權;跨 Project 就要另外把讀取角色給節點的 service account。
如果你跟我一樣兩邊都得碰,我的做法是在腦中把「K8s 標準元件」跟「雲端專屬設定」切成兩疊。Deployment、Service、Ingress、Secret、requests / limits 是開源標準,學一次到處用;Identity、Registry 授權、Ingress 實作、託管 Secret 整合是各家自己的,每一邊都要重學,但也就這幾項。
切清楚之後你會發現,跨雲搬遷的技術成本沒有想像中大,擋在前面的常常是心理門檻。明天就實際搬一次:同一個 agent-api 上 AKS 最小集,順便畫 ACA 跟 AKS 的分界線。
AKS 對 GKE,大部分的概念只是換個名字;最先撞到、最值得先重學的是 Identity、Ingress 實作、Registry 授權這三件事,而且它們多半不在 YAML 裡。