Hoe Flux en GitOps gebruiken om applicaties te beheren
IT staat nooit stil. Daarom onderzoekt ACA Group voortdurend innovatieve oplossingen en tools. En een van die tools is Flux. In deze blog delen onze experts hun ervaringen en bevindingen.
Eerst en vooral: wat is Flux? Flux is een cloud-native tool die werd ontworpen om de flexibiliteit, schaalbaarheid en veerkracht van de cloud te benutten. Het werkt zowel op elke Kubernetes-gebaseerde oplossing in de openbare/privécloud als op een lokale Kubernetes-cluster. Flux is een gecontaineriseerde tool met slechts één doel: het implementeren van continue levering. Om hierin te slagen, houdt het de Kubernetes-cluster waarop het wordt ingezet, gesynchroniseerd met een configuratiebron. Een GIT-repository is zo’n typische bron. De configuratiebron wordt gecontroleerd door Flux (pull-aanpak). Als er een wijziging wordt gedetecteerd, wordt die wijziging doorgevoerd in de cluster.
De wijziging wordt aangebracht via een reconciliatiemethode. Dat betekent dat Flux niet alle resources zal vernietigen en aanmaken, maar alleen die wijzigingen zal doorvoeren die nodig zijn om overeen te komen met de status zoals die beschreven wordt in de GIT-repository. Stel dat je een Deployment.yaml en een Service.yaml hebt, maar dat je alleen de eerste wilt wijzigen om een nieuwe versie van een container image te gebruiken. Dan wordt alleen de Deployment.yaml vervangen binnen de cluster, zonder de service te veranderen. Het synchronisatieproces van de inhoud in GIT wordt GitOps genoemd.
Wat is GitOps
Bij een GitOps-aanpak wordt de status van de cluster volledig beschreven in GIT-repositories. Het bevat alles wat nodig is om een applicatie te implementeren (Deployment.yaml, Service.yaml, ConfigMap.yaml, ...). Om de cluster met de status te doen overeenstemmen, hebben we een geautomatiseerde oplossing nodig. In dit geval zal Flux een reconciliatie uitvoeren als er iets veranderd is in GIT.
Het gebruik van GitOps wordt beschouwd als een meer ontwikkelaarsgerichte ervaring. Het is gebaseerd op tools en principes die ontwikkelaars al kennen, waardoor er geen extra kennis meer nodig is.
De voordelen van GitOps
Het gebruik van de door Flux geïmplementeerde GitOps-aanpak biedt tal van voordelen:
- De volledige Kubernetes-clusterstatus is zichtbaar in GIT, waardoor deze begrijpelijker is voor ontwikkelaars.
- Ontwikkelingsteams kunnen onafhankelijker werken, omdat er geen complexe implementatiepijplijnen nodig zijn.
- Het is veel eenvoudiger om extra applicaties op te zetten die op de Kubernetes-cluster kunnen worden gebruikt.
- Het gebruik van pull request flows vergemakkelijkt de monitoring van wijzigingen in applicaties.
- Branching- of versioning-strategieën maken het makkelijk om verschillende omgevingen (test, aanvaarding, productie) synchroon te houden.
- De aanpak kan uniform zijn voor alle soorten Kubernetes-clusters (EKS, Rancher, OpenShift of een lokale set-up).
- Flux is erg licht en kan gemakkelijk op elke Kubernetes-cluster worden geïnstalleerd, omdat de capaciteit meestal al aanwezig is.
- Flux kan rekenen op een goede documentatie en een actieve community.
Omdat de Flux-resources binnen onze cluster draaien, is het niet nodig om andere ontwikkelingstools (zoals Jenkins of Bamboo) te gebruiken. Ook dat heeft enkele voordelen:
- Minder beveiligingsproblemen omdat we een pull-aanpak hanteren en geen credentials in externe tools moeten opslaan.
- Geen onverwachte downtime veroorzaakt door externe implementatietools.
- Minder overhead omdat er geen implementatietools onderhouden moeten worden.
Hoe applicaties beheren met Flux
Stel dat we een GIT-repository hebben met de naam flux-app die de Deployment.yaml bevat die we willen implementeren. Hoe kunnen we Flux de opdracht geven om deze Deployment aan te maken in de Kubernetes-cluster?
Voordat we onze applicaties kunnen implementeren, moeten we eerst Flux installeren. Flux maakt ook gebruik van een GitOps-aanpak om zijn eigen installatie te beheren:
- Maak een GIT-repository aan die de resources voor de Flux-installatie zal bevatten.
- Download de Flux CLI
- Voer het bootstrap-commando uit.
flux bootstrap git \
--url=ssh://git@bitbucket.org/sample-repo/flux-installation.git \
--private-key-file=/Users/yourname/.ssh/flux \
--branch=main \
--path=./clusters/rancher-desktop-local
De YAML-bestanden worden opgeslagen in de hierboven vermelde GIT-repository en worden toegepast op je cluster. De belangrijkste aangemaakte resources worden weergegeven in onderstaande afbeelding.
De Flux-installatie heeft 4 belangrijke componenten toegevoegd aan onze Kubernetes-cluster:
- source-controller pod
- kustomize-controller pod
- GitRepository CRD (Custom Resource Definition)
- Kustomization CRD (Custom Resource Definition)
⚠️ Wat zijn Custom Resource Definitions?
Kubernetes voorziet standaard een specifieke reeks API-resources. Het gaat hierbij om de welbekende resources zoals Pods, ConfigMaps, Deployments en Secrets. Een CR (Custom Resource) is een uitbreiding op de Kubernetes-API. Het is een manier om naast deze bestaande resources nieuwe resourcetypes toe te voegen. Net als bij gekende resources, hebben we echter een specificatie nodig over hoe zo'n resource moet worden aangemaakt.
De CustomResourceDefinition (CRD) is eigenlijk een blauwdruk van hoe de CustomResource (CR) er zou moeten uitzien. Bovendien hebben we logica nodig over wat er moet gebeuren wanneer zo'n resource wordt aangemaakt. Deze logica wordt meestal toegevoegd aan de applicatiecontainer, die de CRD controleert op wijzigingen en de vereiste acties onderneemt als die zich voordoen.
Hier vind je meer informatie over dit onderwerp in de officiële Kubernetes-documentatie
In het geval van Flux bevat de source-controller pod de logica om acties te ondernemen wanneer een GitRepository CR wordt aangemaakt/gewijzigd. De kustomize-controller pod heeft dan weer de logica om acties te ondernemen wanneer een Kustomization CR wordt aangemaakt/gewijzigd. Flux biedt de CustomResourceDefinition (blauwdruk) en de logica (die in de containers draait) om iets te doen met een Custom Resource. De Custom Resource wordt in de volgende stappen toegevoegd aan de Kubernetes-cluster.
GitRepository Custom Resources toevoegen
Nu we de GitRepository CustomResourceDefinition en de source-controller hebben, kunnen we GitRepository-resources gaan toevoegen. Deze resource bevat de logica om verbinding te maken met de GIT-repository waar de YAML-bestanden van je applicatie zijn opgeslagen.
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: flux-app
namespace: flux-app
spec:
gitImplementation: go-git
interval: 1m0s
ref:
branch: main
secretRef:
name: bitbucket-cloud-credentials
timeout: 60s
url: https://bitbucket.org/sample-repo/application
We maken de GitRepository-resource aan.
kubectl create -f GitRepository.yaml
De source-controller pikt de nieuwe configuratie op en controleert de BitBucket-repository.
kubectl -n flux-app get gitrepository
NAME URL AGE READY STATUS
flux-app https://bitbucket.org/sample-repo/application 21m True stored artifact for revision 'main/9ad65085cfe584f438f71e361c4ad20ac9d04f55'
Merk op dat de revisie branch/commit-id aangeeft.
In deze fase wordt de GIT-repository bekeken, maar er wordt niets geïmplementeerd in onze cluster. Om de YAML-bestanden die in de GIT-repository flux-app zijn opgeslagen, te implementeren, moeten we een Kustomization-resource aanmaken.
⚠️ Je moet een geheim voor authenticatie toevoegen aan de BitBucket-repository. Omdat dit op verschillende manieren kan, hebben we dit niet toegevoegd aan dit artikel. Zodra het geheim is aangemaakt, moet je ernaar verwijzen in je GitRepository YAML-bestand.
secretRef: name: bitbucket-cloud-credentials
Meer informatie vind je hier.
Kustomization Custom Resources toevoegen
De Kustomization-resource zal configureren welke GitRepository-resource op wijzigingen moet letten. Zodra de GitRepository-resource een nieuwe revisie aangeeft, zal de kustomize-controller de huidige versie van de artefacten implementeren in de cluster.
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: flux-app
namespace: flux-app
spec:
force: true
interval: 1m0s
path: ./
prune: false
sourceRef:
kind: GitRepository
name: flux-app
We maken de Kustomization-resource aan.
kubectl create -f Kustomization.yaml
Als we de status van de aangemaakte Kustomization-resource bekijken, zien we dat deze overeenkomt met de laatste revisie.
kubectl -n flux-app get kustomization flux-app
NAME AGE READY STATUS
flux-app 37m True Applied revision: main/9ad65085cfe584f438f71e361c4ad20ac9d04f55
Als we BitBucket controleren, zien we dat er een Deployment-bestand in onze GIT-repository zit: de commit komt overeen met die welke door Kustomization wordt genoemd.
Deze Deployment werd toegepast op onze Kubernetes-cluster.
kubectl -n flux-app get pod
NAME READY STATUS RESTARTS AGE
flux-app-7ddd9dd674-xp24s 1/1 Running 0 5m49s
Samengevat
Het bovenstaande ontwerp vat de flow samen:
1. Een ontwikkelaar maakt een pull request aan.
2. Het pull request wordt samengevoegd tot een branch die wordt gemonitord door Flux.
3. De source-controller controleert de branch. Als hij een nieuwe commit id opmerkt, verandert hij de revisie van de GitRepository-bron in 'branch/commit-id'.
4. De kustomize-controller houdt de GitRepository-bron in de gaten.
5. Als er een nieuwe versie wordt opgemerkt, zal de nieuwe versie van de bestanden worden toegepast en zal de revisie van de Kustomization-bron worden veranderd in 'branch/commit-id'.
Conclusie
In deze blog hebben we uitgelegd hoe Flux werkt en hoe eenvoudig het is om Flux te gebruiken voor continue levering. Binnen ACA zijn we momenteel bezig met de migratie van complexe Jenkins-implementatiepijplijnen naar een eenvoudig te begrijpen GitOps-aanpak die gebruik maakt van Flux. We zijn ervan overtuigd dat deze GitOps-aanpak in de nabije toekomst de standaardbenadering zal worden om workloads te implementeren.
Meer weten over FLux?