mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	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.
This commit is contained in:
		@@ -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"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[]()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										84
									
								
								docs/service_accounts_admin.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								docs/service_accounts_admin.md
									
									
									
									
									
										Normal 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
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[]()
 | 
			
		||||
		Reference in New Issue
	
	Block a user