mirror of https://github.com/k3s-io/k3s
Service account documentation.
Fixes #9344. Depends on #9821. Update Secrets documentation to explain how secrets can be created/used manually, or automatically with service accounts. Greatly expanded service account documentation. Added a service account admin guide. Lots of cross-references.pull/6/head
parent
51e0647f41
commit
0b4ced80a7
|
@ -102,10 +102,10 @@ the `kubernetes` DNS name, which resolves to a Service IP which in turn
|
|||
will be routed to an apiserver.
|
||||
|
||||
The recommended way to authenticate to the apiserver is with a
|
||||
[service account](../docs/service_accounts.md). By default, a pod
|
||||
[service account](service_accounts.md) credential. By default, a pod
|
||||
is associated with a service account, and a credential (token) for that
|
||||
service account is placed into the filesystem tree of each container in that pod,
|
||||
at `/var/run/secrets/kubernetes.io/serviceaccount`.
|
||||
at `/var/run/secrets/kubernetes.io/serviceaccount/token`.
|
||||
|
||||
From within a pod the recommended ways to connect to API are:
|
||||
- run a kubectl proxy as one of the containers in the pod, or as a background
|
||||
|
@ -115,6 +115,7 @@ From within a pod the recommended ways to connect to API are:
|
|||
in a pod](../examples/kubectl-container/).
|
||||
- use the Go client library, and create a client using the `client.NewInContainer()` factory.
|
||||
This handles locating and authenticating to the apiserver.
|
||||
In each case, the credentials of the pod are used to communicate securely with the apiserver.
|
||||
|
||||
|
||||
## <a name="otherservices"></a>Accessing services running on the cluster
|
||||
|
|
|
@ -68,7 +68,7 @@ This can be used to preload certain images for speed or as an alternative to aut
|
|||
|
||||
All pods will have read access to any pre-pulled images.
|
||||
|
||||
### Specifying ImagePullKeys on a Pod
|
||||
### Specifying ImagePullSecrets on a Pod
|
||||
Kubernetes supports specifying registry keys on a pod.
|
||||
|
||||
First, create a `.dockercfg`, such as running `docker login <registry.domain>`.
|
||||
|
|
118
docs/secrets.md
118
docs/secrets.md
|
@ -5,26 +5,45 @@ passwords, OAuth tokens, and ssh keys. Putting this information in a `secret`
|
|||
is safer and more flexible than putting it verbatim in a `pod` definition or in
|
||||
a docker image.
|
||||
|
||||
### Creating and Using Secrets
|
||||
To make use of secrets requires at least two steps:
|
||||
1. create a `secret` resource with secret data
|
||||
1. create a pod that has a volume of type `secret` and a container
|
||||
which mounts that volume.
|
||||
## Overview of Secrets
|
||||
|
||||
This is an example of a simple secret, in json format:
|
||||
```json
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Secret",
|
||||
"metadata" : {
|
||||
"name": "mysecret",
|
||||
"namespace": "myns"
|
||||
},
|
||||
"data": {
|
||||
"username": "dmFsdWUtMQ0K",
|
||||
"password": "dmFsdWUtMg0K"
|
||||
}
|
||||
}
|
||||
|
||||
Creation of secrets can be manual (done by the user) or automatic (done by
|
||||
automation built into the cluster).
|
||||
|
||||
A secret can be used with a pod in two ways: either as files in a volume mounted on one or more of
|
||||
its containers, or used by kubelet when pulling images for the pod.
|
||||
|
||||
To use a secret, a pod needs to reference the secret. This reference
|
||||
can likewise be added manually or automatically.
|
||||
|
||||
A single Pod may use various combination of the above options.
|
||||
|
||||
### Service Accounts Automatically Create and Use Secrets with API Credentials
|
||||
|
||||
Kubernetes automatically creates secrets which contain credentials for
|
||||
accessing the API and it automatically modifies your pods to use this type of
|
||||
secret.
|
||||
|
||||
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 apiserver,
|
||||
this is the recommended workflow.
|
||||
|
||||
See the [Service Account](service_accounts.md) documentation for more
|
||||
information on how Service Accounts work.
|
||||
|
||||
### Creating a Secret Manually
|
||||
|
||||
This is an example of a simple secret, in yaml format:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: mysecret
|
||||
type: Opaque
|
||||
data:
|
||||
password: dmFsdWUtMg0K
|
||||
username: dmFsdWUtMQ0K
|
||||
```
|
||||
|
||||
The data field is a map. Its keys must match
|
||||
|
@ -33,7 +52,15 @@ allowed. The values are arbitrary data, encoded using base64. The values of
|
|||
username and password in the example above, before base64 encoding,
|
||||
are `value-1` and `value-2`, respectively, with carriage return and newline characters at the end.
|
||||
|
||||
This is an example of a pod that uses a secret, in json format:
|
||||
Create the secret using [`kubectl create`](kubectl-create.md).
|
||||
|
||||
Once the secret is created, you can:
|
||||
- create pods that automatically use it via a [Service Account](service_accounts.md).
|
||||
- modify your pod specification to use the secret
|
||||
|
||||
### Manually specifying a Secret to be Mounted on a Pod
|
||||
|
||||
This is an example of a pod that mounts a secret in a volume:
|
||||
```json
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
|
@ -62,6 +89,29 @@ This is an example of a pod that uses a secret, in json format:
|
|||
}
|
||||
```
|
||||
|
||||
Each secret you want to use needs its own `spec.volumes`.
|
||||
|
||||
If there are multiple containers in the pod, then each container needs its
|
||||
own `volumeMounts` block, but only one `spec.volumes` is needed per secret.
|
||||
|
||||
You can package many files into one secret, or use many secrets,
|
||||
whichever is convenient.
|
||||
|
||||
### Manually specifying an imagePullSecret
|
||||
Use of imagePullSecrets is desribed in the [images documentation](
|
||||
images.md#specifying-imagepullsecrets-on-a-pod)
|
||||
### Automatic use of Manually Created Secrets
|
||||
|
||||
*This feature is planned but not implemented. See [issue
|
||||
9902](https://github.com/GoogleCloudPlatform/kubernetes/issues/9902).*
|
||||
|
||||
You can reference manually created secrets from a [service account](
|
||||
service_accounts.md).
|
||||
Then, pods which use that service account will have
|
||||
`volumeMounts` and/or `imagePullSecrets` added to them.
|
||||
The secrets will be mounted at **TBD**.
|
||||
|
||||
## Details
|
||||
### Restrictions
|
||||
Secret volume sources are validated to ensure that the specified object
|
||||
reference actually points to an object of type `Secret`. Therefore, a secret
|
||||
|
@ -106,7 +156,7 @@ versions of Kubernetes are expected to provide more automation for populating
|
|||
environment variables from files.
|
||||
|
||||
|
||||
## Secret and Pod Lifetime interaction
|
||||
### Secret and Pod Lifetime interaction
|
||||
|
||||
When a pod is created via the API, there is no check whether a referenced
|
||||
secret exists. Once a pod is scheduled, the kubelet will try to fetch the
|
||||
|
@ -327,6 +377,30 @@ Both containers will have the following files present on their filesystems:
|
|||
Note how the specs for the two pods differ only in one field; this facilitates
|
||||
creating pods with different capabilities from a common pod config template.
|
||||
|
||||
You could further simplify the base pod specification by using two service accounts:
|
||||
one called, say, `prod-user` with the `prod-db-secret`, and one called, say,
|
||||
`test-user` with the `test-db-secret`. Then, the pod spec can be shortened to, for example:
|
||||
```json
|
||||
{
|
||||
"kind": "Pod",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "prod-db-client-pod",
|
||||
"labels": {
|
||||
"name": "prod-db-client"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"serviceAccount": "prod-db-client",
|
||||
"containers": [
|
||||
{
|
||||
"name": "db-client-container",
|
||||
"image": "myClientImage",
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Use-case: Secret visible to one container in a pod
|
||||
<a name="use-case-two-containers"></a>
|
||||
|
||||
|
@ -344,6 +418,8 @@ With this partitioned approach, an attacker now has to trick the application
|
|||
server into doing something rather arbitrary, which may be harder than getting
|
||||
it to read a file.
|
||||
|
||||
<!-- TODO: explain how to do this while still using automation. -->
|
||||
|
||||
## Security Properties
|
||||
|
||||
### Protections
|
||||
|
|
|
@ -1,14 +1,93 @@
|
|||
# Service Accounts
|
||||
A serviceAccount provides an identity for processes that run in a Pod.
|
||||
The behavior of the the serviceAccount object is implemented via a plugin
|
||||
called an [Admission Controller]( admission_controllers.md). When this plugin is active
|
||||
(and it is by default on most distributions), then it does the following when a pod is created or modified:
|
||||
1. If the pod does not have a ```ServiceAccount```, it modifies the pod's ```ServiceAccount``` to "default".
|
||||
2. It ensures that the ```ServiceAccount``` referenced by a pod exists.
|
||||
3. If ```LimitSecretReferences``` is true, it rejects the pod if the pod references ```Secret``` objects which the pods
|
||||
```ServiceAccount``` does not reference.
|
||||
4. If the pod does not contain any ```ImagePullSecrets```, the ```ImagePullSecrets``` of the
|
||||
```ServiceAccount``` are added to the pod.
|
||||
5. If ```MountServiceAccountToken``` is true, it adds a ```VolumeMount``` with the pod's ```ServiceAccount``` API token secret to containers in the pod.
|
||||
|
||||
A service account provides an identity for processes that run in a Pod.
|
||||
|
||||
*This is a user introduction to Service Accounts. See also the
|
||||
[Cluster Admin Guide to Service Accounts](service_accounts_admin.md).*
|
||||
|
||||
*Note: This document descibes how service accounts behave in a cluster set up
|
||||
as recommended by the Kubernetes project. Your cluster administrator may have
|
||||
customized the behavior in your cluster, in which case this documentation may
|
||||
not apply.*
|
||||
|
||||
When you (a human) access the cluster (e.g. using kubectl), you are
|
||||
authenticated by the apiserver as a particular User Account (currently this is
|
||||
usually "admin", unless your cluster administrator has customized your
|
||||
cluster). Processes in containers inside pods can also contact the apiserver.
|
||||
When they do, they are authenticated as a particular Service Account (e.g.
|
||||
"default").
|
||||
|
||||
## Using the Default Service Account to access the API server.
|
||||
|
||||
When you create a pod, you do not need to specify a service account. It is
|
||||
automatically assigned the `default` service account of the same namespace. If
|
||||
you get the raw json or yaml for a pod you have created (e.g. `kubectl get
|
||||
pods/podname -o yaml`), you can see the `spec.serviceAccount` field has been
|
||||
[automatically set](working_with_resources.md#resources-are-automatically-modified).
|
||||
|
||||
You can access the API using a proxy or with a client library, as described in
|
||||
[Accessing the Cluster](accessing-the-cluster.md#accessing-the-api-from-a-pod).
|
||||
|
||||
## Using Multiple Service Accounts
|
||||
|
||||
Every namespace has a default service account resource called "default".
|
||||
You can list this and any other serviceAccount resources in the namespace with this command:
|
||||
```
|
||||
kubectl get serviceAccounts
|
||||
$ NAME SECRETS
|
||||
default 1
|
||||
```
|
||||
|
||||
You can create additional serviceAccounts like this:
|
||||
```
|
||||
$ cat > serviceaccount.yaml <<EOF
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: build-robot
|
||||
EOF
|
||||
$ kubectl create -f serviceaccount.json
|
||||
serviceacccounts/build-robot
|
||||
```
|
||||
|
||||
If you get a complete dump of the service account object, like this:
|
||||
```
|
||||
$ kubectl get serviceacccounts/build-robot -o yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
creationTimestamp: 2015-06-16T00:12:59Z
|
||||
name: build-robot
|
||||
namespace: default
|
||||
resourceVersion: "272500"
|
||||
selfLink: /api/v1/namespaces/default/serviceaccounts/build-robot
|
||||
uid: 721ab723-13bc-11e5-aec2-42010af0021e
|
||||
secrets:
|
||||
- name: build-robot-token-bvbk5
|
||||
```
|
||||
then you will see that a token has automatically been created and is referenced by the service account.
|
||||
|
||||
In the future, you will be able to configure different access policies for each service account.
|
||||
|
||||
To use a non-default service account, simply set the `spec.serviceAccount`
|
||||
field of a pod to the set to the name of the service account you wish to use.
|
||||
|
||||
The service account has to exist at the time the pod is created, or it will be rejected.
|
||||
|
||||
You cannot update the service account of an already created pod.
|
||||
|
||||
You can clean up the service account from this example like this:
|
||||
```
|
||||
$ kubectl delete serviceaccount/build-robot
|
||||
```
|
||||
|
||||
<!-- TODO: describe how to create a pod with no Service Account. -->
|
||||
|
||||
## Adding Secrets to a service account.
|
||||
TODO: Test and explain how to use additional non-K8s secrets with an existing service account.
|
||||
|
||||
TODO explain:
|
||||
- The token goes to: "/var/run/secrets/kubernetes.io/serviceaccount/$WHATFILENAME"
|
||||
|
||||
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/service_accounts.md?pixel)]()
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
# Cluster Admin Guide to Service Accounts
|
||||
|
||||
*This is a Cluster Administrator guide to service accounts. It assumes knowledge of
|
||||
the [User Guide to Service Accounts](service_accounts.md).*
|
||||
|
||||
*Support for authorization and user accounts is planned but incomplete. Sometimes
|
||||
incomplete features are referred to in order to better describe service accounts.*
|
||||
|
||||
## User accounts vs service accounts
|
||||
|
||||
Kubernetes distinguished between the concept of a user account and a service accounts
|
||||
for a number of reasons:
|
||||
- User accounts are for humans. Service accounts are for processes, which
|
||||
run in pods.
|
||||
- User accounts are intended to be global. Names must be unique across all
|
||||
namespaces of a cluster, future user resource will not be namespaced).
|
||||
Service accounts are namespaced.
|
||||
- Typically, a clusters User accounts might be synced from a corporate
|
||||
database, where new user account creation requires special privileges and
|
||||
is tied to complex business processes. Service account creation is intended
|
||||
to be more lightweight, allowing cluster users to create service accounts for
|
||||
specific tasks (i.e. principle of least privilege).
|
||||
- Auditing considerations for humans and service accounts may differ.
|
||||
- A config bundle for a complex system may include definition of various service
|
||||
accounts for components of that system. Because service accounts can be created
|
||||
ad-hoc and have namespaced names, such config is portable.
|
||||
|
||||
## Service account automation
|
||||
|
||||
Three separate components cooperate to implement the automation around service accounts:
|
||||
- A Service account admission controller
|
||||
- A Token controller
|
||||
- A Service account controller
|
||||
|
||||
### Service Account Admission Controller
|
||||
|
||||
The modification of pods is implemented via a plugin
|
||||
called an [Admission Controller](admission_controllers.md). It is part of the apiserver.
|
||||
It acts synchronously to modify pods as they are created or updated. When this plugin is active
|
||||
(and it is by default on most distributions), then it does the following when a pod is created or modified:
|
||||
1. If the pod does not have a `ServiceAccount` set, it sets the `ServiceAccount` to `default`.
|
||||
2. It ensures that the `ServiceAccount` referenced by the pod exists, and otherwise rejects it.
|
||||
4. If the pod does not contain any `ImagePullSecrets`, then `ImagePullSecrets` of the
|
||||
`ServiceAccount` are added to the pod.
|
||||
5. It adds a `volume` to the pod which contains a token for API access.
|
||||
6. It adds a `volumeSource` to each container of the pod mounted at `/var/run/secrets/kubernetes.io/serviceaccount`.
|
||||
|
||||
### Token Controller
|
||||
TokenController runs as part of controller-manager. It acts asynchronously. It:
|
||||
- observes serviceAccount creation and creates a corresponding Secret to allow API access.
|
||||
- observes serviceAccount deletion and deletes all corresponding ServiceAccountToken Secrets
|
||||
- observes secret addition, and ensures the referenced ServiceAccount exists, and adds a token to the secret if needed
|
||||
- observer secret deleteion and removes a reference from the corresponding ServiceAccount if needed
|
||||
|
||||
#### To create additional API tokens
|
||||
|
||||
A controller loop ensures a secret with an API token exists for each service
|
||||
account. To create additional API tokens for a service account, create a secret
|
||||
of type `ServiceAccountToken` with an annotation referencing the service
|
||||
account, and the controller will update it with a generated token:
|
||||
|
||||
```
|
||||
secret.json:
|
||||
{
|
||||
"kind": "Secret",
|
||||
"metadata": {
|
||||
"name": "mysecretname",
|
||||
"annotations": {
|
||||
"kubernetes.io/service-account.name": "myserviceaccount"
|
||||
}
|
||||
}
|
||||
"type": "kubernetes.io/service-account-token"
|
||||
}
|
||||
|
||||
$ kubectl create -f secret.json
|
||||
$ kubectl describe secret mysecretname
|
||||
```
|
||||
|
||||
#### To delete/invalidate a service account token:
|
||||
```
|
||||
kubectl delete secret mysecretname
|
||||
```
|
||||
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/service_accounts_admin.md?pixel)]()
|
Loading…
Reference in New Issue