配置 kubelet 映象憑證提供程式

功能狀態: Kubernetes v1.26 [stable]

從 Kubernetes v1.20 開始,kubelet 可以使用 exec 外掛動態地檢索容器映象倉庫的憑證。kubelet 和 exec 外掛透過 stdio(stdin、stdout 和 stderr)使用 Kubernetes 版本化 API 進行通訊。這些外掛允許 kubelet 動態請求容器倉庫的憑證,而不是將靜態憑證儲存在磁碟上。例如,外掛可以與本地元資料伺服器通訊,以檢索由 kubelet 拉取的映象的短期憑證。

如果以下任何條件為真,你可能對使用此功能感興趣:

  • 需要呼叫雲提供商服務 API 以檢索登錄檔的身份驗證資訊。
  • 憑證有效期短,需要頻繁請求新憑證。
  • 將登錄檔憑證儲存在磁碟上或 imagePullSecrets 中是不可接受的。

本指南演示瞭如何配置 kubelet 的映象憑證提供程式外掛機制。

用於拉取映象的服務賬號令牌

特性狀態: Kubernetes v1.34 [beta] (預設啟用:true)

從 Kubernetes v1.33 開始,kubelet 可以配置為將繫結到要拉取映象的 Pod 的服務賬號令牌傳送到憑證提供程式外掛。

這允許外掛將令牌換取訪問映象倉庫的憑證。

要啟用此功能,必須在 kubelet 上啟用 `KubeletServiceAccountTokenForCredentialProviders` 特性門控,並且必須在外掛的 `CredentialProviderConfig` 檔案中設定 `tokenAttributes` 欄位。

`tokenAttributes` 欄位包含將傳遞給外掛的服務賬號令牌的資訊,包括令牌的預期受眾以及外掛是否要求 Pod 具有服務賬號。

使用服務賬號令牌憑證可以實現以下用例:

  • 避免需要基於 kubelet/節點的身份才能從登錄檔拉取映象。
  • 允許工作負載根據其自身的執行時身份拉取映象,而無需長期/持久的 Secret。

準備工作

  • 你需要一個具有支援 kubelet 憑證提供程式外掛的節點的 Kubernetes 叢集。此支援在 Kubernetes 1.34 中可用;Kubernetes v1.24 和 v1.25 將此作為 Beta 功能包含在內,預設啟用。
  • 如果你正在配置一個需要服務賬號令牌的憑證提供程式外掛,則需要一個具有執行 Kubernetes v1.33 或更高版本的節點的 Kubernetes 叢集,並且在 kubelet 上啟用了 `KubeletServiceAccountTokenForCredentialProviders` 特性門控。
  • 一個可工作的憑證提供程式 exec 外掛實現。你可以構建自己的外掛或使用雲提供商提供的外掛。
你的 Kubernetes 伺服器版本必須等於或晚於 v1.26。

要檢查版本,請輸入 kubectl version

在節點上安裝外掛

憑證提供程式外掛是 kubelet 將執行的可執行二進位制檔案。確保外掛二進位制檔案存在於叢集中的每個節點上,並存儲在已知目錄中。稍後在配置 kubelet 標誌時將需要該目錄。

配置 kubelet

為了使用此功能,kubelet 需要設定兩個標誌:

  • `--image-credential-provider-config` - 憑證提供程式外掛配置檔案的路徑。
  • `--image-credential-provider-bin-dir` - 憑證提供程式外掛二進位制檔案所在的目錄的路徑。

配置 kubelet 憑證提供程式

傳遞給 `--image-credential-provider-config` 的配置檔案由 kubelet 讀取,以確定哪些容器映象應該呼叫哪些 exec 外掛。如果你正在使用 基於 ECR 的外掛,這有一個你可能最終會使用的配置檔案示例

