Using Init Containers with Chainguard Containers
Example showing how to use an init container to configure Chainguard's minimal nginx container image.
Gatekeeper is an admission controller that enforces policies in Kubernetes clusters. This article describes how it can be leveraged to ensure resources follow best practices related to the use of Chainguard Containers.
To follow the examples in this guide, you will need the following:
kubectl
— the command line interface tool for Kubernetes — installed on your local machine.You can use the K8sAllowedReposV2
constraint from the Gatekeeper Library to ensure that images are only pulled from a list of allowed repositories.
To configure this constraint, add the constraint template to your cluster.
kubectl create -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/refs/heads/master/library/general/allowedreposv2/template.yaml
Then, create a constraint that only allows images hosted in cgr.dev
. Note that if you are mirroring Chainguard container images into a different registry, then you could replace this with your own URLs:
kubectl create -f - <<EOF
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedReposv2
metadata:
name: repo-is-cgr-dev
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces:
- "kube-system"
parameters:
allowedImages:
- "cgr.dev/*"
EOF
Note that you may not be able to control where images provided by the platform are hosted in certain managed Kubernetes solutions.
To test that this constraint is working correctly, try to create a non-compliant pod:
kubectl create -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx-disallowed
spec:
containers:
- name: nginx
image: nginx
EOF
Error from server (Forbidden): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [repo-is-cgr-dev] container <nginx> has an invalid image <nginx>, allowed images are ["cgr.dev/*"]
This example tries to create a pod using a container image downloaded from the Docker Hub registry, not Chainguard’s registry. As this output indicates, attempting to create a non-compliant pod resulted in an error, and the request was denied.
Chainguard Containers are updated frequently to incorporate CVE fixes and package updates. The tags for Chainguard’s container images are highly mutable, meaning that the underlying image changes frequently, even for very specific tags like v1.2.3-r1
.
To prevent the risk of updates introducing breaking changes, you can pull by digest to ensure the use of a specific image.
The K8sImageDigests
constraint from the Gatekeeper Library can be used to mandate this practice inside a Kubernetes cluster.
Add the template to your cluster:
kubectl create -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/refs/heads/master/library/general/imagedigests/template.yaml
Then create the constraint:
kubectl create -f - <<EOF
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sImageDigests
metadata:
name: container-image-must-have-digest
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces:
- "kube-system"
EOF
Be aware that in certain managed Kubernetes solutions, you may not be able to control whether images provided by the platform are referenced by digest.
To test the constraint, try to create a non-compliant pod:
kubectl create -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx-disallowed
spec:
containers:
- name: nginx
image: cgr.dev/chainguard/nginx
EOF
Error from server (Forbidden): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [container-image-must-have-digest] container <nginx> uses an image without a digest <cgr.dev/chainguard/nginx>
This example attempts to create a pod using the nginx
Chainguard container image, but does not pull the image by its digest as required by the constraint. As the output indicates, the attempt resulted in an error and the request was denied.
When introducing new constraints into a cluster, it is a good idea to initially configure them with enforcementAction: warn
so as to avoid blocking existing workloads.
This way, when a user creates a non-compliant resource, they will get a warning like the following example. This gives the user a signal that they should update their configuration.
Warning: [container-image-must-have-digest] container <nginx> uses an image without a digest <cgr.dev/chainguard/nginx>
You can also find non-compliant resources that exist in the cluster by reviewing the constraint’s violations:
kubectl get k8simagedigests container-image-must-have-digest -o json | jq -r '.status.violations[]'
{
"enforcementAction": "warn",
"group": "",
"kind": "Pod",
"message": "container <nginx> uses an image without a digest <cgr.dev/chainguard/nginx>",
"name": "nginx-disallowed",
"namespace": "default",
"version": "v1"
}
Once all the violations have been addressed, you can remove enforcementAction: warn
and Gatekeeper will start to block the creation of resources that violate the constraint.
By combining OPA Gatekeeper with Chainguard container images, you gain a powerful way to enforce security and compliance across your Kubernetes clusters. Gatekeeper ensures that only container images meeting your defined policies are deployed, while Chainguard Containers provide a minimal, hardened foundation to reduce risk from the start. Together, they help teams ship software more securely and confidently, without slowing down development.
If you’d like to learn more about Gatekeeper, we encourage you to refer to the official documentation.
Last updated: 2025-09-02 10:00