2023-03-11 22:07:22 +11:00
..
2023-03-11 22:07:22 +11:00
2022-11-22 16:52:44 +11:00
2023-03-11 22:07:22 +11:00

Introduction to Flux CD v2

Create a kubernetes cluster

In this guide we we''ll need a Kubernetes cluster for testing. Let's create one using kind

kind create cluster --name fluxcd --image kindest/node:v1.23.5

Run a container to work in

run Alpine Linux:

docker run -it --rm -v ${HOME}:/root/ -v ${PWD}:/work -w /work --net host alpine sh

install some tools

# install curl 
apk add --no-cache curl

# install kubectl 
curl -sLO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl

test cluster access:

/work # kubectl get nodes
NAME                    STATUS   ROLES    AGE   VERSION
fluxcd-control-plane   Ready    control-plane,master   3m26s   v1.23.5

Flux CD

get flux command-line tool

Let's download the flux command-line utility.
We can get this utility from the GitHub Releases page

It's also worth noting that you want to ensure you get a compatible version of flux which supports your version of Kubernetes. Checkout the prerequisites page.

curl -o /tmp/flux.tar.gz -sLO https://github.com/fluxcd/flux2/releases/download/v0.41.1/flux_0.41.1_linux_amd64.tar.gz
tar -C /tmp/ -zxvf /tmp/flux.tar.gz
mv /tmp/flux /usr/local/bin/flux
chmod +x /usr/local/bin/flux

Now we can run flux --help to see its installed

Check our cluster

flux check --pre

Documentation

As with every guide, we start with the documentation
The Core Concepts is a good place to start.

We begin by following the steps under the bootstrap section for GitHub

We'll need to generate a personal access token (PAT) that can create repositories by checking all permissions under repo.

Once we have a token, we can set it:

export GITHUB_TOKEN=<your-token>

Then we can bootstrap it using the GitHub bootstrap method

flux bootstrap github \
  --owner=marcel-dempers \
  --repository=docker-development-youtube-series \
  --path=kubernetes/fluxcd/repositories/config/clusters/dev-cluster \
  --personal \
  --branch fluxcd-2022

flux check

# flux manages itself using GitOps objects:
kubectl -n flux-system get GitRepository
kubectl -n flux-system get Kustomization

Check the source code that flux bootstrap created

git pull origin <branch-name>

Repository structure

https://fluxcd.io/flux/guides/repository-structure/

  • Mono Repo
  • Repo per team
  • Repo per app
- apps
  - example-app-1
  - example-app-2
- infrastructure
  - ingress-nginx
  - monitoring
- clusters
  -dev-cluster
  -prod-cluster

build our app

Let's say we have a microservice called example-app-1 and it has its own GitHub repo somewhere.
For demo, it's code is under kubernetes/fluxcd/repositories/example-app-1/

# go to our "git repo"
cd kubernetes/fluxcd/repositories/example-app-1
# check the files
ls

cd src
docker build . -t example-app-1:0.0.1

#load the image to our test cluster so we dont need to push to a registry
kind load docker-image example-app-1:0.0.1 --name fluxcd 

setup our gitops pipeline

Now we will also have a "config" GitHub repo where configuration files for GitOps live.

cd kubernetes/fluxcd

# tell flux where our Git repo is and where the YAML is
# this is once off
# flux will monitor the example-app-1 Git repo for when any infrastructure changes, it will sync
kubectl -n default apply -f repositories/config/apps/example-app-1/gitrepository.yaml
kubectl -n default apply -f repositories/config/apps/example-app-1/kustomization.yaml

# check our flux resources 
kubectl -n default describe gitrepository example-app-1
kubectl -n default describe kustomization example-app-1

# check deployed resources
kubectl get all

kubectl port-forward svc/example-app-1 80:80

Now we have setup CD, let's take a look at CI

changes to our app

Once we make changes to our app.py we can build a new image with a new tag

docker build . -t example-app-1:0.0.2

#load the image to our test cluster so we dont need to push to a registry
kind load docker-image example-app-1:0.0.2 --name fluxcd 

# update our kubernetes deployment YAML image tag
# git commit & git push to branch!

If we wait a minute or so we can kubectl port-forward svc/example-app-1 80:80 again and see the changes

deploy by updating manifest

So all we did to update our app is to build a new image, push it to our registry and update the image tag in our kubernetes deployment YAML file and flux will sync it.
This is generally the role of CI, where flux concern is mainly CD.

Here is an example on how to automate that

deploy by image scanning

An alternative method is to use your CI to build and push a newly tagged image to your registry (same as first option) and use Flux image scanner to trigger the rollout instead of automating a commit to your config repo.

We firstly need to enable image scanning as its not enabled by default.
To do this we just need to re-bootstrap flux with an addition flag

flux bootstrap github \
  --owner=marcel-dempers \
  --repository=docker-development-youtube-series \
  --path=kubernetes/fluxcd/repositories/config/clusters/dev-cluster \
  --components-extra=image-reflector-controller,image-automation-controller \
  --personal \
  --branch fluxcd-2022

We need to create a image reigsitry credential where we will push our image:

kubectl -n default create secret docker-registry dockerhub-credential --docker-username '' --docker-password '' --docker-email 'test@test.com'

build and push example-app-2

cd kubernetes\fluxcd\repositories\example-app-2\
ls
cd src
ls
docker build . -t aimvector/example-app-2:0.0.1
docker push aimvector/example-app-2:0.0.1

We will need to tell Flux how to manage our image deployment
Note that this time our Kubernetes YAML is in the configs repo.
This is because our application repo triggers it's CI which will build and push a new image to our cluster
Flux will then detech the new image tag and update our Kubernetes YAML in our configs repo.
If Flux pushed the update to our application repo, it will cause a CI/CD loop.

add image policy and repository


kubectl -n default apply -f repositories/config/apps/example-app-2/gitrepository.yaml
kubectl -n default apply -f repositories/config/apps/example-app-2/kustomization.yaml

# tell flux about our image update policy
kubectl -n default apply -f repositories/config/apps/example-app-2/imagerepository.yaml
kubectl -n default apply -f repositories/config/apps/example-app-2/imagepolicy.yaml

Build and push our example-app-2

#see changes
kubectl describe imagerepository