apiVersion: kubelet.config.k8s.io/v1
kind: CredentialProviderConfig
# providers is a list of credential provider helper plugins that will be enabled by the kubelet.
# Multiple providers may match against a single image, in which case credentials
# from all providers will be returned to the kubelet. If multiple providers are called
# for a single image, the results are combined. If providers return overlapping
# auth keys, the value from the provider earlier in this list is used.
providers:
  # name is the required name of the credential provider. It must match the name of the
  # provider executable as seen by the kubelet. The executable must be in the kubelet's
  # bin directory (set by the --image-credential-provider-bin-dir flag).
  - name: ecr-credential-provider
    # matchImages is a required list of strings used to match against images in order to
    # determine if this provider should be invoked. If one of the strings matches the
    # requested image from the kubelet, the plugin will be invoked and given a chance
    # to provide credentials. Images are expected to contain the registry domain
    # and URL path.
    #
    # Each entry in matchImages is a pattern which can optionally contain a port and a path.
    # Globs can be used in the domain, but not in the port or the path. Globs are supported
    # as subdomains like '*.k8s.io' or 'k8s.*.io', and top-level-domains such as 'k8s.*'.
    # Matching partial subdomains like 'app*.k8s.io' is also supported. Each glob can only match
    # a single subdomain segment, so `*.io` does **not** match `*.k8s.io`.
    #
    # A match exists between an image and a matchImage when all of the below are true:
    # - Both contain the same number of domain parts and each part matches.
    # - The URL path of an matchImages must be a prefix of the target image URL path.
    # - If the matchImages contains a port, then the port must match in the image as well.
    #
    # Example values of matchImages:
    # - 123456789.dkr.ecr.us-east-1.amazonaws.com
    # - *.azurecr.io
    # - gcr.io
    # - *.*.registry.io
    # - registry.io:8080/path
    matchImages:
      - "*.dkr.ecr.*.amazonaws.com"
      - "*.dkr.ecr.*.amazonaws.com.cn"
      - "*.dkr.ecr-fips.*.amazonaws.com"
      - "*.dkr.ecr.us-iso-east-1.c2s.ic.gov"
      - "*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov"
    # defaultCacheDuration is the default duration the plugin will cache credentials in-memory
    # if a cache duration is not provided in the plugin response. This field is required.
    defaultCacheDuration: "12h"
    # Required input version of the exec CredentialProviderRequest. The returned CredentialProviderResponse
    # MUST use the same encoding version as the input. Current supported values are:
    # - credentialprovider.kubelet.k8s.io/v1
    apiVersion: credentialprovider.kubelet.k8s.io/v1
    # Arguments to pass to the command when executing it.
    # +optional
    # args:
    #   - --example-argument
    # Env defines additional environment variables to expose to the process. These
    # are unioned with the host's environment, as well as variables client-go uses
    # to pass argument to the plugin.
    # +optional
    env:
      - name: AWS_PROFILE
        value: example_profile

    # tokenAttributes is the configuration for the service account token that will be passed to the plugin.
    # The credential provider opts in to using service account tokens for image pull by setting this field.
    # if this field is set without the `KubeletServiceAccountTokenForCredentialProviders` feature gate enabled, 
    # kubelet will fail to start with invalid configuration error.
    # +optional
    tokenAttributes:
      # serviceAccountTokenAudience is the intended audience for the projected service account token.
      # +required
      serviceAccountTokenAudience: "<audience for the token>"
      # cacheType indicates the type of cache key use for caching the credentials returned by the plugin
      # when the service account token is used.
      # The most conservative option is to set this to "Token", which means the kubelet will cache
      # returned credentials on a per-token basis. This should be set if the returned credential's
      # lifetime is limited to the service account token's lifetime.
      # If the plugin's credential retrieval logic depends only on the service account and not on
      # pod-specific claims, then the plugin can set this to "ServiceAccount". In this case, the
      # kubelet will cache returned credentials on a per-serviceaccount basis. Use this when the
      # returned credential is valid for all pods using the same service account.
      # +required
      cacheType: "<Token or ServiceAccount>"
      # requireServiceAccount indicates whether the plugin requires the pod to have a service account.
      # If set to true, kubelet will only invoke the plugin if the pod has a service account.
      # If set to false, kubelet will invoke the plugin even if the pod does not have a service account
      # and will not include a token in the CredentialProviderRequest. This is useful for plugins
      # that are used to pull images for pods without service accounts (e.g., static pods).
      # +required
      requireServiceAccount: true
      # requiredServiceAccountAnnotationKeys is the list of annotation keys that the plugin is interested in
      # and that are required to be present in the service account.
      # The keys defined in this list will be extracted from the corresponding service account and passed
      # to the plugin as part of the CredentialProviderRequest. If any of the keys defined in this list
      # are not present in the service account, kubelet will not invoke the plugin and will return an error.
      # This field is optional and may be empty. Plugins may use this field to extract additional information
      # required to fetch credentials or allow workloads to opt in to using service account tokens for image pull.
      # If non-empty, requireServiceAccount must be set to true.
      # The keys defined in this list must be unique and not overlap with the keys defined in the
      # optionalServiceAccountAnnotationKeys list.
      # +optional
      requiredServiceAccountAnnotationKeys:
      - "example.com/required-annotation-key-1"
      - "example.com/required-annotation-key-2"
      # optionalServiceAccountAnnotationKeys is the list of annotation keys that the plugin is interested in
      # and that are optional to be present in the service account.
      # The keys defined in this list will be extracted from the corresponding service account and passed
      # to the plugin as part of the CredentialProviderRequest. The plugin is responsible for validating the
      # existence of annotations and their values. This field is optional and may be empty.
      # Plugins may use this field to extract additional information required to fetch credentials.
      # The keys defined in this list must be unique and not overlap with the keys defined in the
      # requiredServiceAccountAnnotationKeys list.
      # +optional
      optionalServiceAccountAnnotationKeys:
      - "example.com/optional-annotation-key-1"
      - "example.com/optional-annotation-key-2"

