| Crates.io | kube-autorollout |
| lib.rs | kube-autorollout |
| version | 0.4.3 |
| created_at | 2025-10-05 21:18:17.269159+00 |
| updated_at | 2025-11-13 19:52:56.036391+00 |
| description | A lightweight Kubernetes controller that automatically triggers Kubernetes deployment rollouts when container image digests change, ensuring your applications stay up-to-date without manual intervention 🚀 |
| homepage | https://github.com/juv/kube-autorollout |
| repository | https://github.com/juv/kube-autorollout |
| max_upload_size | |
| id | 1869462 |
| size | 218,626 |
A lightweight Kubernetes controller that automatically triggers Kubernetes Deployment/StatefulSet/DaemonSet
rollouts when container image digests change, ensuring your applications stay up-to-date without manual intervention
🚀
kube-autorollout monitors Kubernetes resources of kind Deployment/StatefulSet/DaemonSet and automatically triggers
rollouts when new container image versions are available. Unlike other image update mechanisms that require changing
tags via semver version bump, this tool
is built to compare container image digests (@sha256:...) for
static / mutable tags (e.g., latest, main, nightly).
Benefits of kube-autorollout:
latest, main, nightly, etc. to ensure
your up-to-date baseline is being executed in the Kubernetes cluster. Particularly suited for development
environments.Deployment/StatefulSet/DaemonSet resources for auto-rollouts by adding the label
kube-autorollout/enabled=truelatest, main, nightly//todo: add diagram, description
kube-autorollout is supposed to be installed using the Helm chart.
kube-autorollout is supposed to be installed in each Kubernetes namespace where you want to enable automated rollouts.
The Helm Chart is available on Artifact Hub:
Add the label kube-autorollout/enabled=true to any of your Deployment/StatefulSet/DaemonSet resources.
That's it. Your pods can have any number of containers. Your image tag can be any static tag, it does not necessarily be
latest, as shown in the snippet below.
kube-autorollout will print warnings into the log for containers that do not set imagePullPolicy: Always. Make sure
you set that imagePullPolicy, otherwise the updated
image is not guaruanteed to be downloaded by
the kubelet
upon next pod creation. Example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
kube-autorollout/enabled: "true"
spec:
# ...
template:
# ...
spec:
containers:
- name: my-app
image: ghcr.io/myorg/my-app:latest
imagePullPolicy: Always
# ...
- name: another-container
image: ghcr.io/another-org/whatever:main
imagePullPolicy: Always
To ensure compatibility to the state drift detection in GitOps tools like ArgoCD and FluxCD, enable the feature flag
enableKubectlAnnotation in your Helm Chart values file:
#...
config:
#...
featureFlags:
#...
enableKubectlAnnotation: true
This changes the kube-autorollout patch annotation key (that internally triggers the redeployment of the pods) from
kube-autorollout/restartedAt to kubectl.kubernetes.io/restartedAt.
The latter annotation is applied by kubectl when executing the command kubectl rollout restart.
Most GitOps tools like ArgoCD and FluxCD ignore the kubectl annotation from state drift detection. If you are not using
this value on "true" you might need to add further configuration to ArgoCD and FluxCD to not show the kube-autorollout
annotation as a state drift.
When connecting to private registries that present a TLS certificate that is not signed by a well-known/public certificate authority, you need to provide the custom ca certificates as part of the Helm Chart values.
#...
config:
#...
tls:
customCaCertificates:
enabled: true
secrets:
- # -- The name of the secret to reference that includes the custom CA certificate chain
name: custom-ca-01-secret
# -- The key / subPath within the secret to mount in kube-autorollout
subPath: ca-01.crt
# -- The mountPath within kube-autoroll, will be auto-wired in the config
mountPath: /etc/secrets/ca/custom-ca-01.crt
This snippet will mount the subPath ca-01.crt of Kubernetes secret custom-ca-01-secret into the kube-autorollout
pod. The mountPath needs to be a unique value when multiple ca certificates are mounted. The Helm Chart is auto-wiring
all mountPath values into the config file automatically.
kube-autorollout expects your Kubernetes secrets to be existing before installing the Helm chart. For a quick start, you can create the above-mentioned secret example like this:
kubectl create secret generic custom-ca-01-secret --from-file=ca-01.crt={path/to/ca-01.crt}
kube-autorollout will automatically pick up the pod's imagePullSecrets by default and find the correct secret
to authenticate to the registry to request the recent image digests. If you chose to disable the "get" permission on
Secret resources by disabling the Helm value rbac.secrets.enabled, you will need to manually specify the registry
configuration as shown below.
Create a Helm values file/override that covers all registries for the supported Kubernetes resource kinds that are
labeled with kube-autorollout/enabled=true. For some quick examples, see the snippet below.
For full field reference, see the Helm chart README.
#...
config:
registries:
# -- GitHub container registry with ImagePullSecret
- hostnamePattern: "ghcr.io"
secret:
# -- REQUIRED: The type of the secret - ImagePullSecret, Opaque, None. <ImagePullSecret> must define keys "name" and "mountPath". <Opaque> with Kubernetes Secret must define keys "name" and "key", optionally "username". <Opaque> with hardcoded token must define keys "token". <None> will ignore authentication to the registry.
type: ImagePullSecret
# -- ImagePullSecret secret name to reference that contains the ghcr.io docker config
name: ghcr-io-registry-creds
# -- REQUIRED FOR <ImagePullSecret>: The mount path of the ImagePullSecret within the kube-autorollout pod. Must be unique across registry secrets.
mountPath: /etc/secrets/registries/ghcr.io
# -- DockerHub registry with ImagePullSecret, covers both docker.io and registry-1.docker.io
- hostnamePattern: "docker.io"
secret:
type: ImagePullSecret
name: docker-io-registry-creds
mountPath: /etc/secrets/registries/docker.io
# -- Wildcard-match for JFrog Artifactory registry with "subdomain method for docker" https://jfrog.com/help/r/jfrog-artifactory-documentation/the-subdomain-method-for-docker
- hostnamePattern: "*.artifactory.example.com"
secret:
type: Opaque
# -- Kubernetes Secret name of secret type Opaque to reference. The secret should contain the Docker Registry API token, personal access token, JFrog Artifactory identity token, etc.
name: jfrog-artifactory-registry-creds
# -- OPTIONAL FOR <Opaque>: The key to reference of the secret. Will be referenced in the config automatically if .token is unset
key: IDENTITY_TOKEN
# -- JFrog Artifactory registry with "repository path method for docker" https://jfrog.com/help/r/jfrog-artifactory-documentation/the-repository-path-method-for-docker
- hostnamePattern: "another-artifactory.example.com"
secret:
name: jfrog-artifactory-registry-creds
key: IDENTITY_TOKEN
featureFlags:
# -- Enables an automated fallback for Artifactory's "repository path method for docker" setup
enableJfrogArtifactoryFallback: true
kube-autorollout expects your Kubernetes secrets to be existing before installing the Helm chart. For a quick start, you can create the above-mentioned secret examples like this:
JFrog Artifactory, secret type Opaque:
kubectl create secret generic jfrog-artifactory-registry-creds --from-literal=IDENTITY_TOKEN=<jfrog-identity-token-here>
GitHub personal access token, secret type ImagePullSecret:
kubectl create secret docker-registry ghcr-io-registry-creds --docker-server=https://ghcr.io --docker-username=<github-username-here> --docker-password=<github-personal-access-token-here>
Docker personal access token, secret type ImagePullSecret:
kubectl create secret docker-registry docker-io-registry-creds --docker-server=https://docker.io --docker-username=<docker-io-username-here> --docker-password=<docker-io-personal-access-token-here>
kube-autorollout requires permissions to query the Kubernetes API server to do its job. The Helm Chart will create a
least-privilege Role, RoleBinding and ServiceAccount to run the application with per default.
More specifically, the application requires get/list/patch permissions for deployments, statefulsets and
daemonsets. On top of that, get and list permissions are required for pods.
The patch permission is required to patch the resource's rollout annotation in field
.spec.template.metadata.annotations. That is key kube-autorollout/restartedAt or
kubectl.kubernetes.io/restartedAt depending on your config.
Per default, the Helm Chart also grants the verb get on secrets. The kube-autorollout application needs this to
iterate through the list of the individual pod's imagePullSecrets to determine the correct registry credentials that
were used to pull the image. With the same credentials, the recent image digests will then be requested from the
registry. This can be disabled by setting the field .rbac.secrets.enabled to false in the Helm Chart. However, if
you choose to do so, you need to manually specify all registry configurations as shown in section Advanced registry
configuration.
In case you do not want to use any the default RBAC config that comes with the Helm Chart (enabled by default in the
values.yaml), make sure to grant proper rolebinding to the service account that you use to run kube-autorollout with.
Set rbac.enabled to false in your values file to disable the default RBAC configuration.
See role.yaml for reference.
rules:
- apiGroups: [ "" ]
resources: [ "pods" ]
verbs: [ "get", "list" ]
- apiGroups: [ "apps" ]
resources: [ "deployments", "statefulsets", "daemonsets" ]
verbs: [ "get", "list", "patch" ]
{ { - if .Values.rbac.secrets.enabled } }
- apiGroups: [ "" ]
resources: [ "secrets" ]
verbs: [ "get" ]
{ { - end } }
docker.io / registry-1.docker.io) - Requires username and personal access tokenghcr.io) - Requires username and personal access tokenOther registries are untested but likely work in some combination as long as they follow the the OCI Distribution Specification.
kube-autorollout contains end-to-end tests in the CI workflow for at least the most recent three minor releases of Kubernetes. Essentially, a similar support coverage is provided as described in the Kubernetes release version maintenance.
| Kubernetes Version | Support Status | Test environment | Registry |
|---|---|---|---|
| v1.31 | Supported ✔️ | k3d v5.8.3, k8s v1.31.13 | GHCR |
| v1.32 | Supported ✔️ | k3d v5.8.3, k8s v1.32.9 | GHCR |
| v1.33 | Supported ✔️ | k3d v5.8.3, k8s v1.33.5 | GHCR |
| v1.34 | Supported ✔️ | k3d v5.8.3, k8s v1.34.1 | GHCR |
todo
Registry authentication failures
No rollouts occur
kube-autorollout/enabled=true label is present on each Kubernetes resource of interestserviceaccount in case you are not using the
rbac.enabled=true Helm chart configurationThis project is licensed under the Apache License 2.0 - see LICENSE.
# Clone the repository
git clone https://github.com/juv/kube-autorollout.git
cd kube-autorollout
# Build the binary
cargo build --release
# Build Docker image
docker build -t kube-autorollout:latest .
# Run tests
cargo test
To execute kube-autorollout locally, set these environment variables:
CONFIG_FILE: Required -- the file path to the config file. Config example:cronSchedule: "*/45 * * * * *"
webserver:
port: 8080
registries:
- hostnamePattern: "docker.io"
secret:
type: ImagePullSecret
mountPath: "C:/Users/<YourUser>/Desktop/kube-autorollout/docker-io"
- hostnamePattern: "*.artifactory.example.com"
secret:
type: Opaque
token: ${REGISTRY_TOKEN}
- hostnamePattern: "ghcr.io"
secret:
type: ImagePullSecret
mountPath: "C:/Users/<YourUser>/Desktop/kube-autorollout/ghcr-io"
tls:
caCertificatePaths: [ ]
featureFlags:
enableJfrogArtifactoryFallback: false
enableKubectlAnnotation: false
Opaque should be present as environment variables and referenced in the application config
using ${ENV_VAR_NAME} syntaxImagePullSecret must include a mountPath that points to an existing folder, which
includes a file .dockerconfigjson with a content like this:{
"auths": {
"your.private.registry.example.com": {
"username": "janedoe",
"password": "xxxxxxxxxxx",
"email": "jdoe@example.com",
"auth": "c3R...zE2"
}
}
}