Chapter 11. Image Policy
11.1. Overview
You can control which images can be imported, tagged, and run in a cluster. There are two facilities for this purpose.
Allowed Registries for import is an image policy configuration that allows you to restrict image origins to particular set of external registries. This set of rules is applied to any image being imported or tagged into any image stream. Therefore any image referencing registry not matched by the rule set will be rejected.
ImagePolicy admission plug-in lets you specify which images are allowed to be run on your cluster. This is currently considered beta. It allows you to control:
- Image sources: which registries can be used to pull images
- Image resolution: force pods to run with immutable digests to ensure the image does not change due to a re-tag
- Container image label restrictions: limits or requires labels on an image
- Image annotation restrictions: limits or requires the annotations on an image in the integrated container image registry
11.2. Configuring Registries Allowed for Import
You can configure registries allowed for import in master-config.yaml under imagePolicyConfig:allowedRegistriesForImport
section as demonstrated in the following example. If the setting is not present, all images are allowed, which is the default.
Example 11.1. Example Configuration of Registries Allowed for Import
imagePolicyConfig: allowedRegistriesForImport: - domainName: registry.redhat.io 1 - domainName: *.mydomain.com insecure: true 2 - domainName: local.registry.corp:5000 3
Each rule is composed of the following attributes:
-
domainName
: is a hostname optionally terminated by:<port>
suffix where special wildcard characters (?
,*
) are recognized. The former matches a sequence of characters of any length while the later matches exactly one character. The wildcard characters can be present both before and after:
separator. The wildcards apply only to the part before or after the separator regardless of separator’s presence. -
insecure
: is a boolean used to decide which ports are matched if the:<port>
part is missing fromdomainName
. If true, thedomainName
will match registries with:80
suffix or unspecified port as long as the insecure flag is used during import. If false, registries with:443
suffix or unspecified port will be matched.
If a rule should match both secure and insecure ports of the same domain, the rule must be listed twice (once with insecure=true
and once with insecure=false
.
Unqualified images references are qualified to docker.io
before any rule evaluation. To whitelist them, use domainName: docker.io
.
domainName: *
rule matches any registry hostname, but port is still restricted to 443
. To match arbitrary registry serving on arbitrary port, use domainName: *:*
.
Based on the rules established in Example Configuration of Registries Allowed for Import:
-
oc tag --insecure reg.mydomain.com/app:v1 app:v1
is whitelisted by the handling of themydomain.com
rule -
oc import-image --from reg1.mydomain.com:80/foo foo:latest
will be also whitelisted -
oc tag local.registry.corp/bar bar:latest
will be rejected because the port does not match5000
in the third rule
Rejected image imports will generate error messages similar to the following text:
The ImageStream "bar" is invalid: * spec.tags[latest].from.name: Forbidden: registry "local.registry.corp" not allowed by whitelist: "local.registry.corp:5000", "*.mydomain.com:80", "registry.redhat.io:443" * status.tags[latest].items[0].dockerImageReference: Forbidden: registry "local.registry.corp" not allowed by whitelist: "local.registry.corp:5000", "*.mydomain.com:80", "registry.redhat.io:443"
11.3. Configuring the ImagePolicy Admission Plug-in
To configure which images can run on your cluster, configure the ImagePolicy Admission plug-in in the master-config.yaml
file. You can set one or more rules as required.
Reject images with a particular annotation:
Use this rule to reject all images that have a specific annotation set on them. The following rejects all images using the
images.openshift.io/deny-execution
annotation:- name: execution-denied onResources: - resource: pods - resource: builds reject: true matchImageAnnotations: - key: images.openshift.io/deny-execution 1 value: "true" skipOnResolutionFailure: true
- 1
- If a particular image has been deemed harmful, administrators can set this annotation to flag those images.
Enable user to run images from Docker Hub:
Use this rule to allow users to use images from Docker Hub:
- name: allow-images-from-dockerhub onResources: - resource: pods - resource: builds matchRegistries: - docker.io
Following is an example configuration for setting multiple ImagePolicy addmission plugin rules in the master-config.yaml
file:
Annotated Example File
admissionConfig: pluginConfig: openshift.io/ImagePolicy: configuration: kind: ImagePolicyConfig apiVersion: v1 resolveImages: AttemptRewrite 1 executionRules: 2 - name: execution-denied # Reject all images that have the annotation images.openshift.io/deny-execution set to true. # This annotation may be set by infrastructure that wishes to flag particular images as dangerous onResources: 3 - resource: pods - resource: builds reject: true 4 matchImageAnnotations: 5 - key: images.openshift.io/deny-execution value: "true" skipOnResolutionFailure: true 6 - name: allow-images-from-internal-registry # allows images from the internal registry and tries to resolve them onResources: - resource: pods - resource: builds matchIntegratedRegistry: true - name: allow-images-from-dockerhub onResources: - resource: pods - resource: builds matchRegistries: - docker.io resolutionRules: 7 - targetResource: resource: pods localNames: true policy: AttemptRewrite - targetResource: 8 group: batch resource: jobs localNames: true 9 policy: AttemptRewrite
- 1
- Try to resolve images to an immutable image digest and update the image pull specification in the pod.
- 2
- Array of rules to evaluate against incoming resources. If you only have
reject: true
rules, the default is allow all. If you have any accept rule, that isreject: false
in any of the rules, the default behaviour of the ImagePolicy switches to deny-all. - 3
- Indicates which resources to enforce rules upon. If nothing is specified, the default is pods.
- 4
- Indicates that if this rule matches, the pod should be rejected.
- 5
- List of annotations to match on the image object’s metadata.
- 6
- If you are not able to resolve the image, do not fail the pod.
- 7
- Array of rules allowing use of image streams in Kubernetes resources. The default configuration allows pods, replicationcontrollers, replicasets, statefulsets, daemonsets, deployments, and jobs to use same-project image stream tag references in their image fields.
- 8
- Identifies the group and resource to which this rule applies. If resource is
*
, this rule will apply to all resources in that group. - 9
LocalNames
will allow single segment names (for example,ruby:2.5
) to be interpreted as namespace-local image stream tags, but only if the resource or target image stream haslocal name resolution
enabled.
If you normally rely on infrastructure images being pulled using a default registry prefix (such as docker.io or registry.redhat.io), those images will not match to any matchRegistries
value since they will have no registry prefix. To ensure infrastructure images have a registry prefix that can match your image policy, set the imageConfig.format value in your master-config.yaml
file.
11.4. Using an Admission Controller to Always Pull Images
After an image is pulled to a node, any Pod on that node from any user can use the image without an authorization check against the image. To ensure that Pods do not use images for which they do not have credentials, use the AlwaysPullImages admission controller.
This admission controller modifies every new Pod to force the image pull policy to Always
, ensuring that private images can only be used by those who have the credentials to pull them, even if the Pod specification uses an image pull policy of Never
.
To enable the AlwaysPullImages admission controller:
Add the following to the
master-config.yaml
:admissionConfig: pluginConfig: AlwaysPullImages: 1 configuration: kind: DefaultAdmissionConfig apiVersion: v1 disable: false 2
Restart master services running in control plane static Pods using the
master-restart
command:$ master-restart api $ master-restart controllers
11.5. Testing the ImagePolicy Admission Plug-in
Use the
openshift/image-policy-check
to test your configuration.For example, use the information above, then test like this:
$ oc import-image openshift/image-policy-check:latest --confirm
Create a pod using this YAML. The pod should be created.
apiVersion: v1 kind: Pod metadata: generateName: test-pod spec: containers: - image: docker.io/openshift/image-policy-check:latest name: first
Create another pod pointing to a different registry. The pod should be rejected.
apiVersion: v1 kind: Pod metadata: generateName: test-pod spec: containers: - image: different-registry/openshift/image-policy-check:latest name: first
Create a pod pointing to the internal registry using the imported image. The pod should be created and if you look at the image specification, you should see a digest in place of the tag.
apiVersion: v1 kind: Pod metadata: generateName: test-pod spec: containers: - image: <internal registry IP>:5000/<namespace>/image-policy-check:latest name: first
Create a pod pointing to the internal registry using the imported image. The pod should be created and if you look at the image specification, you should see the tag unmodified.
apiVersion: v1 kind: Pod metadata: generateName: test-pod spec: containers: - image: <internal registry IP>:5000/<namespace>/image-policy-check:v1 name: first
Get the digest from
oc get istag/image-policy-check:latest
and use it foroc annotate images/<digest> images.openshift.io/deny-execution=true
. For example:$ oc annotate images/sha256:09ce3d8b5b63595ffca6636c7daefb1a615a7c0e3f8ea68e5db044a9340d6ba8 images.openshift.io/deny-execution=true
Create this pod again, and you should see the pod rejected:
apiVersion: v1 kind: Pod metadata: generateName: test-pod spec: containers: - image: <internal registry IP>:5000/<namespace>/image-policy-check:latest name: first