Gitops w/ FluxCD: Configuring FluxCD for Push-Based Reconciliation.
FluxCD employs a Pull-Based Reconciliation. After changes are made, manifests have to be checked into a repo, from where Kustomizations, periodically, find out what to update in the K8s infrastructure. Sometimes a check-i
flux reconcile kustomization <name of kustomization>
flux reconcile sources <type of source> <name of source>
FluxCD: Not A One-Trick Pony.
Fortunately, FluxCD can be configured for Push-Based Reconciliation as well.
- The code will be checked in
- The 'code-check-in event' will push (or trigger) the GitOps flow, and reconcile the infrastructure (without waiting for the documented intervals to elapse)
What would a Push-Based Reconciliation look like?
![](https://hestia.ghost.io/content/images/2024/03/image-20.png)
- GitHub sends git events and an authentication token to a Reciever Service
- GitHub sends the git push event to the webhook-receiver Service (which we will configure)
- Notification Controller validates the authenticity of the payload using a token (which we will create)
- Source Controller pulls the changes into the cluster and updates the instavote GitRepository object
- The Kustomize Controller is notified about the revision change
- Kustomize Controller reconciles all the Kustomizations that reference the GitRepository object
Demo: Configure a Push-Based Reconciliation GitOps Flow
This demo introduces the GitRepository Receiver object. This object contains the list of git events, the token used for authenticating messages from GitHub and a reference to the GitRepository Source Object (which for our series has been instavote).
As part of this demo, we will create 2 new objects (a token, shared between GitHub and the Push-Enabling FluxCD components, and a GitRepository Receiver) and edit some of the existing Kustomization manifests (gotk-components.yaml) to expose a public-facing webhook (for GitHub to send messages to).
Edit manifests and increase time intervals
Edit vote-staging-kustomization.yaml
![](https://hestia.ghost.io/content/images/2024/03/image-10.png)
Edit instavote-staging-gitrepository.yaml
![](https://hestia.ghost.io/content/images/2024/03/image-11.png)
Expose a web service that is publicly accessible for GitHub to send messages to
To receive Git push or Helm chart upload events, you must expose a webhook receiver endpoint outside your Kubernetes cluster on a public address.
Surprisingly, FluxCD installs a Service called webhook-receiver as part of bootstrapping which can be used here.
kubectl get svc -n flux-system
![](https://hestia.ghost.io/content/images/2024/03/image-13.png)
The webhook-receiver Service is a ClusterIP service, by default, but needs signals from GitHub and, therefore, must be changed to either a LoadBalancer or NodePort Service type.
Since webhook-receiver is installed as a part of FluxCD bootstrapping, it MUST have a manifest in the flux-infra repo. Browsing through the flux-infra/clusters/staging/flux-system folders, we will find a webhook-receiver's manifest (gotk-components.yaml) file.
![](https://hestia.ghost.io/content/images/2024/03/image-14.png)
We can use our Kustomize experience (remember this article?) to create an overlay patch turning the webhook-receiver from ClusterIP to NodePort.
Title the patch webhook-receiver-service.yaml (code shown below).
apiVersion: v1
kind: Service
metadata:
name: webhook-receiver
namespace: flux-system
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http-webhook
nodePort: 31234
selector:
app: notification-controller
type: NodePort
Kustomize needs to know where to look for the files which will be customized.
Edit the kustomization.yaml file in staging/flux-system/.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
patches:
- webhook-receiver-service.yaml
Hold on. What is patchesStrategicMerge? The last time I made a Kustomization file I used patches.
The patches take the contents of the webhook-receiver-service.yaml file, find the exact sections in gotk-components.yaml and gotk-sync.yaml and replace them with the contents of the webhook-receiver-service.yaml manifest.
Still unclear? Let's look at the image below to appreciate the magic of patches.
First, list the files in the clusters/staging/flux-system folder.
![](https://hestia.ghost.io/content/images/2024/03/image-15.png)
When we execute the kustomize build command at the root of flux-system folder, Kustomize gets busy generating an edited manifest for gotk-*.yaml.
![](https://hestia.ghost.io/content/images/2024/03/image-16.png)
We can save the generated YAML into a temporary file using
kustomize build -o temp.yaml
Search for 'webhook-service' in temp.yaml and you should be able to see that webhook-service has been turned into a NodePort.
![](https://hestia.ghost.io/content/images/2024/03/image-17.png)
Git-check new code/manifests
git add *
git commit -m 'comment'
git push origin main
Either manually reconcile the infrastructure or let the set interval elapse before checking the state of reconciliation.
flux get kustomizations
![](https://hestia.ghost.io/content/images/2024/03/image-19.png)
However, the real proof that kustomization worked is to confirm webhook-receiver was converted to a NodePort service.
kubectl get svc -n flux-system
![](https://hestia.ghost.io/content/images/2024/03/image-18.png)
So far, we have ONLY generated a NodePort Service that will listen for traffic and event information from GitHub.
Any traffic sent from GitHub to webhook-receiver Service must be authenticated for security any traffic sent from GitHub to webhook-receiver Service. After all, some malicious man-in-the-middle could corrupt the payload from Git to our cluster.
Generate a new K8s Secret to hold the shared token
# Generate a token
TOKEN=$(head -c 12 /dev/urandom | shasum | cut -d ' ' -f1)
# Save token. It will be used later.
echo $TOKEN
# Turn it into a Secret
kubectl -n flux-system create secret generic webhook-token \
--from-literal=token=$TOKEN
Create a GitRepository Receiver
This Receiver will accept GitHub events, filter out those required and ignore those that are not.
flux create receiver instavote \
--type github \
--event ping \
--event push \
--secret-ref webhook-token \
--resource GitRepository/instavote \
![](https://hestia.ghost.io/content/images/2024/03/image-21.png)
- 1: git events in scope (ping, push).
- 2: The GitHub repo from where these events are originating.
- 3: The shared token we just generated. This token is validated by the Notification Controller before letting any traffic pass through.
- 4: The type of code repository the receiver is being made for.
At the end of this step, we have FluxCD components alive and ready.
![](https://hestia.ghost.io/content/images/2024/03/image-22.png)
Our focus now shifts towards GitHub.
Set up a webhook on GitHub
Remember that shared token made earlier? We do have to share it with GitHub.
To get the token, echo the value of $TOKEN.
echo $TOKEN
# The token should resemble this:
# e83d76derar7a85f44aabcgdaaea180b1e8c3
We also need the URL of the webhook-receiver Service. This URL will be saved as part of the webhook that will reside in GitHub.
flux get receivers
![](https://hestia.ghost.io/content/images/2024/03/image-23.png)
Using the URL from the image and appending it to the Node IP and NodePort Port Number will give us the Payload URL.
![](https://hestia.ghost.io/content/images/2024/03/image-24.png)
Load the instavote GitHub repository page.
- Go to Settings --> Webhooks.
- Click on Add Webhook.
- Paste the Payload URL in its text box.
- Paste the token in the Secret text box.
- Select the Just the Push event radio button.
Check the Recent Deliveries tab to confirm everything worked.
![](https://hestia.ghost.io/content/images/2024/03/image-25.png)
Test the integration
It's time to put FluxCD's money where its mouth is. We can make a minor modification in the vote app by increasing the replica count from 2 to 5.
![](https://hestia.ghost.io/content/images/2024/03/image-26.png)
Change the replicas in instavote/deploy/vote/staging/vote-deployment.yaml file from 2 to 5.
After code is checked in, check the replicas count.
![](https://hestia.ghost.io/content/images/2024/03/image-27.png)
Another check is to compare the SHA for the commit (in GitHub) and make sure it's the same for the vote-staging Kustomization.
![](https://hestia.ghost.io/content/images/2024/03/image-29.png)
I write to remember, and if, in the process, I can help someone learn about Containers, Orchestration (Docker Compose, Kubernetes), GitOps, DevSecOps, VR/AR, Architecture, and Data Management, that is just icing on the cake.