到目前為止,我們的 EKS Cluster 已經能跑 Pod、能控制排程,但還有一個大問題:Pod 怎麼取得 AWS 資源的存取權限?
在現實環境裡,許多關鍵元件都需要呼叫 AWS API:
如果沒有正確設定 IAM 權限,這些元件根本跑不起來。傳統做法是把權限綁在 Node IAM Role 上,結果會導致所有 Pod 都共享同一組權限,是個非常不符合最小權限原則的做法。
所以我們需要 IRSA (IAM Role for Service Account):讓 Pod 綁定 ServiceAccount,再透過 OIDC 去 assume IAM Role。這樣每個 Pod 就能拿到自己需要的最小權限。
雖然大部分操作都可以用 kubectl
來完成,但單純看文字輸出有時候會有點空虛。為了方便觀察 Pod 狀態、ServiceAccount annotation 等資訊,我們可以先裝一個圖形化工具 Freelens。
Freelens 是開源的 Lens 分支版本,安裝方式也很簡單:
macOS (Homebrew)
brew install --cask freelens
Windows (Chocolatey)
choco install freelens
Linux (AppImage)
從 FreeLens Release 頁面 下載最新的 AppImage 即可。
安裝好之後,freelens 會自動讀取電腦裡的 kubeconfig,接著就能直接在 GUI 上瀏覽 Pod、ServiceAccount、甚至是 annotation 設定。這樣一來,等下我們介紹 IRSA 的時候,也可以透過 FreeLens 來做截圖輔助。
IRSA 的主要流程如下:
Pod → ServiceAccount → IAM Role → OIDC Provider → AWS Resource
這樣就能把「誰能存取什麼資源」清楚切割開來,避免過度授權。
在我們昨天設置的 terraform-aws-eks
module 裡,只要加上一行設定就能開啟 IRSA:
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_name = var.eks_name
enable_irsa = true
...
}
這一步會自動幫我們建立 OIDC Provider,後續就能建立 IAM Role 綁定 ServiceAccount。
以 VPC CNI 插件為例,它是 DaemonSet (kube-system/aws-node
),跑在每個 Node 上,負責幫 Pod 分配 IP、建立 ENI。如果這個 DaemonSet 長出來的 Pod 沒有 AWS 的相關權限,則這個 cluster 基本上會動不了。Terraform iam-role-for-service-accounts-eks
module 已經內建 VPC CNI 專用的 Policy,我們可以直接採用 module 寫好的 policy:
module "irsa_vpc_cni" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.33.0" # 要注意可能要跟到新版,新版的 module 會配合更新 policy 內容
role_name_prefix = "${var.eks_name}-vpc-cni"
policy_name_prefix = "${var.eks_name}-vpc-cni"
# 直接啟用內建的 VPC CNI Policy
attach_vpc_cni_policy = true
vpc_cni_enable_ipv4 = true
# vpc_cni_enable_ipv6 = true # 如果叢集有 IPv6 再打開
oidc_providers = {
main = {
provider_arn = module.eks.oidc_provider_arn
namespace_service_accounts = ["kube-system:aws-node"]
}
}
}
接著在 EKS module 的 addon 設定裡,把這個 Role 綁到 VPC CNI:
module "eks" {
# ...略
enable_irsa = true
cluster_addons = {
vpc-cni = {
# addon_version 可以固定版本或選 most_recent
service_account_role_arn = module.irsa_vpc_cni.iam_role_arn
}
# 其他 addon ...
}
}
這樣一來,VPC CNI 就會透過 aws-node
ServiceAccount,使用 IRSA 綁定的 IAM Role 去呼叫 AWS API。
檢查 ServiceAccount 是否綁定 IAM Role
$ kubectl -n kube-system describe sa aws-node | grep eks.amazonaws.com/role-arn
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/eks-in-practice-vpc-cniXXXX
應該能看到 annotation 指向剛建立的 IAM Role。如果是用 freelens 的話則可以看到以下的截圖:
檢查 aws-node 日誌
kubectl -n kube-system logs -l k8s-app=aws-node --tail=100
如果沒有 AccessDenied
相關錯誤,代表權限正確生效。
功能測試 (optional)
建立新 Pod 或觸發節點擴容,觀察 Pod 是否能正常分配到新的 IP/ENI。若 ENI 建立成功,就代表 IRSA 正常運作。
最近 AWS 推出了 EKS Pod Identity,這是一種新的方式來讓 Pod 存取 AWS IAM Role,主要是希望簡化 IRSA 的操作與維運。但這個機制是 EKS 專屬,需要部署 Pod Identity Agent,並非 Kubernetes 上游的一部分。
簡單比較:
特性 | IRSA (IAM Roles for Service Accounts) | EKS Pod Identity |
---|---|---|
機制 | Pod → ServiceAccount → OIDC → IAM Role | Pod → Pod Identity Agent → IAM Role |
架構需求 | 啟用 OIDC Provider,靠 SA annotation | 需要額外部署 addon: Pod Identity Agent |
目前 IRSA 並沒有被 deprecated。AWS 官方仍在文件中推薦 IRSA,EKS Pod Identity 算是「新選項」,並非取代品,而是針對 AWS 環境的另一種作法。
細節可以參考我最近剛產出的 Survey 文章!
今天我們介紹了 IAM Role for Service Account (IRSA),並用 VPC CNI 做示範。這個機制讓我們能精準控管「哪個 Pod 可以存取哪個 AWS 資源」,大幅降低了使用 Node IAM Role 時的過度授權風險。
實務上,VPC CNI、EBS CSI Driver、Load Balancer Controller、External DNS 幾乎都必須依賴 IRSA 才能運作。雖然 AWS 推出了 EKS Pod Identity 作為替代方案,但 IRSA 依舊是目前業界標準,短期內沒有被淘汰的跡象。
明天我們會換個步調,來聊聊 Helm Chart 的基本概念。畢竟不管是安裝 infra 元件還是應用服務,Helm 幾乎是繞不開的工具。理解 Chart、Values 和 Release 之間的關係,會讓我們之後在 GitOps 和 Argo CD 的實作更有把握哦!