2015-07-12 04:04:52 +00:00
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
<!-- BEGIN STRIP_FOR_RELEASE -->
2015-07-16 17:02:26 +00:00
< img src = "http://kubernetes.io/img/warning.png" alt = "WARNING"
width="25" height="25">
< img src = "http://kubernetes.io/img/warning.png" alt = "WARNING"
width="25" height="25">
< img src = "http://kubernetes.io/img/warning.png" alt = "WARNING"
width="25" height="25">
< img src = "http://kubernetes.io/img/warning.png" alt = "WARNING"
width="25" height="25">
< img src = "http://kubernetes.io/img/warning.png" alt = "WARNING"
width="25" height="25">
< h2 > PLEASE NOTE: This document applies to the HEAD of the source tree< / h2 >
If you are using a released version of Kubernetes, you should
refer to the docs that go with that version.
2015-12-14 18:37:38 +00:00
<!-- TAG RELEASE_LINK, added by the munger automatically -->
2015-07-16 17:02:26 +00:00
< strong >
2015-11-03 18:17:57 +00:00
The latest release of this document can be found
[here ](http://releases.k8s.io/release-1.1/docs/user-guide/images.md ).
2015-07-16 17:02:26 +00:00
Documentation for other releases can be found at
[releases.k8s.io ](http://releases.k8s.io ).
< / strong >
--
2015-07-13 22:15:35 +00:00
2015-07-12 04:04:52 +00:00
<!-- END STRIP_FOR_RELEASE -->
<!-- END MUNGE: UNVERSIONED_WARNING -->
2015-07-17 22:35:41 +00:00
2014-10-09 17:06:45 +00:00
# Images
2015-07-13 17:57:44 +00:00
2014-10-09 17:06:45 +00:00
Each container in a pod has its own image. Currently, the only type of image supported is a [Docker Image ](https://docs.docker.com/userguide/dockerimages/ ).
2015-07-20 20:45:36 +00:00
You create your Docker image and push it to a registry before referring to it in a Kubernetes pod.
2014-10-09 17:06:45 +00:00
The `image` property of a container supports the same syntax as the `docker` command does, including private registries and tags.
2015-07-13 17:57:44 +00:00
**Table of Contents**
<!-- BEGIN MUNGE: GENERATED_TOC -->
2015-07-17 16:20:19 +00:00
2015-07-13 17:57:44 +00:00
- [Images ](#images )
- [Updating Images ](#updating-images )
- [Using a Private Registry ](#using-a-private-registry )
- [Using Google Container Registry ](#using-google-container-registry )
- [Configuring Nodes to Authenticate to a Private Repository ](#configuring-nodes-to-authenticate-to-a-private-repository )
- [Pre-pulling Images ](#pre-pulling-images )
- [Specifying ImagePullSecrets on a Pod ](#specifying-imagepullsecrets-on-a-pod )
- [Use Cases ](#use-cases )
<!-- END MUNGE: GENERATED_TOC -->
2015-06-09 17:21:18 +00:00
## Updating Images
2015-09-01 22:29:38 +00:00
The default pull policy is `IfNotPresent` which causes the Kubelet to not
2015-06-09 17:21:18 +00:00
pull an image if it already exists. If you would like to always force a pull
2015-09-01 22:29:38 +00:00
you must set a pull image policy of `Always` or specify a `:latest` tag on
2015-06-09 17:21:18 +00:00
your image.
2015-11-14 05:21:00 +00:00
If you did not specify tag of your image, it will be assumed as `:latest` , with
pull image policy of `Always` correspondingly.
2014-10-09 17:06:45 +00:00
## Using a Private Registry
2015-06-26 22:43:16 +00:00
2015-06-09 17:21:18 +00:00
Private registries may require keys to read images from them.
Credentials can be provided in several ways:
2015-06-11 05:11:44 +00:00
- Using Google Container Registry
2015-06-09 17:21:18 +00:00
- Per-cluster
2015-06-26 19:13:43 +00:00
- automatically configured on Google Compute Engine or Google Container Engine
2015-06-09 17:21:18 +00:00
- all pods can read the project's private registry
2015-07-24 21:52:18 +00:00
- Configuring Nodes to Authenticate to a Private Registry
2015-06-09 17:21:18 +00:00
- all pods can read any configured private registries
- requires node configuration by cluster administrator
- Pre-pulling Images
- all pods can use any images cached on a node
- requires root access to all nodes to setup
2015-06-24 22:17:07 +00:00
- Specifying ImagePullSecrets on a Pod
2015-06-09 17:21:18 +00:00
- only pods which provide own keys can access the private registry
Each option is described in more detail below.
2015-07-24 21:52:18 +00:00
2015-06-09 17:21:18 +00:00
### Using Google Container Registry
2015-02-15 18:24:44 +00:00
2015-06-09 17:21:18 +00:00
Kubernetes has native support for the [Google Container
Registry (GCR)](https://cloud.google.com/tools/container-registry/), when running on Google Compute
Engine (GCE). If you are running your cluster on GCE or Google Container Engine (GKE), simply
use the full image name (e.g. gcr.io/my_project/image:tag).
2015-02-15 18:24:44 +00:00
2015-06-09 17:21:18 +00:00
All pods in a cluster will have read access to images in this registry.
2014-10-09 17:06:45 +00:00
2015-09-11 14:42:45 +00:00
The kubelet will authenticate to GCR using the instance's
2015-06-09 17:21:18 +00:00
Google service account. The service account on the instance
will have a `https://www.googleapis.com/auth/devstorage.read_only` ,
so it can pull from the project's GCR, but not push.
2014-10-09 17:06:45 +00:00
2015-06-26 22:43:16 +00:00
### Configuring Nodes to Authenticate to a Private Repository
**Note:** if you are running on Google Container Engine (GKE), there will already be a `.dockercfg` on each node
with credentials for Google Container Registry. You cannot use this approach.
**Note:** this approach is suitable if you can control node configuration. It
will not work reliably on GCE, and any other cloud provider that does automatic
node replacement.
2015-07-24 21:52:18 +00:00
2015-12-16 00:04:13 +00:00
Docker stores keys for private registries in the `$HOME/.dockercfg` or `$HOME/.docker/config.json` file. If you put this
in the `$HOME` of user `root` on a kubelet, then docker will use it.
2015-06-26 22:43:16 +00:00
Here are the recommended steps to configuring your nodes to use a private registry. In this
example, run these on your desktop/laptop:
2015-12-16 00:04:13 +00:00
1. run `docker login [server]` for each set of credentials you want to use. This updates `$HOME/.docker/config.json` .
1. view `$HOME/.docker/config.json` in an editor to ensure it contains just the credentials you want to use.
2015-10-14 19:15:11 +00:00
1. get a list of your nodes, for example:
- if you want the names: `nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')`
- if you want to get the IPs: `nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}')`
2015-12-16 00:04:13 +00:00
1. copy your local `.docker/config.json` to the home directory of root on each node.
- for example: `for n in $nodes; do scp ~/.docker/config.json root@$n:/root/.docker/config.json; done`
2015-06-26 22:43:16 +00:00
Verify by creating a pod that uses a private image, e.g.:
2015-07-17 02:01:02 +00:00
2015-07-18 23:18:12 +00:00
```yaml
2015-07-16 00:20:39 +00:00
$ cat < < EOF > /tmp/private-image-test-1.yaml
2015-06-26 22:43:16 +00:00
apiVersion: v1
kind: Pod
metadata:
name: private-image-test-1
spec:
containers:
- name: uses-private-image
image: $PRIVATE_IMAGE_NAME
2015-08-28 23:33:28 +00:00
imagePullPolicy: Always
2015-06-26 22:43:16 +00:00
command: [ "echo", "SUCCESS" ]
EOF
2015-07-16 00:20:39 +00:00
$ kubectl create -f /tmp/private-image-test-1.yaml
2015-06-26 22:43:16 +00:00
pods/private-image-test-1
$
```
2015-07-17 02:01:02 +00:00
2015-06-26 22:43:16 +00:00
If everything is working, then, after a few moments, you should see:
2015-07-17 02:01:02 +00:00
2015-07-18 23:18:12 +00:00
```console
2015-06-26 22:43:16 +00:00
$ kubectl logs private-image-test-1
SUCCESS
```
If it failed, then you will see:
2015-07-17 02:01:02 +00:00
2015-07-18 23:18:12 +00:00
```console
2015-06-26 22:43:16 +00:00
$ kubectl describe pods/private-image-test-1 | grep "Failed"
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
```
2015-06-09 17:21:18 +00:00
2015-12-16 00:04:13 +00:00
You must ensure all nodes in the cluster have the same `.docker/config.json` . Otherwise, pods will run on
2015-06-09 17:21:18 +00:00
some nodes and fail to run on others. For example, if you use node autoscaling, then each instance
2015-12-16 00:04:13 +00:00
template needs to include the `.docker/config.json` or mount a drive that contains it.
2015-06-09 17:21:18 +00:00
2015-06-26 22:43:16 +00:00
All pods will have read access to images in any private registry once private
2015-12-16 00:04:13 +00:00
registry keys are added to the `.docker/config.json` .
2015-06-26 22:43:16 +00:00
**This was tested with a private docker repository as of 26 June with Kubernetes version v0.19.3.
It should also work for a private registry such as quay.io, but that has not been tested.**
2015-06-09 17:21:18 +00:00
### Pre-pulling Images
2014-10-09 17:06:45 +00:00
2015-06-26 22:43:16 +00:00
**Note:** if you are running on Google Container Engine (GKE), there will already be a `.dockercfg` on each node
with credentials for Google Container Registry. You cannot use this approach.
**Note:** this approach is suitable if you can control node configuration. It
will not work reliably on GCE, and any other cloud provider that does automatic
node replacement.
2014-10-09 17:06:45 +00:00
Be default, the kubelet will try to pull each image from the specified registry.
2015-01-21 04:30:42 +00:00
However, if the `imagePullPolicy` property of the container is set to `IfNotPresent` or `Never` ,
2014-10-09 17:06:45 +00:00
then a local image is used (preferentially or exclusively, respectively).
2015-06-09 17:21:18 +00:00
If you want to rely on pre-pulled images as a substitute for registry authentication,
you must ensure all nodes in the cluster have the same pre-pulled images.
2014-10-09 17:06:45 +00:00
This can be used to preload certain images for speed or as an alternative to authenticating to a private registry.
2015-06-09 17:21:18 +00:00
All pods will have read access to any pre-pulled images.
2015-04-29 01:34:28 +00:00
2015-05-21 20:25:20 +00:00
### Specifying ImagePullSecrets on a Pod
2015-06-26 22:43:16 +00:00
**Note:** This approach is currently the recommended approach for GKE, GCE, and any cloud-providers
where node creation is automated.
2015-06-09 17:21:18 +00:00
Kubernetes supports specifying registry keys on a pod.
2015-12-16 00:04:13 +00:00
First, create a `.docker/config.json` , such as by running `docker login <registry.domain>` .
Then put the resulting `.docker/config.json` file into a [secret resource ](secrets.md ). For example:
2015-07-17 02:01:02 +00:00
2015-07-18 23:18:12 +00:00
```console
2015-06-24 22:17:07 +00:00
$ docker login
Username: janedoe
Password: ●●●●●●●●●●●
Email: jdoe@example.com
2015-12-16 00:04:13 +00:00
WARNING: login credentials saved in /Users/jdoe/.docker/config.json.
2015-06-24 22:17:07 +00:00
Login Succeeded
2015-12-16 00:04:13 +00:00
$ echo $(cat ~/.docker/config.json)
2015-06-24 22:17:07 +00:00
{ "https://index.docker.io/v1/": { "auth": "ZmFrZXBhc3N3b3JkMTIK", "email": "jdoe@example.com" } }
2015-12-16 00:04:13 +00:00
$ cat ~/.docker/config.json | base64
2015-06-24 22:17:07 +00:00
eyAiaHR0cHM6Ly9pbmRleC5kb2NrZXIuaW8vdjEvIjogeyAiYXV0aCI6ICJabUZyWlhCaGMzTjNiM0prTVRJSyIsICJlbWFpbCI6ICJqZG9lQGV4YW1wbGUuY29tIiB9IH0K
2015-07-16 00:20:39 +00:00
$ cat > /tmp/image-pull-secret.yaml < < EOF
2015-06-24 22:17:07 +00:00
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
data:
2015-12-16 00:04:13 +00:00
.dockerconfigjson: eyAiaHR0cHM6Ly9pbmRleC5kb2NrZXIuaW8vdjEvIjogeyAiYXV0aCI6ICJabUZyWlhCaGMzTjNiM0prTVRJSyIsICJlbWFpbCI6ICJqZG9lQGV4YW1wbGUuY29tIiB9IH0K
type: kubernetes.io/dockerconfigjson
2015-06-09 17:21:18 +00:00
EOF
2015-07-16 00:20:39 +00:00
$ kubectl create -f /tmp/image-pull-secret.yaml
2015-06-09 17:21:18 +00:00
secrets/myregistrykey
```
2015-07-24 21:52:18 +00:00
If you get the error message `error: no objects passed to create` , it may mean the base64 encoded string is invalid.
2015-12-16 00:04:13 +00:00
If you get an error message like `Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ...` it means
the data was successfully un-base64 encoded, but could not be parsed as a `.docker/config.json` file.
2015-06-24 22:17:07 +00:00
2015-12-16 00:04:13 +00:00
This process needs to be done one time per namespace, or to any non-default service accounts you create.
2015-06-24 22:17:07 +00:00
2015-06-09 17:21:18 +00:00
Now, you can create pods which reference that secret by adding an `imagePullSecrets`
section to a pod definition.
2015-07-17 02:01:02 +00:00
2015-07-18 23:18:12 +00:00
```yaml
2015-06-09 17:21:18 +00:00
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: foo
2015-06-24 22:17:07 +00:00
image: janedoe/awesomeapp:v1
2015-06-09 17:21:18 +00:00
imagePullSecrets:
- name: myregistrykey
```
2015-07-17 02:01:02 +00:00
2015-06-09 17:21:18 +00:00
This needs to be done for each pod that is using a private registry.
However, setting of this field can be automated by setting the imagePullSecrets
2015-07-15 05:07:44 +00:00
in a [serviceAccount ](service-accounts.md ) resource.
2015-06-09 17:21:18 +00:00
2015-12-16 00:04:13 +00:00
You can use this in conjunction with a per-node `.docker/config.json` . The credentials
2015-06-26 22:43:16 +00:00
will be merged. This approach will work on Google Container Engine (GKE).
2015-06-09 17:21:18 +00:00
### Use Cases
2015-07-17 22:35:41 +00:00
2015-06-09 17:21:18 +00:00
There are a number of solutions for configuring private registries. Here are some
common use cases and suggested solutions.
2015-04-29 01:34:28 +00:00
2016-01-04 21:02:32 +00:00
1. Cluster running only non-proprietary (e.g open-source) images. No need to hide images.
2015-06-09 17:21:18 +00:00
- Use public images on the Docker hub.
- no configuration required
- on GCE/GKE, a local mirror is automatically used for improved speed and availability
2016-01-04 21:02:32 +00:00
1. Cluster running some proprietary images which should be hidden to those outside the company, but
2015-06-09 17:21:18 +00:00
visible to all cluster users.
- Use a hosted private [Docker registry ](https://docs.docker.com/registry/ )
- may be hosted on the [Docker Hub ](https://hub.docker.com/account/signup/ ), or elsewhere.
2015-12-16 00:04:13 +00:00
- manually configure .docker/config.json on each node as described above
2015-06-09 17:21:18 +00:00
- Or, run an internal private registry behind your firewall with open read access.
2015-07-20 20:45:36 +00:00
- no Kubernetes configuration required
2015-06-09 17:21:18 +00:00
- Or, when on GCE/GKE, use the project's Google Container Registry.
- will work better with cluster autoscaling than manual node configuration
- Or, on a cluster where changing the node configuration is inconvenient, use `imagePullSecrets` .
2016-01-04 21:02:32 +00:00
1. Cluster with a proprietary images, a few of which require stricter access control
- ensure [AlwaysPullImages admission controller ](../../docs/admin/admission-controllers.md#alwayspullimages ) is active, otherwise, all Pods potentially have access to all images
- Move sensitive data into a "Secret" resource, instead of packaging it in an image.
1. A multi-tenant cluster where each tenant needs own private registry
- ensure [AlwaysPullImages admission controller ](../../docs/admin/admission-controllers.md#alwayspullimages ) is active, otherwise, all Pods of all tenants potentially have access to all images
- run a private registry with authorization required.
- generate registry credential for each tenant, put into secret, and populate secret to each tenant namespace.
- tenant adds that secret to imagePullSecrets of each namespace.
2015-05-14 22:12:45 +00:00
2015-07-14 00:13:09 +00:00
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
2015-07-14 16:37:37 +00:00
[![Analytics ](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/images.md?pixel )]()
2015-07-14 00:13:09 +00:00
<!-- END MUNGE: GENERATED_ANALYTICS -->