017: Auto-deploy Kubernetes resources with Flux Skip to main content

017: Auto-deploy Kubernetes resources with Flux

Flux is a GitOps Operator for Kubernetes which supports both Git sync, automated deployment and rollback, so that deliveries can go faster and safer.

The daily mood

I had the opportunity to attend to a meeting with developers about the plan to migrate one of our applications. They might need the support of our team. I really enjoyed the topics discussed even though I felt a bit overloaded with developer jargon, specific acronyms and historical details. 

Back to my ramp-up, we already introduced what is Flux in a previous post, a typical GitOps implementation for K8s. In this test use-case, the developer basically commits something to his branch and the cluster just takes care of the rest i.e. updates the application on the cluster.
Basic requirements
  • K8s client and cluster (ex. our local minikube or microk8s)
  • Git client and repo (ex. empty project in GitHub)
  • K8s application (ex. our nginx application from previous post)
Installation steps
  1. Setup Flux command-line tool (fluxctl)
    sudo su -
    snap install fluxctl
    fluxctl completion bash > /etc/bash_completion.d/fluxctl
  2. Deploy and configure Flux operator on the K8s cluster
    # create a namespace dedicated to flux operator
    kubectl create ns flux
    # configure flux operator connection to GitHub
    export GHUSER="<your_github_username>"
    export GHREPO="<your_github_reponame>"
    fluxctl install \
    --git-user=${GHUSER} \
    --git-email=${GHUSER}@users.noreply.github.com \
    --git-url=git@github.com:${GHUSER}/${GHREPO} \
    --git-path=workloads \
    --namespace=flux | kubectl apply -f -
    # wait for flux to start
    kubectl -n flux rollout status deployment/flux
    # generate ssh key
    fluxctl identity --k8s-fwd-ns flux
  3. Manually add SSH-deployment-key under your GitHub-Repo-Settings and grant write access
Preparation steps

As mentioned in the requirements above we are using nginx as the test application but it could be anything fitting into one or more containers (ex. a Spring Boot, Node.js or Python Flask application). Now let us download our empty project from GitHub, create the required structure as defined in setup git-path, and put our manifest in it.
git clone https://www.github.com/${GHUSER}/${GHREPO}
cd ${GHREPO} && mkdir workloads && mv ../nginx-manifest.yaml workloads/
There are a few optional questions to answer though, like is this an application managed by flux, in which namespace shall the operator deploy to and what is the actual deployment strategy.
# diff nginx-manifest.yaml nginx-manifest-flux.yaml 
4a5,7 > namespace: default > annotations: > fluxcd.io/automated: "true" 9a13,16 > strategy: > type: RollingUpdate > rollingUpdate: > maxUnavailable: 0 24a32,34 > namespace: default > annotations: > fluxcd.io/automated: "true"
Execution steps

Now let us push those changes to the repository
git add workloads && git commit -m "add nginx flux workload" && git push
Default pull frequency is 5 min. and we can't wait for a result
fluxctl sync --k8s-fwd-ns flux
List the workloads managed by our flux operator (or show eventual repo structure error)
fluxctl list-workloads --k8s-fwd-ns flux
With this, we've just spin-up a service without connecting to K8s (the essence of GitOps). In case you want to monitor, Flux operator logs are exposed like for any other pod:
kubectl -n flux logs deploy/flux
Note that with Flux, changes can be made bi-directionaly (with the exception of deletions as explained further below). Changing for example the replica-count of our deployment either directly on the cluster (kubectl edit nginx-deployment) or in the configuration repo (GitHub commit) will propagate accordingly. Deploying the new release version of an image is also possible without any configuration change on either side, just via Flux client as follow:
fluxctl release --workload=default:deployment/nginx-deployment --update-image=nginx.latest
De-automation

Note that deletions on the cluster will not lead to removal on the repo. The reason for this is that Flux takes care of the reliability of any managed object. So deleting a deployment for example will have a similar effect to deleting a replicated pod. Flux client supports activation/deactivation of automation flag as follow: 
fluxctl deautomate --k8s-fwd-ns flux --workload=default:deployment/nginx-deployment
fluxctl deautomate --k8s-fwd-ns flux --workload=default:service/nginx-service
Note that as Flux is able to reflect cluster state, it will remove automation flag from the application manifest and commit change to the repo. As expected, relative objects are not de-commissioned (application still running fine).

Conclusion

Flux implementation is absolutely conform to the GitOps operational model but not yet much mature.
Next we'll have a look at Flux Helm operator, and try to match it with our internal requirements.

Comments