Merge pull request #41137 from Adi-ty/docs-secret
A more clear description for commands in working with secrets sectionpull/42040/head
commit
81560e7e89
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
reviewers:
|
reviewers:
|
||||||
- mikedanese
|
- mikedanese
|
||||||
title: Secrets
|
title: Secrets
|
||||||
content_type: concept
|
content_type: concept
|
||||||
feature:
|
feature:
|
||||||
|
@ -56,6 +56,7 @@ See [Information security for Secrets](#information-security-for-secrets) for mo
|
||||||
## Uses for Secrets
|
## Uses for Secrets
|
||||||
|
|
||||||
There are three main ways for a Pod to use a Secret:
|
There are three main ways for a Pod to use a Secret:
|
||||||
|
|
||||||
- As [files](#using-secrets-as-files-from-a-pod) in a
|
- As [files](#using-secrets-as-files-from-a-pod) in a
|
||||||
{{< glossary_tooltip text="volume" term_id="volume" >}} mounted on one or more of
|
{{< glossary_tooltip text="volume" term_id="volume" >}} mounted on one or more of
|
||||||
its containers.
|
its containers.
|
||||||
|
@ -95,6 +96,405 @@ on those short-lived session tokens. Pods running in your cluster can make use o
|
||||||
and operator ensures they are valid. This separation means that you can run Pods that are unaware of
|
and operator ensures they are valid. This separation means that you can run Pods that are unaware of
|
||||||
the exact mechanisms for issuing and refreshing those session tokens.
|
the exact mechanisms for issuing and refreshing those session tokens.
|
||||||
|
|
||||||
|
## Types of Secret {#secret-types}
|
||||||
|
|
||||||
|
When creating a Secret, you can specify its type using the `type` field of
|
||||||
|
the [Secret](/docs/reference/kubernetes-api/config-and-storage-resources/secret-v1/)
|
||||||
|
resource, or certain equivalent `kubectl` command line flags (if available).
|
||||||
|
The Secret type is used to facilitate programmatic handling of the Secret data.
|
||||||
|
|
||||||
|
Kubernetes provides several built-in types for some common usage scenarios.
|
||||||
|
These types vary in terms of the validations performed and the constraints
|
||||||
|
Kubernetes imposes on them.
|
||||||
|
|
||||||
|
| Built-in Type | Usage |
|
||||||
|
| ------------------------------------- | --------------------------------------- |
|
||||||
|
| `Opaque` | arbitrary user-defined data |
|
||||||
|
| `kubernetes.io/service-account-token` | ServiceAccount 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 built-in types, you must meet all the requirements defined
|
||||||
|
for that type.
|
||||||
|
|
||||||
|
If you are defining a type of secret that's for public use, follow the convention
|
||||||
|
and structure the secret type to have your domain name before the name, separated
|
||||||
|
by a `/`. For example: `cloud-hosting.example.net/cloud-api-credentials`.
|
||||||
|
|
||||||
|
### 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 you have created an empty Secret.
|
||||||
|
|
||||||
|
### Service account token Secrets
|
||||||
|
|
||||||
|
A `kubernetes.io/service-account-token` type of Secret is used to store a
|
||||||
|
token credential that identifies a
|
||||||
|
{{< glossary_tooltip text="service account" term_id="service-account" >}}.
|
||||||
|
|
||||||
|
{{< note >}}
|
||||||
|
Versions of Kubernetes before v1.22 automatically created credentials for
|
||||||
|
accessing the Kubernetes API. This older mechanism was based on creating token
|
||||||
|
Secrets that could then be mounted into running Pods.
|
||||||
|
In more recent versions, including Kubernetes v{{< skew currentVersion >}}, API
|
||||||
|
credentials are obtained directly by using the
|
||||||
|
[TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/)
|
||||||
|
API, and are mounted into Pods using a
|
||||||
|
[projected volume](/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume).
|
||||||
|
The tokens obtained using this method have bounded lifetimes, and are
|
||||||
|
automatically invalidated when the Pod they are mounted into is deleted.
|
||||||
|
|
||||||
|
You can still
|
||||||
|
[manually create](/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token)
|
||||||
|
a service account token Secret; for example, if you need a token that never
|
||||||
|
expires. However, using the
|
||||||
|
[TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/)
|
||||||
|
subresource to obtain a token to access the API is recommended instead.
|
||||||
|
You can use the
|
||||||
|
[`kubectl create token`](/docs/reference/generated/kubectl/kubectl-commands#-em-token-em-)
|
||||||
|
command to obtain a token from the `TokenRequest` API.
|
||||||
|
{{< /note >}}
|
||||||
|
|
||||||
|
You should only create a service account token Secret object
|
||||||
|
if you can't use the `TokenRequest` API to obtain a token,
|
||||||
|
and the security exposure of persisting a non-expiring token credential
|
||||||
|
in a readable API object is acceptable to you.
|
||||||
|
|
||||||
|
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. If you are creating both the ServiceAccount and
|
||||||
|
the Secret objects, you should create the ServiceAccount object first.
|
||||||
|
|
||||||
|
After the Secret is created, a Kubernetes {{< glossary_tooltip text="controller" term_id="controller" >}}
|
||||||
|
fills in some other fields such as the `kubernetes.io/service-account.uid` annotation, and the
|
||||||
|
`token` key in the `data` field, which is populated with an authentication token.
|
||||||
|
|
||||||
|
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==
|
||||||
|
```
|
||||||
|
|
||||||
|
After creating the Secret, wait for Kubernetes to populate the `token` key in the `data` field.
|
||||||
|
|
||||||
|
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" >}}/#pod-v1-core)
|
||||||
|
for information on referencing service account credentials from within Pods.
|
||||||
|
|
||||||
|
### Docker config Secrets
|
||||||
|
|
||||||
|
You can use one of the following `type` values to create a Secret to
|
||||||
|
store the credentials for accessing a container image registry:
|
||||||
|
|
||||||
|
- `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.io/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: |
|
||||||
|
"<base64 encoded ~/.dockercfg file>"
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< 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 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 Secret for accessing a container registry, you can do:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl create secret docker-registry secret-tiger-docker \
|
||||||
|
--docker-email=tiger@acme.example \
|
||||||
|
--docker-username=tiger \
|
||||||
|
--docker-password=pass1234 \
|
||||||
|
--docker-server=my-registry.example:5000
|
||||||
|
```
|
||||||
|
|
||||||
|
That command creates a Secret of type `kubernetes.io/dockerconfigjson`.
|
||||||
|
If you dump the `.data.dockerconfigjson` field from that new Secret and then
|
||||||
|
decode it from base64:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl get secret secret-tiger-docker -o jsonpath='{.data.*}' | base64 -d
|
||||||
|
```
|
||||||
|
|
||||||
|
then the output is equivalent to this JSON document (which is also a valid
|
||||||
|
Docker configuration file):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"auths": {
|
||||||
|
"my-registry.example:5000": {
|
||||||
|
"username": "tiger",
|
||||||
|
"password": "pass1234",
|
||||||
|
"email": "tiger@acme.example",
|
||||||
|
"auth": "dGlnZXI6cGFzczEyMzQ="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< note >}}
|
||||||
|
The `auth` value there is base64 encoded; it is obscured but not secret.
|
||||||
|
Anyone who can read that Secret can learn the registry access bearer token.
|
||||||
|
{{< /note >}}
|
||||||
|
|
||||||
|
### 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 one of 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 manifest is an example of a basic authentication Secret:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: secret-basic-auth
|
||||||
|
type: kubernetes.io/basic-auth
|
||||||
|
stringData:
|
||||||
|
username: admin # required field for kubernetes.io/basic-auth
|
||||||
|
password: t0p-Secret # required field for kubernetes.io/basic-auth
|
||||||
|
```
|
||||||
|
|
||||||
|
The basic authentication Secret type is provided only for convenience.
|
||||||
|
You can create an `Opaque` type for credentials used for basic authentication.
|
||||||
|
However, using the defined and public Secret type (`kubernetes.io/basic-auth`) helps other
|
||||||
|
people to understand the purpose of your Secret, and sets a convention for what key names
|
||||||
|
to expect.
|
||||||
|
The Kubernetes API verifies that the required keys are set for a Secret of this type.
|
||||||
|
|
||||||
|
### 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 manifest is an example of a Secret used for SSH public/private
|
||||||
|
key authentication:
|
||||||
|
|
||||||
|
```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 could instead create an `Opaque` type Secret for credentials used for SSH authentication.
|
||||||
|
However, using the defined and public Secret type (`kubernetes.io/ssh-auth`) helps other
|
||||||
|
people to understand the purpose of your Secret, and sets a convention for what key names
|
||||||
|
to expect.
|
||||||
|
and the API server does verify if the required keys are provided in a Secret configuration.
|
||||||
|
|
||||||
|
{{< caution >}}
|
||||||
|
SSH private keys do not establish trusted communication between an SSH client and
|
||||||
|
host server on their own. A secondary means of establishing trust is needed to
|
||||||
|
mitigate "man in the middle" attacks, such as a `known_hosts` file added to a ConfigMap.
|
||||||
|
{{< /caution >}}
|
||||||
|
|
||||||
|
### TLS secrets
|
||||||
|
|
||||||
|
Kubernetes provides a builtin Secret type `kubernetes.io/tls` for storing
|
||||||
|
a certificate and its associated key that are typically used for TLS.
|
||||||
|
|
||||||
|
One common use for TLS secrets is to configure encryption in transit for
|
||||||
|
an [Ingress](/docs/concepts/services-networking/ingress/), but you can also use it
|
||||||
|
with other resources or directly in your 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 DER format as per
|
||||||
|
[Section 5.1 of RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-5.1),
|
||||||
|
and must match the given private key for `--key` (PKCS #8 in DER format;
|
||||||
|
[Section 11 of RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-11)).
|
||||||
|
|
||||||
|
{{< note >}}
|
||||||
|
A kubernetes.io/tls Secret stores the Base64-encoded DER data for keys and
|
||||||
|
certificates. If you're familiar with PEM format for private keys and for certificates,
|
||||||
|
the base64 data are the same as that format except that you omit
|
||||||
|
the initial and the last lines that are used in PEM.
|
||||||
|
|
||||||
|
For example, for a certificate, you do **not** include `--------BEGIN CERTIFICATE-----`
|
||||||
|
and `-------END CERTIFICATE----`.
|
||||||
|
{{< /note >}}
|
||||||
|
|
||||||
|
### 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-<token-id>` where `<token-id>` 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 Secret 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.
|
||||||
|
- `description`: A human-readable string that describes what the token is
|
||||||
|
used for. Optional.
|
||||||
|
- `expiration`: An absolute UTC time using [RFC3339](https://datatracker.ietf.org/doc/html/rfc3339) specifying when the token
|
||||||
|
should be expired. Optional.
|
||||||
|
- `usage-bootstrap-<usage>`: 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 the `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:
|
||||||
|
|
||||||
|
```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"
|
||||||
|
```
|
||||||
|
|
||||||
## Working with Secrets
|
## Working with Secrets
|
||||||
|
|
||||||
### Creating a Secret
|
### Creating a Secret
|
||||||
|
@ -135,8 +535,8 @@ number of Secrets (or other resources) in a namespace.
|
||||||
You can edit an existing Secret unless it is [immutable](#secret-immutable). To
|
You can edit an existing Secret unless it is [immutable](#secret-immutable). To
|
||||||
edit a Secret, use one of the following methods:
|
edit a Secret, use one of the following methods:
|
||||||
|
|
||||||
* [Use `kubectl`](/docs/tasks/configmap-secret/managing-secret-using-kubectl/#edit-secret)
|
- [Use `kubectl`](/docs/tasks/configmap-secret/managing-secret-using-kubectl/#edit-secret)
|
||||||
* [Use a configuration file](/docs/tasks/configmap-secret/managing-secret-using-config-file/#edit-secret)
|
- [Use a configuration file](/docs/tasks/configmap-secret/managing-secret-using-config-file/#edit-secret)
|
||||||
|
|
||||||
You can also edit the data in a Secret using the [Kustomize tool](/docs/tasks/configmap-secret/managing-secret-using-kustomize/#edit-secret). However, this
|
You can also edit the data in a Secret using the [Kustomize tool](/docs/tasks/configmap-secret/managing-secret-using-kustomize/#edit-secret). However, this
|
||||||
method creates a new `Secret` object with the edited data.
|
method creates a new `Secret` object with the edited data.
|
||||||
|
@ -560,406 +960,6 @@ With this partitioned approach, an attacker now has to trick the application
|
||||||
server into doing something rather arbitrary, which may be harder than getting
|
server into doing something rather arbitrary, which may be harder than getting
|
||||||
it to read a file.
|
it to read a file.
|
||||||
|
|
||||||
## Types of Secret {#secret-types}
|
|
||||||
|
|
||||||
When creating a Secret, you can specify its type using the `type` field of
|
|
||||||
the [Secret](/docs/reference/kubernetes-api/config-and-storage-resources/secret-v1/)
|
|
||||||
resource, or certain equivalent `kubectl` command line flags (if available).
|
|
||||||
The Secret type is used to facilitate programmatic handling of the Secret data.
|
|
||||||
|
|
||||||
Kubernetes provides several built-in types for some common usage scenarios.
|
|
||||||
These types vary in terms of the validations performed and the constraints
|
|
||||||
Kubernetes imposes on them.
|
|
||||||
|
|
||||||
| Built-in Type | Usage |
|
|
||||||
|--------------|-------|
|
|
||||||
| `Opaque` | arbitrary user-defined data |
|
|
||||||
| `kubernetes.io/service-account-token` | ServiceAccount 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 built-in types, you must meet all the requirements defined
|
|
||||||
for that type.
|
|
||||||
|
|
||||||
If you are defining a type of secret that's for public use, follow the convention
|
|
||||||
and structure the secret type to have your domain name before the name, separated
|
|
||||||
by a `/`. For example: `cloud-hosting.example.net/cloud-api-credentials`.
|
|
||||||
|
|
||||||
### 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 you have created an empty Secret.
|
|
||||||
|
|
||||||
### Service account token Secrets
|
|
||||||
|
|
||||||
A `kubernetes.io/service-account-token` type of Secret is used to store a
|
|
||||||
token credential that identifies a
|
|
||||||
{{< glossary_tooltip text="service account" term_id="service-account" >}}.
|
|
||||||
|
|
||||||
{{< note >}}
|
|
||||||
Versions of Kubernetes before v1.22 automatically created credentials for
|
|
||||||
accessing the Kubernetes API. This older mechanism was based on creating token
|
|
||||||
Secrets that could then be mounted into running Pods.
|
|
||||||
In more recent versions, including Kubernetes v{{< skew currentVersion >}}, API
|
|
||||||
credentials are obtained directly by using the
|
|
||||||
[TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/)
|
|
||||||
API, and are mounted into Pods using a
|
|
||||||
[projected volume](/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume).
|
|
||||||
The tokens obtained using this method have bounded lifetimes, and are
|
|
||||||
automatically invalidated when the Pod they are mounted into is deleted.
|
|
||||||
|
|
||||||
You can still
|
|
||||||
[manually create](/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token)
|
|
||||||
a service account token Secret; for example, if you need a token that never
|
|
||||||
expires. However, using the
|
|
||||||
[TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/)
|
|
||||||
subresource to obtain a token to access the API is recommended instead.
|
|
||||||
You can use the
|
|
||||||
[`kubectl create token`](/docs/reference/generated/kubectl/kubectl-commands#-em-token-em-)
|
|
||||||
command to obtain a token from the `TokenRequest` API.
|
|
||||||
{{< /note >}}
|
|
||||||
|
|
||||||
You should only create a service account token Secret object
|
|
||||||
if you can't use the `TokenRequest` API to obtain a token,
|
|
||||||
and the security exposure of persisting a non-expiring token credential
|
|
||||||
in a readable API object is acceptable to you.
|
|
||||||
|
|
||||||
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. If you are creating both the ServiceAccount and
|
|
||||||
the Secret objects, you should create the ServiceAccount object first.
|
|
||||||
|
|
||||||
After the Secret is created, a Kubernetes {{< glossary_tooltip text="controller" term_id="controller" >}}
|
|
||||||
fills in some other fields such as the `kubernetes.io/service-account.uid` annotation, and the
|
|
||||||
`token` key in the `data` field, which is populated with an authentication token.
|
|
||||||
|
|
||||||
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==
|
|
||||||
```
|
|
||||||
|
|
||||||
After creating the Secret, wait for Kubernetes to populate the `token` key in the `data` field.
|
|
||||||
|
|
||||||
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" >}}/#pod-v1-core)
|
|
||||||
for information on referencing service account credentials from within Pods.
|
|
||||||
|
|
||||||
### Docker config Secrets
|
|
||||||
|
|
||||||
You can use one of the following `type` values to create a Secret to
|
|
||||||
store the credentials for accessing a container image registry:
|
|
||||||
|
|
||||||
- `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.io/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: |
|
|
||||||
"<base64 encoded ~/.dockercfg file>"
|
|
||||||
```
|
|
||||||
|
|
||||||
{{< 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 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 Secret for accessing a container registry, you can do:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
kubectl create secret docker-registry secret-tiger-docker \
|
|
||||||
--docker-email=tiger@acme.example \
|
|
||||||
--docker-username=tiger \
|
|
||||||
--docker-password=pass1234 \
|
|
||||||
--docker-server=my-registry.example:5000
|
|
||||||
```
|
|
||||||
|
|
||||||
That command creates a Secret of type `kubernetes.io/dockerconfigjson`.
|
|
||||||
If you dump the `.data.dockerconfigjson` field from that new Secret and then
|
|
||||||
decode it from base64:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
kubectl get secret secret-tiger-docker -o jsonpath='{.data.*}' | base64 -d
|
|
||||||
```
|
|
||||||
|
|
||||||
then the output is equivalent to this JSON document (which is also a valid
|
|
||||||
Docker configuration file):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"auths": {
|
|
||||||
"my-registry.example:5000": {
|
|
||||||
"username": "tiger",
|
|
||||||
"password": "pass1234",
|
|
||||||
"email": "tiger@acme.example",
|
|
||||||
"auth": "dGlnZXI6cGFzczEyMzQ="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
{{< note >}}
|
|
||||||
The `auth` value there is base64 encoded; it is obscured but not secret.
|
|
||||||
Anyone who can read that Secret can learn the registry access bearer token.
|
|
||||||
{{< /note >}}
|
|
||||||
|
|
||||||
### 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 one of 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 manifest is an example of a basic authentication Secret:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: secret-basic-auth
|
|
||||||
type: kubernetes.io/basic-auth
|
|
||||||
stringData:
|
|
||||||
username: admin # required field for kubernetes.io/basic-auth
|
|
||||||
password: t0p-Secret # required field for kubernetes.io/basic-auth
|
|
||||||
```
|
|
||||||
|
|
||||||
The basic authentication Secret type is provided only for convenience.
|
|
||||||
You can create an `Opaque` type for credentials used for basic authentication.
|
|
||||||
However, using the defined and public Secret type (`kubernetes.io/basic-auth`) helps other
|
|
||||||
people to understand the purpose of your Secret, and sets a convention for what key names
|
|
||||||
to expect.
|
|
||||||
The Kubernetes API verifies that the required keys are set for a Secret of this type.
|
|
||||||
|
|
||||||
### 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 manifest is an example of a Secret used for SSH public/private
|
|
||||||
key authentication:
|
|
||||||
|
|
||||||
```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 could instead create an `Opaque` type Secret for credentials used for SSH authentication.
|
|
||||||
However, using the defined and public Secret type (`kubernetes.io/ssh-auth`) helps other
|
|
||||||
people to understand the purpose of your Secret, and sets a convention for what key names
|
|
||||||
to expect.
|
|
||||||
and the API server does verify if the required keys are provided in a Secret configuration.
|
|
||||||
|
|
||||||
{{< caution >}}
|
|
||||||
SSH private keys do not establish trusted communication between an SSH client and
|
|
||||||
host server on their own. A secondary means of establishing trust is needed to
|
|
||||||
mitigate "man in the middle" attacks, such as a `known_hosts` file added to a ConfigMap.
|
|
||||||
{{< /caution >}}
|
|
||||||
|
|
||||||
### TLS secrets
|
|
||||||
|
|
||||||
Kubernetes provides a builtin Secret type `kubernetes.io/tls` for storing
|
|
||||||
a certificate and its associated key that are typically used for TLS.
|
|
||||||
|
|
||||||
One common use for TLS secrets is to configure encryption in transit for
|
|
||||||
an [Ingress](/docs/concepts/services-networking/ingress/), but you can also use it
|
|
||||||
with other resources or directly in your 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 DER format as per
|
|
||||||
[Section 5.1 of RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-5.1),
|
|
||||||
and must match the given private key for `--key` (PKCS #8 in DER format;
|
|
||||||
[Section 11 of RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-11)).
|
|
||||||
|
|
||||||
{{< note >}}
|
|
||||||
A kubernetes.io/tls Secret stores the Base64-encoded DER data for keys and
|
|
||||||
certificates. If you're familiar with PEM format for private keys and for certificates,
|
|
||||||
the base64 data are the same as that format except that you omit
|
|
||||||
the initial and the last lines that are used in PEM.
|
|
||||||
|
|
||||||
For example, for a certificate, you do **not** include `--------BEGIN CERTIFICATE-----`
|
|
||||||
and `-------END CERTIFICATE----`.
|
|
||||||
{{< /note >}}
|
|
||||||
|
|
||||||
### 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-<token-id>` where `<token-id>` 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 Secret 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.
|
|
||||||
- `description`: A human-readable string that describes what the token is
|
|
||||||
used for. Optional.
|
|
||||||
- `expiration`: An absolute UTC time using [RFC3339](https://datatracker.ietf.org/doc/html/rfc3339) specifying when the token
|
|
||||||
should be expired. Optional.
|
|
||||||
- `usage-bootstrap-<usage>`: 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 the `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:
|
|
||||||
|
|
||||||
```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"
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Immutable Secrets {#secret-immutable}
|
## Immutable Secrets {#secret-immutable}
|
||||||
|
|
||||||
{{< feature-state for_k8s_version="v1.21" state="stable" >}}
|
{{< feature-state for_k8s_version="v1.21" state="stable" >}}
|
||||||
|
@ -980,10 +980,8 @@ You can create an immutable Secret by setting the `immutable` field to `true`. F
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata: ...
|
||||||
...
|
data: ...
|
||||||
data:
|
|
||||||
...
|
|
||||||
immutable: true
|
immutable: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1035,4 +1033,3 @@ Secrets used on that node.
|
||||||
- Learn how to [manage Secrets using config file](/docs/tasks/configmap-secret/managing-secret-using-config-file/)
|
- Learn how to [manage Secrets using config file](/docs/tasks/configmap-secret/managing-secret-using-config-file/)
|
||||||
- Learn how to [manage Secrets using kustomize](/docs/tasks/configmap-secret/managing-secret-using-kustomize/)
|
- Learn how to [manage Secrets using kustomize](/docs/tasks/configmap-secret/managing-secret-using-kustomize/)
|
||||||
- Read the [API reference](/docs/reference/kubernetes-api/config-and-storage-resources/secret-v1/) for `Secret`
|
- Read the [API reference](/docs/reference/kubernetes-api/config-and-storage-resources/secret-v1/) for `Secret`
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue