metalstack cloud

Automating Image Deployment with Flux

Prerequisites

Before diving into the specifics of automating image deployment with Flux, it is essential to have a basic understanding of how Flux operates within a Kubernetes environment. If you are new to Flux, begin by setting up Flux in your Cluster.

To follow along with this tutorial, you can clone the repository, which includes all necessary files expect the bootstraped flux manifests:

git clone https://github.com/x-cellent/Flux-Developerguide
cd Flux-Developerguide

We will use Github Image Registry for this.

Extending Flux Functionality

Remember how we used Flux for deployments? Let’s supercharge it! Run this command to enable automatic image updates:

flux bootstrap github \
  --token-auth \
  --components-extra=image-reflector-controller,image-automation-controller  \
  --owner=$GITHUB_USER \
  --repository=your-repository-name \
  --branch=master \
  --path=manifests \
  --personal # (just needed if it's your personal GitHub account)

With the additional components image-reflector-controller and image-automation-controller, Flux gains the ability to manage image updates automatically.

Configuration Files

In order to use the Github Container Registry you have to create a CI, that packages your application in a docker image, which is then pushed to the registry. Getting into specifics of the CI is out of scope for this tutorial, for the full CI refer to the Repository linked at the top of the guide.

To better understand how the GitHub Container Registry works, you can refer to the GitHub Packages Documentation.

Create a Secret to Access the Image Registry

export DOCKER_USERNAME=<your-username>
export DOCKER_PASSWORD=<your-token> # This is the token you created in the last tutorial
kubectl create secret docker-registry ghcr-secret \
  --namespace web \
  --docker-server=ghcr.io  \
  --docker-username=$DOCKER_USERNAME \
  --docker-password=$DOCKER_PASSWORD 

Create a new secret for the Flux Bot

Now we also have to create a secret so the Flux bot can commit to the repository. For that we will create a Fine Grained Token with the following permissions. Be sure to save your token, as you’ll need it for the next step.

  1. Administration -> Access: Read-only
  2. Contents -> Access: Read and write
  3. Metadata -> Access: Read-only

GitHub Token Image

Create Git Secret and Repository

Create the secret with the token you created in the last step and your Github username.

kubectl create secret generic git-secret \
--from-literal=username=your-github-username \
--from-literal=password=your-token -n web

Now also add a new yaml to your manifest, this will be used to define which Git Repository the Flux bot will work with.

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: app-repo
  namespace: web
spec:
  interval: 1m
  url: https://github.com/your-github-username/repository-name.git
  ref:
    branch: main
  secretRef:
    name: git-secret

ImageRepository Configuration

Create a YAML file in the manifests folder to define the image repository, if the repository is private you need to add the secretRef.

apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: app-image
  namespace: web
spec:
  image: ghcr.io/your-github-username/packagename 
  # For example if your username is testUser and the package is testPackage ghcr.io/testUser/testPackage
  interval: 5m
  secretRef:
    name: ghcr-secret

ImagePolicy Configuration

This configuration determines which images to pull based on specified filters. In this example, we pull the latest image using its timestamp. Ensure your pipeline tags the images appropriately when pushing them to the repository. For more details on filtering images, refer to the Flux documentation.

apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: app-policy
  namespace: web
spec:
  imageRepositoryRef:
    name: app-image
  filterTags:
    pattern: '^(?P<timestamp>.*)'
    extract: '$timestamp'
  policy:
    numerical:
      order: asc

ImageUpdateAutomation Configuration

Here you can define how often the controller should check for new images.

apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
  name: app-auto
  namespace: web
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: app-repo
  git:
    commit:
      author:
        email: fluxcdbot@users.noreply.github.com
        name: fluxcdbot
    push:
      branch: main
  update:
    path: './'
    strategy: Setter

Adjust deployment to use newest Image

To ensure our deployment always uses the newest image, we need to add an annotation to the container image specification.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      imagePullSecrets:
        - name: ghcr-secret
      containers:
        - name: app
          image: ${IMAGE_REPOSITORY_URL}:2123 # {"$imagepolicy": "web:app-policy"}
          ports:
            - containerPort: 80

Check if everything is running

Use the following commands to verify that the resources are created and running correctly in your Kubernetes cluster:

kubectl get imagerepository app-image -n web
kubectl get imagepolicy app-policy -n web
kubectl get imageupdateautomation app-auto -n web

Expected Output

NAME          LAST SCAN              TAGS
app-image     2024-07-03T12:45:03Z   58

NAME          LATESTIMAGE
app-policy    ${IMAGE_REPOSITORY_URL}:20240703124016

NAME          LAST RUN
app-auto      2024-07-03T12:48:55Z
  • app-image: Shows the last scan time and the number of tags found.
  • app-policy: Displays the latest image that matches the policy’s criteria.
  • app-auto: Indicates the last time the automation checked for new images.

Conclusion

Now every time a new image is built and pushed to the package of the repository you can see that Flux changes the tag of the deployment, which in return updates the manifests and updates the cluster.

GitHub Token Image

Nice work!

You've completed this developer guide. We have many more, so feel free to explore our other guides! Should you have any questions about our products or need help with metalstack.cloud, please reach out to us anytime.