`providers` 欄位是 kubelet 使用的已啟用外掛列表。每個條目都有幾個必需欄位:

  • `name`: 外掛的名稱,必須與傳遞給 `--image-credential-provider-bin-dir` 的目錄中存在的二進位制可執行檔案的名稱匹配。
  • `matchImages`: 用於匹配映象以確定是否應呼叫此提供程式的字串列表。詳見下文。
  • `defaultCacheDuration`: 如果外掛未指定快取持續時間,kubelet 將在記憶體中快取憑證的預設持續時間。
  • `apiVersion`: kubelet 和 exec 外掛在通訊時將使用的 API 版本。

每個憑證提供程式還可以獲得可選的引數和環境變數。請諮詢外掛實現者以確定給定外掛所需的引數和環境變數集。

如果你正在使用 `KubeletServiceAccountTokenForCredentialProviders` 特性門控,並透過設定 `tokenAttributes` 欄位將外掛配置為使用服務賬號令牌,則需要以下欄位:

  • `serviceAccountTokenAudience`: 預期投射服務賬號令牌的受眾。這不能是空字串。
  • `cacheType`: 當使用服務賬號令牌時,用於快取外掛返回的憑證的快取鍵型別。最保守的選項是將其設定為 `Token`,這意味著 kubelet 將按令牌快取返回的憑證。如果返回的憑證的生命週期限制為服務賬號令牌的生命週期,則應設定此項。如果外掛的憑證檢索邏輯僅依賴於服務賬號而不依賴於 Pod 特定的宣告,則外掛可以將其設定為 `ServiceAccount`。在這種情況下,kubelet 將按服務賬號快取返回的憑證。當返回的憑證對所有使用相同服務賬號的 Pod 都有效時,請使用此項。
  • `requireServiceAccount`: 外掛是否要求 Pod 具有服務賬號。
    • 如果設定為 `true`,則 kubelet 僅在 Pod 具有服務賬號時才呼叫外掛。
    • 如果設定為 `false`,即使 Pod 沒有服務賬號,kubelet 也會呼叫外掛,並且不會在 `CredentialProviderRequest` 中包含令牌。

這對於用於為沒有服務賬號的 Pod(例如靜態 Pod)拉取映象的外掛很有用。

配置映象匹配

kubelet 使用每個憑證提供程式的 `matchImages` 欄位來確定是否應為 Pod 使用的給定映象呼叫外掛。`matchImages` 中的每個條目都是一個映象模式,可以選擇包含埠和路徑。域中可以使用 glob 模式,但不能在埠或路徑中使用。glob 模式支援子域,如 `*.k8s.io` 或 `k8s.*.io`,以及頂級域,如 `k8s.*`。還支援匹配部分子域,如 `app*.k8s.io`。每個 glob 模式只能匹配一個子域段,因此 `*.io` 不匹配 `*.k8s.io`。

當以下所有條件都為真時,映象名稱和 `matchImage` 條目之間存在匹配:

  • 兩者包含相同數量的域部分,並且每個部分都匹配。
  • 匹配映象的 URL 路徑必須是目標映象 URL 路徑的字首。
  • 如果 `matchImages` 包含埠,則映象中的埠也必須匹配。

`matchImages` 模式的一些示例值是:

  • 123456789.dkr.ecr.us-east-1.amazonaws.com
  • *.azurecr.io
  • gcr.io
  • *.*.registry.io
  • foo.registry.io:8080/path

下一步

上次修改時間:2025 年 6 月 25 日太平洋標準時間上午 9:19:新增 Kubelet 映象憑證提供程式測試版的 PSAT 文件 (a618b01c1a)