mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-16 22:53:22 +00:00
address issue #1488; clean up linewrap and some minor editing issues in the docs/design/* tree
Signed-off-by: mikebrow <brownwm@us.ibm.com>
This commit is contained in:
@@ -34,15 +34,17 @@ Documentation for other releases can be found at
|
||||
|
||||
## Abstract
|
||||
|
||||
A proposal for the distribution of [secrets](../user-guide/secrets.md) (passwords, keys, etc) to the Kubelet and to
|
||||
containers inside Kubernetes using a custom [volume](../user-guide/volumes.md#secrets) type. See the [secrets example](../user-guide/secrets/) for more information.
|
||||
A proposal for the distribution of [secrets](../user-guide/secrets.md)
|
||||
(passwords, keys, etc) to the Kubelet and to containers inside Kubernetes using
|
||||
a custom [volume](../user-guide/volumes.md#secrets) type. See the
|
||||
[secrets example](../user-guide/secrets/) for more information.
|
||||
|
||||
## Motivation
|
||||
|
||||
Secrets are needed in containers to access internal resources like the Kubernetes master or
|
||||
external resources such as git repositories, databases, etc. Users may also want behaviors in the
|
||||
kubelet that depend on secret data (credentials for image pull from a docker registry) associated
|
||||
with pods.
|
||||
Secrets are needed in containers to access internal resources like the
|
||||
Kubernetes master or external resources such as git repositories, databases,
|
||||
etc. Users may also want behaviors in the kubelet that depend on secret data
|
||||
(credentials for image pull from a docker registry) associated with pods.
|
||||
|
||||
Goals of this design:
|
||||
|
||||
@@ -52,114 +54,127 @@ Goals of this design:
|
||||
|
||||
## Constraints and Assumptions
|
||||
|
||||
* This design does not prescribe a method for storing secrets; storage of secrets should be
|
||||
pluggable to accommodate different use-cases
|
||||
* This design does not prescribe a method for storing secrets; storage of
|
||||
secrets should be pluggable to accommodate different use-cases
|
||||
* Encryption of secret data and node security are orthogonal concerns
|
||||
* It is assumed that node and master are secure and that compromising their security could also
|
||||
compromise secrets:
|
||||
* If a node is compromised, the only secrets that could potentially be exposed should be the
|
||||
secrets belonging to containers scheduled onto it
|
||||
* It is assumed that node and master are secure and that compromising their
|
||||
security could also compromise secrets:
|
||||
* If a node is compromised, the only secrets that could potentially be
|
||||
exposed should be the secrets belonging to containers scheduled onto it
|
||||
* If the master is compromised, all secrets in the cluster may be exposed
|
||||
* Secret rotation is an orthogonal concern, but it should be facilitated by this proposal
|
||||
* A user who can consume a secret in a container can know the value of the secret; secrets must
|
||||
be provisioned judiciously
|
||||
* Secret rotation is an orthogonal concern, but it should be facilitated by
|
||||
this proposal
|
||||
* A user who can consume a secret in a container can know the value of the
|
||||
secret; secrets must be provisioned judiciously
|
||||
|
||||
## Use Cases
|
||||
|
||||
1. As a user, I want to store secret artifacts for my applications and consume them securely in
|
||||
containers, so that I can keep the configuration for my applications separate from the images
|
||||
that use them:
|
||||
1. As a cluster operator, I want to allow a pod to access the Kubernetes master using a custom
|
||||
`.kubeconfig` file, so that I can securely reach the master
|
||||
2. As a cluster operator, I want to allow a pod to access a Docker registry using credentials
|
||||
from a `.dockercfg` file, so that containers can push images
|
||||
3. As a cluster operator, I want to allow a pod to access a git repository using SSH keys,
|
||||
so that I can push to and fetch from the repository
|
||||
2. As a user, I want to allow containers to consume supplemental information about services such
|
||||
as username and password which should be kept secret, so that I can share secrets about a
|
||||
service amongst the containers in my application securely
|
||||
3. As a user, I want to associate a pod with a `ServiceAccount` that consumes a secret and have
|
||||
the kubelet implement some reserved behaviors based on the types of secrets the service account
|
||||
consumes:
|
||||
1. As a user, I want to store secret artifacts for my applications and consume
|
||||
them securely in containers, so that I can keep the configuration for my
|
||||
applications separate from the images that use them:
|
||||
1. As a cluster operator, I want to allow a pod to access the Kubernetes
|
||||
master using a custom `.kubeconfig` file, so that I can securely reach the
|
||||
master
|
||||
2. As a cluster operator, I want to allow a pod to access a Docker registry
|
||||
using credentials from a `.dockercfg` file, so that containers can push images
|
||||
3. As a cluster operator, I want to allow a pod to access a git repository
|
||||
using SSH keys, so that I can push to and fetch from the repository
|
||||
2. As a user, I want to allow containers to consume supplemental information
|
||||
about services such as username and password which should be kept secret, so
|
||||
that I can share secrets about a service amongst the containers in my
|
||||
application securely
|
||||
3. As a user, I want to associate a pod with a `ServiceAccount` that consumes a
|
||||
secret and have the kubelet implement some reserved behaviors based on the types
|
||||
of secrets the service account consumes:
|
||||
1. Use credentials for a docker registry to pull the pod's docker image
|
||||
2. Present Kubernetes auth token to the pod or transparently decorate traffic between the pod
|
||||
and master service
|
||||
4. As a user, I want to be able to indicate that a secret expires and for that secret's value to
|
||||
be rotated once it expires, so that the system can help me follow good practices
|
||||
2. Present Kubernetes auth token to the pod or transparently decorate
|
||||
traffic between the pod and master service
|
||||
4. As a user, I want to be able to indicate that a secret expires and for that
|
||||
secret's value to be rotated once it expires, so that the system can help me
|
||||
follow good practices
|
||||
|
||||
### Use-Case: Configuration artifacts
|
||||
|
||||
Many configuration files contain secrets intermixed with other configuration information. For
|
||||
example, a user's application may contain a properties file than contains database credentials,
|
||||
SaaS API tokens, etc. Users should be able to consume configuration artifacts in their containers
|
||||
and be able to control the path on the container's filesystems where the artifact will be
|
||||
presented.
|
||||
Many configuration files contain secrets intermixed with other configuration
|
||||
information. For example, a user's application may contain a properties file
|
||||
than contains database credentials, SaaS API tokens, etc. Users should be able
|
||||
to consume configuration artifacts in their containers and be able to control
|
||||
the path on the container's filesystems where the artifact will be presented.
|
||||
|
||||
### Use-Case: Metadata about services
|
||||
|
||||
Most pieces of information about how to use a service are secrets. For example, a service that
|
||||
provides a MySQL database needs to provide the username, password, and database name to consumers
|
||||
so that they can authenticate and use the correct database. Containers in pods consuming the MySQL
|
||||
service would also consume the secrets associated with the MySQL service.
|
||||
Most pieces of information about how to use a service are secrets. For example,
|
||||
a service that provides a MySQL database needs to provide the username,
|
||||
password, and database name to consumers so that they can authenticate and use
|
||||
the correct database. Containers in pods consuming the MySQL service would also
|
||||
consume the secrets associated with the MySQL service.
|
||||
|
||||
### Use-Case: Secrets associated with service accounts
|
||||
|
||||
[Service Accounts](service_accounts.md) are proposed as a
|
||||
mechanism to decouple capabilities and security contexts from individual human users. A
|
||||
`ServiceAccount` contains references to some number of secrets. A `Pod` can specify that it is
|
||||
associated with a `ServiceAccount`. Secrets should have a `Type` field to allow the Kubelet and
|
||||
other system components to take action based on the secret's type.
|
||||
[Service Accounts](service_accounts.md) are proposed as a mechanism to decouple
|
||||
capabilities and security contexts from individual human users. A
|
||||
`ServiceAccount` contains references to some number of secrets. A `Pod` can
|
||||
specify that it is associated with a `ServiceAccount`. Secrets should have a
|
||||
`Type` field to allow the Kubelet and other system components to take action
|
||||
based on the secret's type.
|
||||
|
||||
#### Example: service account consumes auth token secret
|
||||
|
||||
As an example, the service account proposal discusses service accounts consuming secrets which
|
||||
contain Kubernetes auth tokens. When a Kubelet starts a pod associated with a service account
|
||||
which consumes this type of secret, the Kubelet may take a number of actions:
|
||||
As an example, the service account proposal discusses service accounts consuming
|
||||
secrets which contain Kubernetes auth tokens. When a Kubelet starts a pod
|
||||
associated with a service account which consumes this type of secret, the
|
||||
Kubelet may take a number of actions:
|
||||
|
||||
1. Expose the secret in a `.kubernetes_auth` file in a well-known location in the container's
|
||||
file system
|
||||
2. Configure that node's `kube-proxy` to decorate HTTP requests from that pod to the
|
||||
`kubernetes-master` service with the auth token, e. g. by adding a header to the request
|
||||
(see the [LOAS Daemon](http://issue.k8s.io/2209) proposal)
|
||||
1. Expose the secret in a `.kubernetes_auth` file in a well-known location in
|
||||
the container's file system
|
||||
2. Configure that node's `kube-proxy` to decorate HTTP requests from that pod
|
||||
to the `kubernetes-master` service with the auth token, e. g. by adding a header
|
||||
to the request (see the [LOAS Daemon](http://issue.k8s.io/2209) proposal)
|
||||
|
||||
#### Example: service account consumes docker registry credentials
|
||||
|
||||
Another example use case is where a pod is associated with a secret containing docker registry
|
||||
credentials. The Kubelet could use these credentials for the docker pull to retrieve the image.
|
||||
Another example use case is where a pod is associated with a secret containing
|
||||
docker registry credentials. The Kubelet could use these credentials for the
|
||||
docker pull to retrieve the image.
|
||||
|
||||
### Use-Case: Secret expiry and rotation
|
||||
|
||||
Rotation is considered a good practice for many types of secret data. It should be possible to
|
||||
express that a secret has an expiry date; this would make it possible to implement a system
|
||||
component that could regenerate expired secrets. As an example, consider a component that rotates
|
||||
expired secrets. The rotator could periodically regenerate the values for expired secrets of
|
||||
common types and update their expiry dates.
|
||||
Rotation is considered a good practice for many types of secret data. It should
|
||||
be possible to express that a secret has an expiry date; this would make it
|
||||
possible to implement a system component that could regenerate expired secrets.
|
||||
As an example, consider a component that rotates expired secrets. The rotator
|
||||
could periodically regenerate the values for expired secrets of common types and
|
||||
update their expiry dates.
|
||||
|
||||
## Deferral: Consuming secrets as environment variables
|
||||
|
||||
Some images will expect to receive configuration items as environment variables instead of files.
|
||||
We should consider what the best way to allow this is; there are a few different options:
|
||||
Some images will expect to receive configuration items as environment variables
|
||||
instead of files. We should consider what the best way to allow this is; there
|
||||
are a few different options:
|
||||
|
||||
1. Force the user to adapt files into environment variables. Users can store secrets that need to
|
||||
be presented as environment variables in a format that is easy to consume from a shell:
|
||||
1. Force the user to adapt files into environment variables. Users can store
|
||||
secrets that need to be presented as environment variables in a format that is
|
||||
easy to consume from a shell:
|
||||
|
||||
$ cat /etc/secrets/my-secret.txt
|
||||
export MY_SECRET_ENV=MY_SECRET_VALUE
|
||||
|
||||
The user could `source` the file at `/etc/secrets/my-secret` prior to executing the command for
|
||||
the image either inline in the command or in an init script,
|
||||
The user could `source` the file at `/etc/secrets/my-secret` prior to
|
||||
executing the command for the image either inline in the command or in an init
|
||||
script.
|
||||
|
||||
2. Give secrets an attribute that allows users to express the intent that the platform should
|
||||
generate the above syntax in the file used to present a secret. The user could consume these
|
||||
files in the same manner as the above option.
|
||||
2. Give secrets an attribute that allows users to express the intent that the
|
||||
platform should generate the above syntax in the file used to present a secret.
|
||||
The user could consume these files in the same manner as the above option.
|
||||
|
||||
3. Give secrets attributes that allow the user to express that the secret should be presented to
|
||||
the container as an environment variable. The container's environment would contain the
|
||||
desired values and the software in the container could use them without accommodation the
|
||||
command or setup script.
|
||||
3. Give secrets attributes that allow the user to express that the secret
|
||||
should be presented to the container as an environment variable. The container's
|
||||
environment would contain the desired values and the software in the container
|
||||
could use them without accommodation the command or setup script.
|
||||
|
||||
For our initial work, we will treat all secrets as files to narrow the problem space. There will
|
||||
be a future proposal that handles exposing secrets as environment variables.
|
||||
For our initial work, we will treat all secrets as files to narrow the problem
|
||||
space. There will be a future proposal that handles exposing secrets as
|
||||
environment variables.
|
||||
|
||||
## Flow analysis of secret data with respect to the API server
|
||||
|
||||
@@ -170,17 +185,19 @@ There are two fundamentally different use-cases for access to secrets:
|
||||
|
||||
### Use-Case: CRUD operations by owners
|
||||
|
||||
In use cases for CRUD operations, the user experience for secrets should be no different than for
|
||||
other API resources.
|
||||
In use cases for CRUD operations, the user experience for secrets should be no
|
||||
different than for other API resources.
|
||||
|
||||
#### Data store backing the REST API
|
||||
|
||||
The data store backing the REST API should be pluggable because different cluster operators will
|
||||
have different preferences for the central store of secret data. Some possibilities for storage:
|
||||
The data store backing the REST API should be pluggable because different
|
||||
cluster operators will have different preferences for the central store of
|
||||
secret data. Some possibilities for storage:
|
||||
|
||||
1. An etcd collection alongside the storage for other API resources
|
||||
2. A collocated [HSM](http://en.wikipedia.org/wiki/Hardware_security_module)
|
||||
3. A secrets server like [Vault](https://www.vaultproject.io/) or [Keywhiz](https://square.github.io/keywhiz/)
|
||||
3. A secrets server like [Vault](https://www.vaultproject.io/) or
|
||||
[Keywhiz](https://square.github.io/keywhiz/)
|
||||
4. An external datastore such as an external etcd, RDBMS, etc.
|
||||
|
||||
#### Size limit for secrets
|
||||
@@ -188,101 +205,116 @@ have different preferences for the central store of secret data. Some possibili
|
||||
There should be a size limit for secrets in order to:
|
||||
|
||||
1. Prevent DOS attacks against the API server
|
||||
2. Allow kubelet implementations that prevent secret data from touching the node's filesystem
|
||||
2. Allow kubelet implementations that prevent secret data from touching the
|
||||
node's filesystem
|
||||
|
||||
The size limit should satisfy the following conditions:
|
||||
|
||||
1. Large enough to store common artifact types (encryption keypairs, certificates, small
|
||||
configuration files)
|
||||
2. Small enough to avoid large impact on node resource consumption (storage, RAM for tmpfs, etc)
|
||||
1. Large enough to store common artifact types (encryption keypairs,
|
||||
certificates, small configuration files)
|
||||
2. Small enough to avoid large impact on node resource consumption (storage,
|
||||
RAM for tmpfs, etc)
|
||||
|
||||
To begin discussion, we propose an initial value for this size limit of **1MB**.
|
||||
|
||||
#### Other limitations on secrets
|
||||
|
||||
Defining a policy for limitations on how a secret may be referenced by another API resource and how
|
||||
constraints should be applied throughout the cluster is tricky due to the number of variables
|
||||
involved:
|
||||
Defining a policy for limitations on how a secret may be referenced by another
|
||||
API resource and how constraints should be applied throughout the cluster is
|
||||
tricky due to the number of variables involved:
|
||||
|
||||
1. Should there be a maximum number of secrets a pod can reference via a volume?
|
||||
1. Should there be a maximum number of secrets a pod can reference via a
|
||||
volume?
|
||||
2. Should there be a maximum number of secrets a service account can reference?
|
||||
3. Should there be a total maximum number of secrets a pod can reference via its own spec and its
|
||||
associated service account?
|
||||
4. Should there be a total size limit on the amount of secret data consumed by a pod?
|
||||
3. Should there be a total maximum number of secrets a pod can reference via
|
||||
its own spec and its associated service account?
|
||||
4. Should there be a total size limit on the amount of secret data consumed by
|
||||
a pod?
|
||||
5. How will cluster operators want to be able to configure these limits?
|
||||
6. How will these limits impact API server validations?
|
||||
7. How will these limits affect scheduling?
|
||||
|
||||
For now, we will not implement validations around these limits. Cluster operators will decide how
|
||||
much node storage is allocated to secrets. It will be the operator's responsibility to ensure that
|
||||
the allocated storage is sufficient for the workload scheduled onto a node.
|
||||
For now, we will not implement validations around these limits. Cluster
|
||||
operators will decide how much node storage is allocated to secrets. It will be
|
||||
the operator's responsibility to ensure that the allocated storage is sufficient
|
||||
for the workload scheduled onto a node.
|
||||
|
||||
For now, kubelets will only attach secrets to api-sourced pods, and not file- or http-sourced
|
||||
ones. Doing so would:
|
||||
For now, kubelets will only attach secrets to api-sourced pods, and not file-
|
||||
or http-sourced ones. Doing so would:
|
||||
- confuse the secrets admission controller in the case of mirror pods.
|
||||
- create an apiserver-liveness dependency -- avoiding this dependency is a main reason to use non-api-source pods.
|
||||
- create an apiserver-liveness dependency -- avoiding this dependency is a
|
||||
main reason to use non-api-source pods.
|
||||
|
||||
### Use-Case: Kubelet read of secrets for node
|
||||
|
||||
The use-case where the kubelet reads secrets has several additional requirements:
|
||||
|
||||
1. Kubelets should only be able to receive secret data which is required by pods scheduled onto
|
||||
the kubelet's node
|
||||
1. Kubelets should only be able to receive secret data which is required by
|
||||
pods scheduled onto the kubelet's node
|
||||
2. Kubelets should have read-only access to secret data
|
||||
3. Secret data should not be transmitted over the wire insecurely
|
||||
4. Kubelets must ensure pods do not have access to each other's secrets
|
||||
|
||||
#### Read of secret data by the Kubelet
|
||||
|
||||
The Kubelet should only be allowed to read secrets which are consumed by pods scheduled onto that
|
||||
Kubelet's node and their associated service accounts. Authorization of the Kubelet to read this
|
||||
data would be delegated to an authorization plugin and associated policy rule.
|
||||
The Kubelet should only be allowed to read secrets which are consumed by pods
|
||||
scheduled onto that Kubelet's node and their associated service accounts.
|
||||
Authorization of the Kubelet to read this data would be delegated to an
|
||||
authorization plugin and associated policy rule.
|
||||
|
||||
#### Secret data on the node: data at rest
|
||||
|
||||
Consideration must be given to whether secret data should be allowed to be at rest on the node:
|
||||
Consideration must be given to whether secret data should be allowed to be at
|
||||
rest on the node:
|
||||
|
||||
1. If secret data is not allowed to be at rest, the size of secret data becomes another draw on
|
||||
the node's RAM - should it affect scheduling?
|
||||
1. If secret data is not allowed to be at rest, the size of secret data becomes
|
||||
another draw on the node's RAM - should it affect scheduling?
|
||||
2. If secret data is allowed to be at rest, should it be encrypted?
|
||||
1. If so, how should be this be done?
|
||||
2. If not, what threats exist? What types of secret are appropriate to store this way?
|
||||
2. If not, what threats exist? What types of secret are appropriate to
|
||||
store this way?
|
||||
|
||||
For the sake of limiting complexity, we propose that initially secret data should not be allowed
|
||||
to be at rest on a node; secret data should be stored on a node-level tmpfs filesystem. This
|
||||
filesystem can be subdivided into directories for use by the kubelet and by the volume plugin.
|
||||
For the sake of limiting complexity, we propose that initially secret data
|
||||
should not be allowed to be at rest on a node; secret data should be stored on a
|
||||
node-level tmpfs filesystem. This filesystem can be subdivided into directories
|
||||
for use by the kubelet and by the volume plugin.
|
||||
|
||||
#### Secret data on the node: resource consumption
|
||||
|
||||
The Kubelet will be responsible for creating the per-node tmpfs file system for secret storage.
|
||||
It is hard to make a prescriptive declaration about how much storage is appropriate to reserve for
|
||||
secrets because different installations will vary widely in available resources, desired pod to
|
||||
node density, overcommit policy, and other operation dimensions. That being the case, we propose
|
||||
for simplicity that the amount of secret storage be controlled by a new parameter to the kubelet
|
||||
with a default value of **64MB**. It is the cluster operator's responsibility to handle choosing
|
||||
the right storage size for their installation and configuring their Kubelets correctly.
|
||||
The Kubelet will be responsible for creating the per-node tmpfs file system for
|
||||
secret storage. It is hard to make a prescriptive declaration about how much
|
||||
storage is appropriate to reserve for secrets because different installations
|
||||
will vary widely in available resources, desired pod to node density, overcommit
|
||||
policy, and other operation dimensions. That being the case, we propose for
|
||||
simplicity that the amount of secret storage be controlled by a new parameter to
|
||||
the kubelet with a default value of **64MB**. It is the cluster operator's
|
||||
responsibility to handle choosing the right storage size for their installation
|
||||
and configuring their Kubelets correctly.
|
||||
|
||||
Configuring each Kubelet is not the ideal story for operator experience; it is more intuitive that
|
||||
the cluster-wide storage size be readable from a central configuration store like the one proposed
|
||||
in [#1553](http://issue.k8s.io/1553). When such a store
|
||||
exists, the Kubelet could be modified to read this configuration item from the store.
|
||||
Configuring each Kubelet is not the ideal story for operator experience; it is
|
||||
more intuitive that the cluster-wide storage size be readable from a central
|
||||
configuration store like the one proposed in [#1553](http://issue.k8s.io/1553).
|
||||
When such a store exists, the Kubelet could be modified to read this
|
||||
configuration item from the store.
|
||||
|
||||
When the Kubelet is modified to advertise node resources (as proposed in
|
||||
[#4441](http://issue.k8s.io/4441)), the capacity calculation
|
||||
for available memory should factor in the potential size of the node-level tmpfs in order to avoid
|
||||
memory overcommit on the node.
|
||||
for available memory should factor in the potential size of the node-level tmpfs
|
||||
in order to avoid memory overcommit on the node.
|
||||
|
||||
#### Secret data on the node: isolation
|
||||
|
||||
Every pod will have a [security context](security_context.md).
|
||||
Secret data on the node should be isolated according to the security context of the container. The
|
||||
Kubelet volume plugin API will be changed so that a volume plugin receives the security context of
|
||||
a volume along with the volume spec. This will allow volume plugins to implement setting the
|
||||
security context of volumes they manage.
|
||||
Secret data on the node should be isolated according to the security context of
|
||||
the container. The Kubelet volume plugin API will be changed so that a volume
|
||||
plugin receives the security context of a volume along with the volume spec.
|
||||
This will allow volume plugins to implement setting the security context of
|
||||
volumes they manage.
|
||||
|
||||
## Community work
|
||||
|
||||
Several proposals / upstream patches are notable as background for this proposal:
|
||||
Several proposals / upstream patches are notable as background for this
|
||||
proposal:
|
||||
|
||||
1. [Docker vault proposal](https://github.com/docker/docker/issues/10310)
|
||||
2. [Specification for image/container standardization based on volumes](https://github.com/docker/docker/issues/9277)
|
||||
@@ -292,14 +324,15 @@ Several proposals / upstream patches are notable as background for this proposal
|
||||
|
||||
## Proposed Design
|
||||
|
||||
We propose a new `Secret` resource which is mounted into containers with a new volume type. Secret
|
||||
volumes will be handled by a volume plugin that does the actual work of fetching the secret and
|
||||
storing it. Secrets contain multiple pieces of data that are presented as different files within
|
||||
the secret volume (example: SSH key pair).
|
||||
We propose a new `Secret` resource which is mounted into containers with a new
|
||||
volume type. Secret volumes will be handled by a volume plugin that does the
|
||||
actual work of fetching the secret and storing it. Secrets contain multiple
|
||||
pieces of data that are presented as different files within the secret volume
|
||||
(example: SSH key pair).
|
||||
|
||||
In order to remove the burden from the end user in specifying every file that a secret consists of,
|
||||
it should be possible to mount all files provided by a secret with a single `VolumeMount` entry
|
||||
in the container specification.
|
||||
In order to remove the burden from the end user in specifying every file that a
|
||||
secret consists of, it should be possible to mount all files provided by a
|
||||
secret with a single `VolumeMount` entry in the container specification.
|
||||
|
||||
### Secret API Resource
|
||||
|
||||
@@ -331,27 +364,30 @@ const (
|
||||
const MaxSecretSize = 1 * 1024 * 1024
|
||||
```
|
||||
|
||||
A Secret can declare a type in order to provide type information to system components that work
|
||||
with secrets. The default type is `opaque`, which represents arbitrary user-owned data.
|
||||
A Secret can declare a type in order to provide type information to system
|
||||
components that work with secrets. The default type is `opaque`, which
|
||||
represents arbitrary user-owned data.
|
||||
|
||||
Secrets are validated against `MaxSecretSize`. The keys in the `Data` field must be valid DNS
|
||||
subdomains.
|
||||
Secrets are validated against `MaxSecretSize`. The keys in the `Data` field must
|
||||
be valid DNS subdomains.
|
||||
|
||||
A new REST API and registry interface will be added to accompany the `Secret` resource. The
|
||||
default implementation of the registry will store `Secret` information in etcd. Future registry
|
||||
implementations could store the `TypeMeta` and `ObjectMeta` fields in etcd and store the secret
|
||||
data in another data store entirely, or store the whole object in another data store.
|
||||
A new REST API and registry interface will be added to accompany the `Secret`
|
||||
resource. The default implementation of the registry will store `Secret`
|
||||
information in etcd. Future registry implementations could store the `TypeMeta`
|
||||
and `ObjectMeta` fields in etcd and store the secret data in another data store
|
||||
entirely, or store the whole object in another data store.
|
||||
|
||||
#### Other validations related to secrets
|
||||
|
||||
Initially there will be no validations for the number of secrets a pod references, or the number of
|
||||
secrets that can be associated with a service account. These may be added in the future as the
|
||||
finer points of secrets and resource allocation are fleshed out.
|
||||
Initially there will be no validations for the number of secrets a pod
|
||||
references, or the number of secrets that can be associated with a service
|
||||
account. These may be added in the future as the finer points of secrets and
|
||||
resource allocation are fleshed out.
|
||||
|
||||
### Secret Volume Source
|
||||
|
||||
A new `SecretSource` type of volume source will be added to the `VolumeSource` struct in the
|
||||
API:
|
||||
A new `SecretSource` type of volume source will be added to the `VolumeSource`
|
||||
struct in the API:
|
||||
|
||||
```go
|
||||
type VolumeSource struct {
|
||||
@@ -366,19 +402,21 @@ type SecretSource struct {
|
||||
}
|
||||
```
|
||||
|
||||
Secret volume sources are validated to ensure that the specified object reference actually points
|
||||
to an object of type `Secret`.
|
||||
Secret volume sources are validated to ensure that the specified object
|
||||
reference actually points to an object of type `Secret`.
|
||||
|
||||
In the future, the `SecretSource` will be extended to allow:
|
||||
|
||||
1. Fine-grained control over which pieces of secret data are exposed in the volume
|
||||
1. Fine-grained control over which pieces of secret data are exposed in the
|
||||
volume
|
||||
2. The paths and filenames for how secret data are exposed
|
||||
|
||||
### Secret Volume Plugin
|
||||
|
||||
A new Kubelet volume plugin will be added to handle volumes with a secret source. This plugin will
|
||||
require access to the API server to retrieve secret data and therefore the volume `Host` interface
|
||||
will have to change to expose a client interface:
|
||||
A new Kubelet volume plugin will be added to handle volumes with a secret
|
||||
source. This plugin will require access to the API server to retrieve secret
|
||||
data and therefore the volume `Host` interface will have to change to expose a
|
||||
client interface:
|
||||
|
||||
```go
|
||||
type Host interface {
|
||||
@@ -394,36 +432,42 @@ The secret volume plugin will be responsible for:
|
||||
1. Returning a `volume.Mounter` implementation from `NewMounter` that:
|
||||
1. Retrieves the secret data for the volume from the API server
|
||||
2. Places the secret data onto the container's filesystem
|
||||
3. Sets the correct security attributes for the volume based on the pod's `SecurityContext`
|
||||
2. Returning a `volume.Unmounter` implementation from `NewUnmounter` that cleans the volume from the
|
||||
container's filesystem
|
||||
3. Sets the correct security attributes for the volume based on the pod's
|
||||
`SecurityContext`
|
||||
2. Returning a `volume.Unmounter` implementation from `NewUnmounter` that
|
||||
cleans the volume from the container's filesystem
|
||||
|
||||
### Kubelet: Node-level secret storage
|
||||
|
||||
The Kubelet must be modified to accept a new parameter for the secret storage size and to create
|
||||
a tmpfs file system of that size to store secret data. Rough accounting of specific changes:
|
||||
The Kubelet must be modified to accept a new parameter for the secret storage
|
||||
size and to create a tmpfs file system of that size to store secret data. Rough
|
||||
accounting of specific changes:
|
||||
|
||||
1. The Kubelet should have a new field added called `secretStorageSize`; units are megabytes
|
||||
1. The Kubelet should have a new field added called `secretStorageSize`; units
|
||||
are megabytes
|
||||
2. `NewMainKubelet` should accept a value for secret storage size
|
||||
3. The Kubelet server should have a new flag added for secret storage size
|
||||
4. The Kubelet's `setupDataDirs` method should be changed to create the secret storage
|
||||
4. The Kubelet's `setupDataDirs` method should be changed to create the secret
|
||||
storage
|
||||
|
||||
### Kubelet: New behaviors for secrets associated with service accounts
|
||||
|
||||
For use-cases where the Kubelet's behavior is affected by the secrets associated with a pod's
|
||||
`ServiceAccount`, the Kubelet will need to be changed. For example, if secrets of type
|
||||
`docker-reg-auth` affect how the pod's images are pulled, the Kubelet will need to be changed
|
||||
to accommodate this. Subsequent proposals can address this on a type-by-type basis.
|
||||
For use-cases where the Kubelet's behavior is affected by the secrets associated
|
||||
with a pod's `ServiceAccount`, the Kubelet will need to be changed. For example,
|
||||
if secrets of type `docker-reg-auth` affect how the pod's images are pulled, the
|
||||
Kubelet will need to be changed to accommodate this. Subsequent proposals can
|
||||
address this on a type-by-type basis.
|
||||
|
||||
## Examples
|
||||
|
||||
For clarity, let's examine some detailed examples of some common use-cases in terms of the
|
||||
suggested changes. All of these examples are assumed to be created in a namespace called
|
||||
`example`.
|
||||
For clarity, let's examine some detailed examples of some common use-cases in
|
||||
terms of the suggested changes. All of these examples are assumed to be created
|
||||
in a namespace called `example`.
|
||||
|
||||
### Use-Case: Pod with ssh keys
|
||||
|
||||
To create a pod that uses an ssh key stored as a secret, we first need to create a secret:
|
||||
To create a pod that uses an ssh key stored as a secret, we first need to create
|
||||
a secret:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -443,7 +487,8 @@ To create a pod that uses an ssh key stored as a secret, we first need to create
|
||||
base64 strings. Newlines are not valid within these strings and must be
|
||||
omitted.
|
||||
|
||||
Now we can create a pod which references the secret with the ssh key and consumes it in a volume:
|
||||
Now we can create a pod which references the secret with the ssh key and
|
||||
consumes it in a volume:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -486,7 +531,8 @@ When the container's command runs, the pieces of the key will be available in:
|
||||
/etc/secret-volume/id-rsa.pub
|
||||
/etc/secret-volume/id-rsa
|
||||
|
||||
The container is then free to use the secret data to establish an ssh connection.
|
||||
The container is then free to use the secret data to establish an ssh
|
||||
connection.
|
||||
|
||||
### Use-Case: Pods with pod / test credentials
|
||||
|
||||
@@ -602,8 +648,9 @@ The pods:
|
||||
}
|
||||
```
|
||||
|
||||
The specs for the two pods differ only in the value of the object referred to by the secret volume
|
||||
source. Both containers will have the following files present on their filesystems:
|
||||
The specs for the two pods differ only in the value of the object referred to by
|
||||
the secret volume source. Both containers will have the following files present
|
||||
on their filesystems:
|
||||
|
||||
/etc/secret-volume/username
|
||||
/etc/secret-volume/password
|
||||
|
Reference in New Issue
Block a user