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
Eric Tune 2015-05-21 13:25:20 -07:00
parent 51e0647f41
commit 0b4ced80a7
5 changed files with 275 additions and 35 deletions

View File

@ -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

View File

@ -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>`.

View File

@ -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

View File

@ -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)]()

View File

@ -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)]()