Digester
Digester resolves tags to
digests for
container and initContainer images in Kubernetes
Pods and
Pod templates.
It replaces container image references that use tags:
spec:
containers:
- image: gcr.io/google_samples/hello-app:1.0
With references that use the image digest:
spec:
containers:
- image: gcr.io/google_samples/hello-app:1.0@sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4
Digester can run either as a
mutating admission webhook
in a Kubernetes cluster, or as a client-side
config function
with the kpt or
kustomize
command-line tools.
If a tag points to an
image index
or
manifest list,
digester resolves the tag to the digest of the image index or manifest list.
The webhook is opt-in at the namespace level by label, see
Deploying the webhook.
If you use
Binary Authorization,
digester can help to ensure that only verified container images can be deployed
to your clusters. A Binary Authorization
attestation
is valid for a particular container image digest. You must deploy container
images by digest so that Binary Authorization can verify the attestations for
the container image. You can use digester as both a config function and a
mutating webhook to deploy container images by digest.
Running the config function
-
Download the digester binary for your platform from the
Releases page.
Alternatively, you can download the latest version using these commands:
VERSION=$(curl -s https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r '.tag_name')
curl -Lo digester "https://github.com/google/k8s-digester/releases/download/$VERSION/digester_$(uname -s)_$(uname -m)"
chmod +x digester
-
Install kpt
and/or
kustomize:
gcloud components install kpt kustomize --quiet
For alternative installation options, see the documentation for
installing kpt
and
installing kustomize.
-
Run the digester config function using either
kpt or
kustomize:
-
Using the kpt
exec runtime:
kpt fn source [manifest files or directory] \
| kpt fn run --enable-exec --exec-path ./digester
-
Using kustomize:
kustomize fn source [manifest files or directory] \
| kustomize fn run --enable-exec --exec-path ./digester
By running as an executable, the config function has access to container
image registry credentials in the current environment, such as the current
user's
Docker config file
and
credential helpers.
For more information, see the digester documentation on
Authenticating to container image registries.
Deploying the webhook
You need a Kubernetes cluster version 1.16 or later.
-
Grant yourself the cluster-admin
Kubernetes
cluster role:
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole cluster-admin \
--user "$(gcloud config get-value core/account)"
-
Install kpt:
gcloud components install kpt --quiet
-
Look up the latest version of digester:
VERSION=$(curl -s https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r '.tag_name')
-
Get the digester webhook kpt package and store the files in a directory
called manifests
:
kpt pkg get \
https://github.com/google/k8s-digester.git/manifests@$VERSION \
manifests
-
Deploy the webhook:
kpt live apply manifests/ --reconcile-timeout=5m --output=table
-
Add the digest-resolution: enabled
label to namespaces where you want the
webhook to resolve tags to digests:
kubectl label namespace [NAMESPACE] digest-resolution=enabled
Private clusters
You must add a firewall rule if you install the webhook in a
private Google Kubernetes Engine (GKE) cluster,
In a private cluster, the cluster nodes only have
internal IP addresses.
The firewall rule allows the API server to access the webhook running on port
8443 on the cluster nodes.
-
Create an environment variable called CLUSTER
. The value is the name of
your cluster that you see when running gcloud container clusters list
:
CLUSTER=[your private GKE cluster name]
-
Look up the IP address range for the cluster API server and store it in an
environment variable:
API_SERVER_CIDR=$(gcloud container clusters describe $CLUSTER \
--format 'value(privateClusterConfig.masterIpv4CidrBlock)')
-
Look up the
network tags
for your cluster nodes and store them comma-separated in an environment
variable:
TARGET_TAGS=$(gcloud compute firewall-rules list \
--filter "name~^gke-$CLUSTER" \
--format 'value(targetTags)' | uniq | paste -d, -s -)
-
Create a firewall rule that allow traffic from the API server to cluster
nodes on TCP port 8443:
gcloud compute firewall-rules create allow-api-server-to-digester-webhook \
--action ALLOW \
--direction INGRESS \
--source-ranges "$API_SERVER_CIDR" \
--rules tcp:8443 \
--target-tags "$TARGET_TAGS"
You can read more about private cluster firewall rules in the
GKE private cluster documentation.
Deploying using kubectl
We recommend deploying the webhook using kpt as described above. If you are
unable to use kpt, you can deploy the digester using kubectl:
git clone https://github.com/google/k8s-digester.git digester
cd digester
VERSION=$(curl -s https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r '.tag_name')
git checkout $VERSION
kubectl apply -f manifests/namespace.yaml
kubectl apply -f manifests/
Documentation
Disclaimer
This is not an officially supported Google product.