From ab5877570252b3dffd86c810ec47bd04aa901107 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Fri, 11 Sep 2020 19:48:37 +0800 Subject: [PATCH] Add secret type documentation --- .../en/docs/concepts/configuration/secret.md | 373 ++++++++++++++++-- 1 file changed, 351 insertions(+), 22 deletions(-) diff --git a/content/en/docs/concepts/configuration/secret.md b/content/en/docs/concepts/configuration/secret.md index 8db4cfa43a..572072dd3e 100644 --- a/content/en/docs/concepts/configuration/secret.md +++ b/content/en/docs/concepts/configuration/secret.md @@ -15,50 +15,379 @@ weight: 30 Kubernetes Secrets let you store and manage sensitive information, such as passwords, OAuth tokens, and ssh keys. Storing confidential information in a Secret is safer and more flexible than putting it verbatim in a -{{< glossary_tooltip term_id="pod" >}} definition or in a {{< glossary_tooltip text="container image" term_id="image" >}}. See [Secrets design document](https://git.k8s.io/community/contributors/design-proposals/auth/secrets.md) for more information. - +{{< glossary_tooltip term_id="pod" >}} definition or in a +{{< glossary_tooltip text="container image" term_id="image" >}}. +See [Secrets design document](https://git.k8s.io/community/contributors/design-proposals/auth/secrets.md) for more information. +A Secret is an object that contains a small amount of sensitive data such as +a password, a token, or a key. Such information might otherwise be put in a +Pod specification or in an image. Users can create Secrets and the system +also creates some Secrets. ## Overview of Secrets -A Secret is an object that contains a small amount of sensitive data such as -a password, a token, or a key. Such information might otherwise be put in a -Pod specification or in an image. Users can create secrets and the system -also creates some secrets. - -To use a secret, a Pod needs to reference the secret. -A secret can be used with a Pod in three ways: +To use a Secret, a Pod needs to reference the Secret. +A Secret can be used with a Pod in three ways: - As [files](#using-secrets-as-files-from-a-pod) in a -{{< glossary_tooltip text="volume" term_id="volume" >}} mounted on one or more of -its containers. + {{< glossary_tooltip text="volume" term_id="volume" >}} mounted on one or more of + its containers. - As [container environment variable](#using-secrets-as-environment-variables). - By the [kubelet when pulling images](#using-imagepullsecrets) for the Pod. The name of a Secret object must be a valid [DNS subdomain name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names). +You can specify the `data` and/or the `stringData` field when creating a +configuration file for a Secret. The `data` and the `stringData` fields are optional. +The values for all keys in the `data` field have to be base64-encoded strings. +If the conversion to base64 string is not desirable, you can choose to specify +the `stringData` field instead, which accepts arbitrary strings as values. The keys of `data` and `stringData` must consist of alphanumeric characters, -`-`, `_` or `.`. +`-`, `_` or `.`. All key-value pairs in the `stringData` field are internally +merged into the `data` field. If a key appears in both the `data` and the +`stringData` field, the value specified in the `stringData` field takes +precedence. -### Built-in Secrets +## Types of Secret {#secret-types} -#### Service accounts automatically create and attach Secrets with API credentials +When creating a Secret, you can specify its type using the `type` field of +the [`Secret`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#secret-v1-core) +resource, or certain equivalent `kubectl` command line flags (if available). +The Secret type is used to facilitate programmatic handling of the Secret data. -Kubernetes automatically creates secrets which contain credentials for -accessing the API and automatically modifies your Pods to use this type of -secret. +Kubernetes provides several builtin types for some common usage scenarios. +These types vary in terms of the validations performed and the constraints +Kubernetes imposes on them. -The automatic creation and use of API credentials can be disabled or overridden -if desired. However, if all you need to do is securely access the API server, -this is the recommended workflow. +| Builtin Type | Usage | +|--------------|-------| +| `Opaque` | arbitrary user-defined data | +| `kubernetes.io/service-account-token` | service account token | +| `kubernetes.io/dockercfg` | serialized `~/.dockercfg` file | +| `kubernetes.io/dockerconfigjson` | serialized `~/.docker/config.json` file | +| `kubernetes.io/basic-auth` | credentials for basic authentication | +| `kubernetes.io/ssh-auth` | credentials for SSH authentication | +| `kubernetes.io/tls` | data for a TLS client or server | +| `bootstrap.kubernetes.io/token` | bootstrap token data | + +You can define and use your own Secret type by assigning a non-empty string as the +`type` value for a Secret object. An empty string is treated as an `Opaque` type. +Kubernetes doesn't impose any constraints on the type name. However, if you +are using one of the builtin types, you must meet all the requirements defined +for that type. + +### Opaque secrets + +`Opaque` is the default Secret type if omitted from a Secret configuration file. +When you create a Secret using `kubectl`, you will use the `generic` +subcommand to indicate an `Opaque` Secret type. For example, the following +command creates an empty Secret of type `Opaque`. + +```shell +kubectl create secret generic empty-secret +kubectl get secret empty-secret +``` + +The output looks like: + +``` +NAME TYPE DATA AGE +empty-secret Opaque 0 2m6s +``` + +The `DATA` column shows the number of data items stored in the Secret. +In this case, `0` means we have just created an empty Secret. + +### Service account token Secrets + +A `kubernetes.io/service-account-token` type of Secret is used to store a +token that identifies a service account. When using this Secret type, you need +to ensure that the `kubernetes.io/service-account.name` annotation is set to an +existing service account name. An Kubernetes controller fills in some other +fields such as the `kubernetes.io/service-account.uid` annotation and the +`token` key in the `data` field set to actual token content. + +The following example configuration declares a service account token Secret: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: secret-sa-sample + annotations: + kubernetes.io/service-account.name: "sa-name" +type: kubernetes.io/service-account-token +data: + # You can include additional key value pairs as you do with Opaque Secrets + extra: YmFyCg== +``` + +When creating a `Pod`, Kubernetes automatically creates a service account Secret +and automatically modifies your Pod to use this Secret. The service account token +Secret contains credentials for accessing the API. + +The automatic creation and use of API credentials can be disabled or +overridden if desired. However, if all you need to do is securely access the +API server, this is the recommended workflow. See the [ServiceAccount](/docs/tasks/configure-pod-container/configure-service-account/) documentation for more information on how service accounts work. +You can also check the `automountServiceAccountToken` field and the +`serviceAccountName` field of the +[`Pod`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#secret-v1-core) +for information on referencing service account from Pods. -### Creating a Secret +### Docker config Secrets + +You can use one of the following `type` values to create a Secret to +store the credentials for accessing a Docker registry for images. + +- `kubernetes.io/dockercfg` +- `kubernetes.io/dockerconfigjson` + +The `kubernetes.io/dockercfg` type is reserved to store a serialized +`~/.dockercfg` which is the legacy format for configuring Docker command line. +When using this Secret type, you have to ensure the Secret `data` field +contains a `.dockercfg` key whose value is content of a `~/.dockercfg` file +encoded in the base64 format. + +The `kubernetes/dockerconfigjson` type is designed for storing a serialized +JSON that follows the same format rules as the `~/.docker/config.json` file +which is a new format for `~/.dockercfg`. +When using this Secret type, the `data` field of the Secret object must +contain a `.dockerconfigjson` key, in which the content for the +`~/.docker/config.json` file is provided as a base64 encoded string. + +Below is an example for a `kubernetes.io/dockercfg` type of Secret: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: secret-dockercfg +type: kubernetes.io/dockercfg +data: + .dockercfg: | + "" +``` + +{{< note >}} +If you do not want to perform the base64 encoding, you can choose to use the +`stringData` field instead. +{{< /note >}} + +When you create these types of Secrets using a manifest, the API +server checks whether the expected key does exists in the `data` field, and +it verifies if the value provided can be parsed as a valid JSON. The API +server doesn't validate if the JSON actually is a Docker config file. + +When you do not have a Docker config file, or you want to use `kubectl` +to create a Docker registry Secret, you can do: + +```shell +kubectl create secret docker-registry secret-tiger-docker \ + --docker-username=tiger \ + --docker-password=pass113 \ + --docker-email=tiger@acme.com +``` + +This command creates a Secret of type `kubernetes.io/dockerconfigjson`. +If you dump the `.dockerconfigjson` content from the `data` field, you will +get the following JSON content which is a valid Docker configuration created +on the fly: + +```json +{ + "auths": { + "https://index.docker.io/v1/": { + "username": "tiger", + "password": "pass113", + "email": "tiger@acme.com", + "auth": "dGlnZXI6cGFzczExMw==" + } + } +} +``` + +### Basic authentication Secret + +The `kubernetes.io/basic-auth` type is provided for storing credentials needed +for basic authentication. When using this Secret type, the `data` field of the +Secret must contain the following two keys: + +- `username`: the user name for authentication; +- `password`: the password or token for authentication. + +Both values for the above two keys are base64 encoded strings. You can, of +course, provide the clear text content using the `stringData` for Secret +creation. + +The following YAML is an example config for a basic authentication Secret: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: secret-basic-auth +type: kubernetes.io/basic-auth +stringData: + username: admin + password: t0p-Secret +``` + +The basic authentication Secret type is provided only for user's convenience. +You can create an `Opaque` for credentials used for basic authentication. +However, using the builtin Secret type helps unify the formats of your credentials +and the API server does verify if the required keys are provided in a Secret +configuration. + +### SSH authentication secrets + +The builtin type `kubernetes.io/ssh-auth` is provided for storing data used in +SSH authentication. When using this Secret type, you will have to specify a +`ssh-privatekey` key-value pair in the `data` (or `stringData`) field. +as the SSH credential to use. + +The following YAML is an example config for a SSH authentication Secret: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: secret-ssh-auth +type: kubernetes.io/ssh-auth +data: + # the data is abbreviated in this example + ssh-privatekey: | + MIIEpQIBAAKCAQEAulqb/Y ... +``` + +The SSH authentication Secret type is provided only for user's convenience. +You can create an `Opaque` for credentials used for SSH authentication. +However, using the builtin Secret type helps unify the formats of your credentials +and the API server does verify if the required keys are provided in a Secret +configuration. + +### TLS secrets + +Kubernetes provides a builtin Secret type `kubernetes.io/tls` for to storing +a certificate and its associated key that are typically used for TLS . This +data is primarily used with TLS termination of the Ingress resource, but may +be used with other resources or directly by a workload. +When using this type of Secret, the `tls.key` and the `tls.crt` key must be provided +in the `data` (or `stringData`) field of the Secret configuration, although the API +server doesn't actually validate the values for each key. + +The following YAML contains an example config for a TLS Secret: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: secret-tls +type: kubernetes.io/tls +data: + # the data is abbreviated in this example + tls.crt: | + MIIC2DCCAcCgAwIBAgIBATANBgkqh ... + tls.key: | + MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ... +``` + +The TLS Secret type is provided for user's convenience. You can create an `Opaque` +for credentials used for TLS server and/or client. However, using the builtin Secret +type helps ensure the consistency of Secret format in your project; the API server +does verify if the required keys are provided in a Secret configuration. + +When creating a TLS Secret using `kubectl`, you can use the `tls` subcommand +as shown in the following example: + +```shell +kubectl create secret tls my-tls-secret \ + --cert=path/to/cert/file \ + --key=path/to/key/file +``` + +The public/private key pair must exist before hand. The public key certificate +for `--cert` must be .PEM encoded (Base64-encoded DER format), and match the +given private key for `--key`. +The private key must be in what is commonly called PEM private key format, +unencrypted. In both cases, the initial and the last lines from PEM (for +example, `--------BEGIN CERTIFICATE-----` and `-------END CERTIFICATE----` for +a cetificate) are *not* included. + +### Bootstrap token Secrets + +A bootstrap token Secret can be created by explicitly specifying the Secret +`type` to `bootstrap.kubernetes.io/token`. This type of Secret is designed for +tokens used during the node bootstrap process. It stores tokens used to sign +well known ConfigMaps. + +A bootstrap token Secret is usually created in the `kube-system` namespace and +named in the form `bootstrap-token-` where `` is a 6 character +string of the token ID. + +As a Kubernetes manifest, a bootstrap token Secret might look like the +following: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: bootstrap-token-5emitj + namespace: kube-system +type: bootstrap.kubernetes.io/token +data: + auth-extra-groups: c3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4= + expiration: MjAyMC0wOS0xM1QwNDozOToxMFo= + token-id: NWVtaXRq + token-secret: a3E0Z2lodnN6emduMXAwcg== + usage-bootstrap-authentication: dHJ1ZQ== + usage-bootstrap-signing: dHJ1ZQ== +``` + +A bootstrap type has the following keys specified under `data`: + +- `token_id`: A random 6 character string as the token identifier. Required. +- `token-secret`: A random 16 character string as the actual token secret. Required. +- `description1`: A human-readable string that describes what the token is + used for. Optional. +- `expiration`: An absolute UTC time using RFC3339 specifying when the token + should be expired. Optional. +- `usage-bootstrap-`: A boolean flag indicating additional usage for + the bootstrap token. +- `auth-extra-groups`: A comma-separated list of group names that will be + authenticated as in addition to system:bootstrappers group. + +The above YAML may look confusing because the values are all in base64 encoded +strings. In fact, you can create an identical Secret using the following YAML +which results in an identical Secret object: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + # Note how the Secret is named + name: bootstrap-token-5emitj + # A bootstrap token Secret usually resides in the kube-system namespace + namespace: kube-system +type: bootstrap.kubernetes.io/token +stringData: + auth-extra-groups: "system:bootstrappers:kubeadm:default-node-token" + expiration: "2020-09-13T04:39:10Z" + # This token ID is used in the name + token-id: "5emitj" + token-secret: "kq4gihvszzgn1p0r" + # This token can be used for authentication + usage-bootstrap-authentication: "true" + # and it can be used for signing + usage-bootstrap-signing: "true" +``` + +## Creating a Secret There are several options to create a Secret: @@ -66,7 +395,7 @@ There are several options to create a Secret: - [create Secret from config file](/docs/tasks/configmap-secret/managing-secret-using-config-file/) - [create Secret using kustomize](/docs/tasks/configmap-secret/managing-secret-using-kustomize/) -### Editing a Secret +## Editing a Secret An existing Secret may be edited with the following command: