Kubernetes v1.34:用於映象拉取的服務帳戶令牌整合進階至 Beta

Kubernetes 社群透過減少對長期憑證的依賴,持續推進安全最佳實踐。繼 Kubernetes v1.33 中的 Alpha 版本成功釋出後,Kubelet 憑證提供程式的服務賬號令牌整合功能現已在 Kubernetes v1.34 中進入 Beta 階段,這使我們離在 Kubernetes 叢集中消除長期存在的映象拉取 Secret 更近了一步。

此增強功能允許憑證提供程式使用特定於工作負載的服務賬號令牌來獲取映象倉庫憑證,為傳統的映象拉取 Secret 提供了一種安全、臨時的替代方案。

Beta 版本有哪些新功能?

Beta 版本的推出帶來了幾個重要的變化,使該功能更加健壯和生產就緒。

必需的 cacheType 欄位

與 Alpha 版本的重大變更:在使用服務賬號令牌時,憑證提供程式配置中必須包含 cacheType 欄位。該欄位是 Beta 版本中的新增欄位,必須指定以確保正確的快取行為。

# CAUTION: this is not a complete configuration example, just a reference for the 'tokenAttributes.cacheType' field.
tokenAttributes:
  serviceAccountTokenAudience: "my-registry-audience"
  cacheType: "ServiceAccount"  # Required field in beta
  requireServiceAccount: true

選擇兩種快取策略

  • Token:按服務賬號令牌快取憑證(當憑證生命週期與令牌繫結時使用)。當憑證提供程式將服務賬號令牌轉換為與令牌具有相同生命週期的映象倉庫憑證時,或者當映象倉庫直接支援 Kubernetes 服務賬號令牌時,此策略非常有用。注意:kubelet 無法直接將服務賬號令牌傳送到映象倉庫;需要憑證提供程式外掛將令牌轉換為映象倉庫期望的使用者名稱/密碼格式。
  • ServiceAccount:按服務賬號身份快取憑證(當憑證對所有使用相同服務賬號的 Pod 都有效時使用)。

隔離的映象拉取憑證

Beta 版本在使用服務賬號令牌進行映象拉取時,為容器映象提供了更強的安全隔離。它確保 Pod 只能訪問使用其被授權使用的 ServiceAccount 拉取的映象。這可以防止對敏感容器映象的未經授權訪問,並實現精細的訪問控制,使不同的工作負載可以根據其 ServiceAccount 擁有不同的映象倉庫許可權。

當憑證提供程式使用服務賬號令牌時,系統會為每個拉取的映象跟蹤 ServiceAccount 的身份(名稱空間、名稱和 UID)。當一個 Pod 嘗試使用快取的映象時,系統會驗證該 Pod 的 ServiceAccount 與最初用於拉取該映象的 ServiceAccount 完全匹配。

管理員可以透過刪除並重新建立 ServiceAccount 來撤銷對先前拉取映象的訪問,這將更改其 UID 並使快取映象的訪問失效。

有關此功能的更多詳細資訊,請參閱映象拉取憑證驗證文件。

工作原理

配置

憑證提供程式透過配置 tokenAttributes 欄位來選擇使用 ServiceAccount 令牌:

#
# CAUTION: this is an example configuration.
#          Do not use this for your own cluster!
#
apiVersion: kubelet.config.k8s.io/v1
kind: CredentialProviderConfig
providers:
- name: my-credential-provider
  matchImages:
  - "*.myregistry.io/*"
  defaultCacheDuration: "10m"
  apiVersion: credentialprovider.kubelet.k8s.io/v1
  tokenAttributes:
    serviceAccountTokenAudience: "my-registry-audience"
    cacheType: "ServiceAccount"  # New in beta
    requireServiceAccount: true
    requiredServiceAccountAnnotationKeys:
    - "myregistry.io/identity-id"
    optionalServiceAccountAnnotationKeys:
    - "myregistry.io/optional-annotation"

映象拉取流程

