dir="$(mktemp -d)" openshift start master --write-config="${dir}" && \ sed -n '/^\s*allowedRegistriesForImport/,/^\s*[a-z]/p' "${dir}/master-config.yaml" && \ rm -rf "${dir}"
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 registry
You can configure registries allowed for import in master-config.yaml
under the imagePolicyConfig:allowedRegistriesForImport
section as demonstrated in
the following example. If the setting is not present, all images are allowed.
The advanced installation
does not generate the setting, therefore it whitelists all registries. However,
the OpenShift master API spawned without any configuration file will use the
recommended list of registries.
The full recommended list of registries can be listed by writing out the configuration file:
dir="$(mktemp -d)" openshift start master --write-config="${dir}" && \ sed -n '/^\s*allowedRegistriesForImport/,/^\s*[a-z]/p' "${dir}/master-config.yaml" && \ rm -rf "${dir}"
imagePolicyConfig:
allowedRegistriesForImport:
-
domainName: registry.access.redhat.com (1)
-
domainName: *.mydomain.com
insecure: true (2)
-
domainName: local.registry.corp:5000 (3)
1 | Allow any image from the specified secure registry. |
2 | Allow any image from any insecure registry hosted on any sub-domain of
mydomain.com . The mydomain.com is not whitelisted. |
3 | Allow any image from the given registry with port specified. |
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 from domainName
. If true, the domainName
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 the mydomain.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 match 5000
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.access.redhat.com:443" * status.tags[latest].items[0].dockerImageReference: Forbidden: registry "local.registry.corp" not allowed by whitelist: "local.registry.corp:5000", "*.mydomain.com:80", "registry.access.redhat.com:443"
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:
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 is reject: 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.4 ) to
be interpreted as namespace-local image stream tags, but only if the resource or
target image stream has
local name resolution enabled. |
If you normally rely on infrastructure images being pulled using a default
registry prefix (such as docker.io or registry.access.redhat.com), those
images will not match to any |
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)
1 | Admission plug-in name. |
2 | Specify false to indicate that the plug-in should be enabled. |
Restart master services running in control plane static Pods using the master-restart
command:
$ systemctl restart atomic-openshift-master-api.service $ systemctl restart atomic-openshift-master-controllers
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 for
oc 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