4 minutes
Kubernetes: Flux image auto update using HelmReleases
How to set FLUX auto image update using ECR as a registry for helm packages and docker images, Flux will use HelmRelease for detecting changes.
Necessary Tools
- AWS CLI version 2.9.2 or newer
- Flux version 0.38.2 or newer
Requirements
- Repository on ECR for docker images (https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html)
- Repository on ECR for helm packages (https://docs.aws.amazon.com/AmazonECR/latest/userguide/push-oci-artifact.html)
Install Flux
Flux bootstrap command (using a github token with all repo access permissions):
flux bootstrap github \
--owner=$GITHUB-ACCOUNT-NAME \
--repository=$REPOSITORY-NAME \
--path=clusters/$CLUSTER-NAME \
--components-extra=image-reflector-controller,image-automation-controller \
--personal
FLUX configuration
- Use the CRD ImageRepository to track your image:
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageRepository
metadata:
name: $NAME-IMAGE-REPOSITORY
namespace: flux-system
spec:
image: $AWS-ACCOUNT-ID.dkr.ecr.$AWS-REGION.amazonaws.com/$REPOSITORY-NAME
interval: 1m0s
- Also, you need to make the cluster able to do this, if not you’ll get a permissions error. In your GitOps repository add a
patch
tokustomization.yaml
belong toflux-system
(more details about it here):
patches:
- target:
version: v1
group: apps
kind: Deployment
name: image-reflector-controller
namespace: flux-system
patch: |-
- op: add
path: /spec/template/spec/containers/0/args/-
value: --aws-autologin-for-ecr
- Use the CRD ImagePolicy to specify which version you want to track, there are plenty ways to filter tags here. I’m tagging images using this prefix
dev-1675960453
the number on the prefix it’s the current date, so each new image it’s going to have a greater number in the tag, I made this using bashdev-$(date +%s)
. The following policy is detecting this pattern and extracting the timestamp, which is sorted by numerical ascendant order to identify the last one.
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImagePolicy
metadata:
name: $
namespace: flux-system
spec:
imageRepositoryRef:
name: $NAME-IMAGE-POLICY
filterTags:
pattern: '^dev-(?P<ts>.*)'
extract: '$ts'
policy:
numerical:
order: asc
- You can check that the tracking works as expected by running the following commands,
READY
should be True for both, if it’sFalse
, inMESSAGE
you can see the reason
flux get image policy $NAME-IMAGE-POLICY
flux get image repository $NAME-IMAGE-REPOSITORY
- Preparing your HelmRelease file/configuration for Flux image update, this part is very important to get this done.
HelmRepository file example:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: $NAME-HELM-REPOSITORY
namespace: $NAMESPACE
spec:
type: oci
interval: 1m
url: oci://$AWS-ACCOUNT-ID.dkr.ecr.$AWS-REGION.amazonaws.com
provider: aws
HelmRelease file example:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: $NAME-HELM-RELEASE
namespace: $NAMESPACE
spec:
interval: 5m
chart:
spec:
chart: $CHART-NAME
version: "0.1.0"
sourceRef:
kind: HelmRepository
name: $NAME-IMAGE-REPOSITORY
namespace: $NAMESPACE
interval: 1m
valuesFrom:
- kind: ConfigMap
name: $NAME-CONFIGMAP
HelmRelease only upgrades resources if helm chart version changes. In order to make image update works we have to generate a dynamic name for our ConfigMap so any time the repository receives a push then this name change and will trigger a new release.
In the same folder where is your helmrelease and kustomization, create/edit the following files:
kustomizeconfig.yaml
nameReference:
- kind: ConfigMap
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: $NAMESPACE
resources:
- namespace.yaml
- repository.yaml
- release.yaml
configMapGenerator:
- name: $NAME-CONFIGMAP
files:
- values.yaml=NAME-FILE-WITH-VALUES.yaml
configurations:
- kustomizeconfig.yaml
file with custom values:
Deployment:
imagePullPolicy: Always
image: $AWS-ACCOUNT-ID.dkr.ecr.$AWS-REGION.amazonaws.com/$REPOSITORY-NAME:$TAG # {"$imagepolicy": "POLICY_NAMESPACE:POLICY_NAME"}
Notice that in line image
we are telling Flux which image would need to be updated, to do so, you need to add a marker to the line with image, this marker can be added to any part of the GitOps repository in any file.
- Check if deploy key has write access in GitHub, go to github repository and then to settings/Deploy Keys the Deploy key should say Read/Write, if not, Delete the current one, run
$ kubectl -n flux-system get secret flux-system -o json | jq '.data."identity.pub"' -r | base64 -d
the output of this command is the key that you will add as a deploy key, make sure mark the option “Allow write access”. Add a new resource called ImageUpdateAutomation, this will commit the new tag where you wrote the marker{"$imagepolicy": "POLICY_NAMESPACE:POLICY_NAME"}
.
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
name: flux-system
namespace: flux-system
spec:
git:
checkout:
ref:
branch: main
commit:
author:
email: fluxcdbot@users.noreply.github.com
name: fluxcdbot
messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}'
push:
branch: main
interval: 1m0s
sourceRef:
kind: GitRepository
name: flux-system
update:
strategy: Setters
- Push a new image with the tag mentioned before and then you will see a new release on k8s cluster.
References
- https://fluxcd.io/flux/guides/image-update
- https://fluxcd.io/flux/guides/helmreleases/#refer-to-values-in-configmaps-generated-with-kustomize