從高層次來看,kubelet 與你的憑證提供程式和容器執行時的協作方式如下:

  • 當映象在本地不存在時

    • kubelet 使用配置的 cacheTypeTokenServiceAccount)檢查其憑證快取。
    • 如果需要,kubelet 會為 Pod 的 ServiceAccount 請求一個 ServiceAccount 令牌,並將其連同任何必需的註解一起傳遞給憑證提供程式。
    • 提供程式將該令牌交換為映象倉庫憑證,並將其返回給 kubelet
    • kubelet 根據 cacheType 策略快取憑證,並使用這些憑證拉取映象。
    • kubelet 記錄與所拉取映象關聯的 ServiceAccount 座標(名稱空間、名稱、UID),以供後續授權檢查使用。
  • 當映象已在本地存在時

    • kubelet 驗證 Pod 的 ServiceAccount 座標是否與為快取映象記錄的座標匹配。
    • 如果它們完全匹配,則無需從映象倉庫拉取即可使用快取的映象。
    • 如果它們不同,kubelet 將使用新 ServiceAccount 的憑證執行一次新的拉取。
  • 啟用映象拉取憑證驗證後

    • 授權將使用記錄的 ServiceAccount 座標來強制執行,確保 Pod 只能使用由其被授權使用的 ServiceAccount 拉取的映象。
    • 管理員可以透過刪除並重新建立 ServiceAccount 來撤銷訪問許可權;UID 會發生變化,先前記錄的授權將不再匹配。

受眾限制

Beta 版本建立在服務賬號節點受眾限制(自 v1.33 起為 Beta)的基礎上,以確保 kubelet 只能請求授權受眾的令牌。管理員使用 RBAC 配置允許的受眾,以使 kubelet 能夠請求用於映象拉取的服務賬號令牌。

#
# CAUTION: this is an example configuration.
#          Do not use this for your own cluster!
#
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kubelet-credential-provider-audiences
rules:
- verbs: ["request-serviceaccounts-token-audience"]
  apiGroups: [""]
  resources: ["my-registry-audience"]
  resourceNames: ["registry-access-sa"]  # Optional: specific SA

開始使用 Beta 版本

先決條件

  1. Kubernetes v1.34 或更高版本
  2. 啟用特性門控KubeletServiceAccountTokenForCredentialProviders=true(Beta,預設啟用)
  3. 憑證提供程式支援:更新你的憑證提供程式以處理 ServiceAccount 令牌。

從 Alpha 版本遷移

如果你已經在使用 Alpha 版本,遷移到 Beta 版本只需做少量更改:

  1. 新增 cacheType 欄位:更新你的憑證提供程式配置,以包含必需的 cacheType 欄位。
  2. 檢查快取策略:根據你的提供程式的行為,在 TokenServiceAccount 快取型別之間進行選擇。
  3. 測試受眾限制:確保你的 RBAC 配置或其他叢集授權規則能正確限制令牌受眾。

示例設定

這是一個使用服務賬號令牌設定憑證提供程式的完整示例(此示例假設你的叢集使用 RBAC 授權):

#
# CAUTION: this is an example configuration.
#          Do not use this for your own cluster!
#

# Service Account with registry annotations
apiVersion: v1
kind: ServiceAccount
metadata:
  name: registry-access-sa
  namespace: default
  annotations:
    myregistry.io/identity-id: "user123"
---
# RBAC for audience restriction
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: registry-audience-access
rules:
- verbs: ["request-serviceaccounts-token-audience"]
  apiGroups: [""]
  resources: ["my-registry-audience"]
  resourceNames: ["registry-access-sa"]  # Optional: specific ServiceAccount
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubelet-registry-audience
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: registry-audience-access
subjects:
- kind: Group
  name: system:nodes
  apiGroup: rbac.authorization.k8s.io
---
# Pod using the ServiceAccount
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: registry-access-sa
  containers:
  - name: my-app
    image: myregistry.example/my-app:latest

接下來是什麼?

對於 Kubernetes v1.35,我們——Kubernetes SIG Auth——預計該功能將保持在 Beta 階段,並將繼續徵求反饋。

你可以在 Kubernetes 文件的用於映象拉取的服務賬號令牌頁面上了解有關此功能的更多資訊。

你也可以在 KEP-4412 上關注後續 Kubernetes 版本中的進展。

行動號召

在這篇博文中,我介紹了 Kubernetes v1.34 中 Kubelet 憑證提供程式的服務賬號令牌整合功能進入 Beta 階段的情況。我討論了關鍵改進,包括必需的 cacheType 欄位以及與 Ensure Secret Pull Images 的增強整合。

在 Alpha 階段,我們收到了社群的積極反饋,並希望在我們為 GA 穩定此功能的過程中聽到更多聲音。特別是,我們希望憑證提供程式實現者在與新的 Beta API 和快取機制整合時提供反饋。請透過 Kubernetes Slack 上的 #sig-auth-authenticators-dev 頻道與我們聯絡。

如何參與

如果你有興趣參與此功能的開發、分享反饋或參與任何其他正在進行的 SIG Auth 專案,請透過 Kubernetes Slack 上的 #sig-auth 頻道與我們聯絡。

也歡迎你參加每兩週一次的 SIG Auth 會議,會議在每隔一個星期三舉行。