K8s Pull Image Authentication
整理 Kubernetes 拉取 image 時的 credential provider 與 imagePullSecret 兩種驗證方式、缺點,以及 v1.33 的 Service Account token 方案。
inspired by Kubernetes v1.33: From Secrets to Service Accounts: Kubernetes Image Pulls Evolved
思考脈絡
K8s v1.33 行為變更(WI for image pull)
↓
Argo CD Image Updater 是否會受影響?
↓
誰實際拉 image?
↓
Argo CD 本體會拉 image 嗎?
↓
Kubelet 拉 image 時用什麼認證方式?
↓
我沒設 imagePullSecret → 是用 credential provider?
↓
我用 EKS + ECR + 沒掛 secret,但能拉 image → 那我是在用 Node IAM Role?
ArgoCD Image Updater 更新 image 的步驟
-
查詢 image registry
-
修改 ArgoCD Application 下的 k8s manifest,把 image tag 根據規則改成最新的
-
ArgoCD sync app → 呼叫 K8s API → K8s 產生新的 pod
-
K8s 為新的 pod 建立 container 時,Kubelet 會拉取新的 image。
Pull image 的驗證會在第四步驟發生,根據環境會採用以下其中一種驗證方式:
- 節點的 IAM Role (+ ECR credential helper):會由 credential provider 自動完成
imagePullSecret:由 pod 或他的 ServiceAccount 提供
Pull Image 驗證方式
-
Credential Provider
-
定義:在 AWS 就是 Node IAM role,在其他雲上就會是該雲的權限管理服務
- 節點的 IAM Role(Node IAM Role)
- 搭配 AWS 提供的工具:
amazon-ecr-credential-helper(或更低層的 SDK 認證流程) - 由 Kubelet 在節點上執行,自動取得 ECR token 並完成 image pull
-
運作方式

-
Kubelet 接收到新的 pod spec,啟動流程包括:
- 驗證 volume 是否存在
- 拉取 image
- 啟動 container
-
Kubelet 呼叫 containerd 拉取 image,containerd 嘗試與 registry 認證
-
containerd 偵測到 ECR,觸發 credential provider (
amazon-ecr-credential-helper) 進行驗證📎 docker 或 containerd 可以透過
amazon-ecr-credential-helper來動態取得 login 密碼這個 helper 程式會執行以下步驟:
- 使用 node instance profile 的權限,透過 AWS SDK 執行
ecr:GetAuthorizationToken- 會獲得 base64 encoded token,格式為
user:password
- 會獲得 base64 encoded token,格式為
- credential helper 將回傳資訊解開成 docker login 所需的資訊,並使用這組資訊向 registry 驗證
- 使用 node instance profile 的權限,透過 AWS SDK 執行
-
驗證成功後,image 會被拉取下來,繼續啟動 container
-
-
-
imagePullSecret-
定義:在 pod / deployment 中指定 pull image 時使用的 secret
-
運作方式:

- API server 收到包含
imagePullSecret的 pod spec,將 secret 存入 etcd - Kubelet 接收到新的 pod spec,內容會包含
imagePullSecret - Kubelet 向 API server 請求
imagePullSecret裡面指定的 secret - API server 回傳 base64 encoded docker config json
- Kubelet 呼叫 containerd 透過 docker config json 來登入 registry、並拉取 image
- API server 收到包含
-
💭 這篇文章比較像是 Kaniko ECR connection Issue & debug 心得 的補充說明。在那篇文章 debug 時,有看到許多關於 ecr-credential-helper 和改用 secret 驗證 registry 的解法,這篇文能幫助理解為什麼其他人會提出那些不同的解法
現有兩種驗證方式的缺點 [link]
- Image pull secrets stored in the Kubernetes API
- 這些 secret 通常會比較難 rotate
- 必須要明確的 attach 到某個 service account 或 pod 上
- secret 洩漏會導致未授權的存取
- Kubelet credential providers
- 這些 credential 存在 node level,因此只要在同個節點上的 pod 就會有權限可以 pull image
- 無法以 workload 做區隔,導致安全風險增加
Solution: Service Account Token Integration for Kubelet Credential Providers
- 這個解法的優點
- 依照 workload 切分認證範圍 (workload-specific authentication)
- 每個 pod 會有自己的 service account token
- 得到的憑證會限制 workload 範圍,不會再有同個 node 下的 pod 共享憑證的問題
- 短期憑證 (Ephemeral credential) 降低外洩風險
- 原生整合 Service Account 認證機制
- 依照 workload 切分認證範圍 (workload-specific authentication)
- 運作方式:
- Pod 被建立時,Kubelet 準備拉 image
- Kubelet 確認 Credential Provider 是否有宣告「支援 SA token」
- 若支援,Kubelet 為該 Pod 所使用的 ServiceAccount 產生一組短期 OIDC 格式的 token
- 將此 token 包進
CredentialProviderRequest中,送給 Credential Provider - Credential Provider 使用該 token 對應的 workload 身份進行驗證
- 向外部 Registry(如 ECR / ACR / GCR)換取臨時的 image pull credential(例如 docker login token)
- 將這些 image pull 憑證回傳給 Kubelet