A container image represents binary data that encapsulates an application and all of its software dependencies. Container images are executable software packages that can run independently and make well-defined assumptions about your runtime environment.
Typically, you create an app container image and send it to a registry before referencing it in a pod.
This page provides a summary of the container image concept.
Image names
Container images are usually named as pause, example/mycontainer, or kube-apiserver. Images can also include a registration hostname; For example: ficcional.registry.example/imagename, and possibly also a port number; For example: ficcional.registry.example:10443/imagename.
If you do not specify a record hostname, Kubernetes assumes that it refers to the Docker public registry.
After the name part of the image, you can add a tag (the same way you would when using with commands like docker or podman). Tags allow you to identify different versions of the same series of images.
Image labels consist of lowercase and uppercase letters, digits, underscores (_), periods (.), and hyphens (-). There are additional rules about where to place separator characters (_, -, and .) within an image tag. If you don’t specify a tag, Kubernetes assumes that it refers to the most recent tag.
Updating images
When you first create a Deployment, StatefulSet, Pod, or other object that includes a Pod template, by default, the pull policy for all containers in that pod will be set to IfNotPresent if not explicitly specified. This policy causes the kubelet to skip extracting an image if it already exists.
imagePullPolicy image
extraction policy
for a
container and the image tag affect when the kubelet attempts to extract (download) the specified
image. Here is
a list of the values you can set for imagePullPolicy and the effects these values have:
IfNotPresentThe image is checked out only if it is not already locally present. Alwaysevery time the kubelet starts a container, the kubelet queries the container’s image log to resolve the name into an image summary. If the kubelet has a container image with that exact digest cached locally, the kubelet uses its cached image; Otherwise, the kubelet extracts the image with the digest resolved and uses that image to start the container. Neverthe kubelet does not attempt to search for the image. If the image is somehow already present locally, the kubelet tries to start the container; otherwise, startup fails. See the pre-extracted images for more details.
The caching semantics of the underlying image provider makes even imagePullPolicy: Always efficient, as long as the registry can be reliably accessed. Your container runtime may notice that the image layers already exist on the node, so you don’t need to download them again.
To ensure that the Pod always uses the same version of a container image, you can specify the image summary; replace <image-name>:<tag> with <image-name>@<digest> (for example, image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2).
When using image tags, if the image registry were to change the code that represents that image’s tag, it could end up with a mix of Pods running the old and new code. An image summary uniquely identifies a specific version of the image, so Kubernetes executes the same code every time you launch a container with that specified image name and summary. Specifying an image per summary corrects the code that runs so that a registry change cannot cause that version merge.
There are third-party intake handlers that mutate pods (and pod templates) when they are created, so that the running workload is defined based on an image summary rather than a tag. This could be useful if you want to ensure that the entire workload runs the same code regardless of tag changes that occur in the registry.
Default image extraction policy
When you (or a controller) send a new Pod to the API server
, the cluster sets the imagePullPolicy field when specific conditions are met:if you omit the imagePullPolicy
- field and the container image label is :latest, imagePullPolicy is automatically set to Always;
- If you omit the imagePullPolicy field and do not specify the label for the container image, imagePullPolicy is automatically set to Always;
- field and specify the label for the container image that is ‘t :latest, imagePullPolicy is automatically set to IfNotPresent.
If you omit the imagePullPolicy
Image extraction required
If you want to always force a checkout, you can do one
of the following:Set the container imagePullPolicy to
- Always.
- Omit imagePullPolicy and use :latest as the label for the image to use; Kubernetes will set the policy to Always when you ship the Pod.
- Omit imagePullPolicy and the label for the image to be used; Kubernetes will set the policy to Always when you ship the Pod.
- Enable the AlwaysPullImages admission handler.
ImagePullBackOff
When a kubelet starts creating containers for a Pod using a container runtime, the container might be in a standby state due
to ImagePullBackOff.
The ImagePullBackOff status means that a container failed to start because Kubernetes failed to pull a container image (for reasons such as an invalid image name or pulling from a private registry without imagePullSecret). The BackOff part indicates that Kubernetes will continue to try to extract the image, with increasing backtracking delay.
Kubernetes increases the delay between each attempt until it reaches a compiled limit, which is 300 seconds (5 minutes).
Serial and parallel image extraction
By default, kubelet extracts serial images. In other words, kubelet sends only one image extraction request to the image service at a time. Other image extraction requests have to wait until the one being processed is completed.
Nodes make image extraction decisions in isolation. Even when serialized image extractions are used, two different nodes can extract the same image side-by-side.
If you want to enable parallel image extractions, you can set the serializeImagePulls field to false in the kubelet configuration. With serializeImagePulls set to false, image extraction requests will be sent to the image service immediately and multiple images will be extracted at the same time.
When enabling parallel image extractions
, ensure that the container runtime image service can handle parallel image extractions
.
The kubelet never extracts multiple images in parallel on behalf of a Pod. For example, if you have a Pod that has a startup container and an application container, the image extractions for the two containers will not be parallelized. However, if you have two Pods using different images, the kubelet extracts the images in parallel on behalf of the two different Pods, when parallel image extractions are enabled.
Parallel Image Extraction Maximum
When serializeImagePulls is set to false, the kubelet has no default limit on the maximum number of images that are extracted at the same time. If you want to limit the number of parallel image extractions, you can set the maxParallelImagePulls field in the kubelet settings. With maxParallelImagePulls set to n, only n images can be extracted at a time, and any image extraction beyond n will have to wait until at least one image extraction in progress is completed.
Limiting the number of parallel image extractions would prevent image extraction from consuming too much network bandwidth or disk I/O, when parallel image extraction is enabled.
You can set maxParallelImagePulls to a positive number greater than or equal to 1. If you set maxParallelImagePulls to be greater than or equal to 2, you must set serializeImagePulls to false. The kubelet will not start with an invalid maxParallelImagePulls configuration.
Multi-architectural images with image indexes
In addition to providing binary images, a container record can also serve a container image index. An image index can point to multiple image manifests for specific versions of a container’s architecture. The idea is that you can have a name for an image (e.g. pause, example/mycontainer, kube-apiserver) and allow different systems to get the correct binary image for the machine architecture they are using.
Kubernetes typically names container images with a -$(ARCH) suffix. For backward compatibility, generate older images with suffixes. The idea is to generate a pause image that has the manifest for all arcs and say pause-amd64, which is backward compatible for older configurations or YAML files that may have encoded the images with suffixes.
Using a private record
Private records may require keys to read images from them. Credentials can be provided in several ways:
- Configuring nodes to authenticate to a private registry
- All pods can read any configured private record
- requires node configuration by cluster administrator
- dynamically obtain credentials for private
- records Kubelet can be configured to use the Credential Provider Exec plugin for the respective private registry.
- Pre-extracted images All pods can
- use any cached image
- Requires root access to all nodes to configure
on a node
- Specifying ImagePullSecrets on a pod
- Only pods that provide their own keys can access the private registry
- Local or vendor-specific
- extensions If you are using a custom node configuration, you (or your cloud provider) can implement their mechanism to authenticate the node to the container registry.
Kubelet Credential provider to
These options are explained in more detail below.
Configuring nodes to authenticate to a private
registry
The specific instructions for setting credentials depend on the container runtime and the registry you have chosen to use. You should consult the solution documentation for the most accurate information.
For an example of configuring a private container image registry, see the Extract an image from a private registry task. That example uses a private record in Docker Hub.
Kubelet credential provider for authenticated image extractions
You can configure the kubelet to invoke a plug-in binary to dynamically obtain registry credentials for a container image. This is the most robust and versatile way to obtain credentials for private records, but it also requires a kubelet-level configuration to enable.
See Configure a kubelet image credential provider for details.
Interpreting
config.json The interpretation of
config.json varies between the original Docker implementation and the Kubernetes interpretation. In Docker, auths keys can only specify root URLs, while Kubernetes allows global URLs as well as matching paths with prefixes. This means that a config.json file like this is valid
:
The root URL
(*my-registry.io) matches the following syntax:p attern: { term } term: ‘*’ matches any sequence of non-separator characters ‘?’ matches any non-separator character ‘[‘ [ ‘^’ ] { character range } ‘]’ character class (must be non-empty) c corresponds to the c character (c != ‘*’, ‘?’, ‘\’, ‘\’, ‘[‘) ‘\’ c matches the c character Character range: c matches the c character (c != ‘\’, ‘-‘, ‘]’) ‘\\’ c matches the c character lo ‘-‘ hi matches the c character for the <= c <= hi
Image extraction operations would now pass credentials to the CRI container runtime for each valid pattern. For example, the following container image names would match correctly:
- my-registry.io/images
- my-registry.io/images/my-image
- my-registry.io/images/another-image
- sub.my-registry.io/images/my-image
- a.sub.my-registry.io/images/my-image
The kubelet performs image extractions sequentially for each credential found. This means that multiple entries are also possible in config.json:
If a container now specifies an image my-registry.io/images/subpath/my-image extract, then the kubelet will attempt to download them from both authentication sources if one of them fails
.
Pre-extracted images By
default, the kubelet attempts to extract each image from the specified registry. However, if the imagePullPolicy property of the container is set to IfNotPresent or Never, a local image is used (preferably or exclusively, respectively).
If you want to rely on pre-extracted images as a substitute for registry authentication
, you must ensure that all nodes in the cluster have the same pre-extracted
images.
This can be used to preload certain images for speed or as an alternative to authentication to a private registry
.
All pods will have read access to any previously extracted images.
Specifying
imagePullSecrets in a pod
Kubernetes supports specifying container image registry keys in a pod. imagePullSecrets must be in the same namespace as the pod. The secrets referred to must be of type kubernetes.io/dockercfg or kubernetes.io/dockerconfigjson.
Create a secret with a Docker configuration
You must know the customer’s user name,
registration password, and email address to authenticate to the registry, as well as their host name. Run the following command, substituting the appropriate uppercase values:
If you already have a Docker credentials file,
instead of using the above command, you can import the credentials file as Kubernetes Secrets.Creating a secret based on existing Docker credentials explains how to configure it.
This is particularly useful if you are using multiple private container registries, Since kubectl create secret docker-registry creates a secret that only works with a single private registry.
By referencing an imagePullSecrets
in
a Pod
Now, you can create pods that reference that secret by adding an imagePullSecrets section to a Pod definition. Each element in the imagePullSecrets array can only reference a Secret in the same namespace.
For example:
This should be done for each pod that uses a private record
.
However, the configuration of this field can be automated by setting imagePullSecrets on a ServiceAccount resource. Check Add ImagePullSecrets
to a service account for detailed instructions
.
You can use it in conjunction with one .docker/config.json per node. The credentials will be merged.
Use cases
There are a number of solutions for setting up private registries. Here are some common use cases and suggested solutions.
- A cluster that runs only non-proprietary (for example, open source) images. No need to hide images. Use public images
- from a public registry
- No configuration required
- Some cloud providers automatically cache or mirror public images, improving availability and reducing time to extract images.
.
- from a public registry
- runs some proprietary images that should be hidden from those outside the enterprise, but visible to all users in the cluster. Use a hosted private registry Manual
-
- configuration may be required on nodes that need to access the
- OR, run an internal private registry behind your firewall with open read access.
- No Kubernetes configuration required.
- Use a hosted container image registration service that controls access to the image
- It will work better with cluster autoscaling than with manual node configuration.
- Or, in a cluster where changing the node configuration is inconvenient, use imagePullSecrets.
private registry
-
- Cluster with proprietary images, some of which require tighter access control.
- Ensure that the AlwaysPullImages admission handler is active. Otherwise, all Pods potentially have access to all images.
- Move sensitive data to a “Secret” resource, instead of packaging it into an image.
- A multi-tenant cluster where each tenant needs its own private record.
- Ensure that the AlwaysPullImages admission handler is active. Otherwise, all Pods from all tenants have potential access to all images.
- Run a private registry with required authorization.
- Generate registry credentials for each tenant, place them secretly, and populate the secret in each tenant namespace.
- The tenant adds that secret to imagePullSecrets in each namespace.
A cluster that
If you need access to multiple records, you can create a secret for each record.
What’s Next
- Read the OCI image manifest specification
- about garbage collection of container images
- Learn how to extract an image from a private record.
. Learn
.