|
| 1 | +--- |
| 2 | +layout: blog |
| 3 | +title: 'Kubernetes v1.26: GA Support for Kubelet Credential Providers' |
| 4 | +date: 2022-11-28 |
| 5 | +slug: kubelet-credential-providers |
| 6 | +--- |
| 7 | + |
| 8 | +**Authors:** Andrew Sy Kim (Google), Dixita Narang (Google) |
| 9 | + |
| 10 | +Kubernetes v1.26 introduced generally available (GA) support for _kubelet credential |
| 11 | +provider plugins_, offering an extensible plugin framework to dynamically fetch credentials |
| 12 | +for any container image registry. |
| 13 | + |
| 14 | +## Background |
| 15 | + |
| 16 | +Kubernetes supports the ability to dynamically fetch credentials for a container registry service. |
| 17 | +Prior to Kubernetes v1.20, this capability was compiled into the kubelet and only available for |
| 18 | +Amazon Elastic Container Registry, Azure Container Registry, and Google Cloud Container Registry. |
| 19 | + |
| 20 | +{{< figure src="kubelet-credential-providers-in-tree.png" caption="Figure 1: Kubelet built-in credential provider support for Amazon Elastic Container Registry, Azure Container Registry, and Google Cloud Container Registry." >}} |
| 21 | + |
| 22 | +Kubernetes v1.20 introduced alpha support for kubelet credential providers plugins, |
| 23 | +which provide a mechanism for the kubelet to dynamically authenticate and pull images |
| 24 | +for arbitrary container registries - whether these are public registries, managed services, |
| 25 | +or even a self-hosted registry. |
| 26 | +In Kubernetes v1.26, this feature is now GA |
| 27 | + |
| 28 | +{{< figure src="kubelet-credential-providers-plugin.png" caption="Figure 2: Kubelet credential provider overview" >}} |
| 29 | + |
| 30 | +## Why is it important? |
| 31 | + |
| 32 | +Prior to Kubernetes v1.20, if you wanted to dynamically fetch credentials for image registries |
| 33 | +other than ACR (Azure Container Registry), ECR (Elastic Container Registry), or GCR |
| 34 | +(Google Container Registry), you needed to modify the kubelet code. |
| 35 | +The new plugin mechanism can be used in any cluster, and lets you authenticate to new registries without |
| 36 | +any changes to Kubernetes itself. Any cloud provider or vendor can publish a plugin that lets you authenticate with their image registry. |
| 37 | + |
| 38 | +## How it Works |
| 39 | + |
| 40 | +The kubelet and the credential provider plugin binary communicate through stdio (stdin, stdout, and stderr) by sending and receiving |
| 41 | +json-serialized api-versioned types. If the exec plugin is enabled and the kubelet requires authentication information for an image |
| 42 | +that matches against a plugin, the kubelet will exec the plugin binary, passing the `CredentialProviderRequest` API via stdin. Then |
| 43 | +the exec plugin communicates with the container registry to dynamically fetch the credentials and returns the credentials in an |
| 44 | +encoded response of the `CredentialProviderResponse` API to the kubelet via stdout. |
| 45 | + |
| 46 | +{{< figure src="kubelet-credential-providers-how-it-works.png" caption="Figure 3: Kubelet credential provider plugin flow" >}} |
| 47 | + |
| 48 | +On receiving credentials from the Kubelet, the plugin can also indicate how long credentials can be cached for, to prevent unecessary |
| 49 | +execution of the plugin by the Kubelet for subsequent image pull requests to the same registry. In cases where the cache duration |
| 50 | +is not specified by the plugin, a default cache duration can be specified by the kubelet (more details below). |
| 51 | + |
| 52 | +```json |
| 53 | +{ |
| 54 | + "apiVersion": "kubelet.k8s.io/v1", |
| 55 | + "kind": "CredentialProviderResponse", |
| 56 | + "auth": { |
| 57 | + "cacheDuration": "6h", |
| 58 | + "private-registry.io/my-app": { |
| 59 | + "username": "“user”", |
| 60 | + "password": "“token12345”" |
| 61 | + } |
| 62 | + } |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +In addition, the plugin can specify the scope in which cached credentials are valid for. This is specified through the `cacheKeyType` field |
| 67 | +in `CredentialProviderResponse`. When the value is `Image`, the kubelet will only use cached credentials for future image pulls that exactly |
| 68 | +match the image of the first request. When the value is `Registry`, the kubelet will use cached credentials for any subsequent image pulls |
| 69 | +that originate from the same registry host, but using different paths (e.g. `gcr.io/foo/bar` and `gcr.io/bar/foo` refer to different images |
| 70 | +from the same registry). And lastly, when the value is `Global`, the kubelet will use returned credentials for all images that match against |
| 71 | +the plugin, including images that can map to different registry hosts (e.g. gcr.io vs k8s.gcr.io). The `cacheKeyType` field is required by plugin |
| 72 | +implementations. |
| 73 | + |
| 74 | +```json |
| 75 | +{ |
| 76 | + "apiVersion": "kubelet.k8s.io/v1", |
| 77 | + "kind": "CredentialProviderResponse", |
| 78 | + "auth": { |
| 79 | + "cacheKeyType": "Registry", |
| 80 | + "private-registry.io/my-app": { |
| 81 | + "username": "“user”", |
| 82 | + "password": "“token12345”" |
| 83 | + } |
| 84 | + } |
| 85 | +} |
| 86 | +``` |
| 87 | + |
| 88 | +## Using kubelet credential providers |
| 89 | + |
| 90 | +You can configure credential providers by installing the exec plugin(s) into |
| 91 | +a local directory accessible by the kubelet on every node. Then you set two command line arguments for the kubelet: |
| 92 | +* `--image-credential-provider-config`: the path to the credential provider plugin config file. |
| 93 | +* `--image-credential-provider-bin-dir`: the path to the directory where credential provider plugin binaries are located. |
| 94 | + |
| 95 | +The configuration file passed into `--image-credential-provider-config` is read by the kubelet to determine which exec plugins should be invoked for a container image used by a Pod. |
| 96 | +Note that the name of each "provider" must match the name of the binary located in the local directry specified in `--image-credential-provider-bin-dir`, otherwise the Kubelet |
| 97 | +cannot locate the path of the plugin to invoke. |
| 98 | + |
| 99 | +```yaml |
| 100 | +kind: CredentialProviderConfig |
| 101 | +apiVersion: kubelet.config.k8s.io/v1 |
| 102 | +providers: |
| 103 | +- name: auth-provider-gcp |
| 104 | + apiVersion: credentialprovider.kubelet.k8s.io/v1 |
| 105 | + matchImages: |
| 106 | + - "container.cloud.google.com" |
| 107 | + - "gcr.io" |
| 108 | + - "*.gcr.io" |
| 109 | + - "*.pkg.dev" |
| 110 | + args: |
| 111 | + - get-credentials |
| 112 | + - --v=3 |
| 113 | + defaultCacheDuration: 1m |
| 114 | +``` |
| 115 | +
|
| 116 | +Below is an overview of how the Kubernetes project is using kubelet credential providers for end-to-end testing. |
| 117 | +
|
| 118 | +{{< figure src="kubelet-credential-providers-enabling.png" caption="Figure 4: Kubelet credential provider configuration used for Kubernetes e2e testing" >}} |
| 119 | +
|
| 120 | +For more configuration details, see [Kubelet Credential Providers](https://kubernetes.io/docs/tasks/kubelet-credential-provider/kubelet-credential-provider/). |
| 121 | +
|
| 122 | +## Getting Involved |
| 123 | +
|
| 124 | +Come join SIG Node if you want to report bugs or have feature requests for the Kubelet Credential Provider. You can reach us through the following ways: |
| 125 | +* Slack: [#sig-node](https://kubernetes.slack.com/messages/sig-node) |
| 126 | +* [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-node) |
| 127 | +* [Open Community Issues/PRs](https://github.com/kubernetes/community/labels/sig%2Fnode) |
| 128 | +* [Biweekly meetings](https://github.com/kubernetes/community/tree/master/sig-node#meetings) |
0 commit comments