Flamingo - Le meilleur des 2 mondes ?

thumbernail cicd

Flamingo - the Flux Subsystem for ArgoCD(FSA)

Vous connaissez tous ces 2 outils Open Source tres puissants qui permettent de faire du GitOps (Utilisation de Git comme source de vérité unique et pour automatiser les opérations) à la fois pour déployer des infrastructures ou des applications.

Argo CD est un outil de déploiement continu qui utilise GitOps pour synchroniser l'état du cluster avec un référentiel Git. Il surveille les changements dans le référentiel Git et déploie automatiquement les applications lorsque les modifications sont détectées. Argo CD offre des fonctionnalités avancées telles que la comparaison de versions, le suivi des mises à jour, la gestion des canaux de publication et la possibilité de déployer sur plusieurs clusters.

FluxCD, quant à lui, est un outil de déploiement continu qui utilise également GitOps pour synchroniser l'état du cluster avec un référentiel Git. FluxCD suit une approche plus modulaire, où les fonctionnalités sont fournies par des plugins appelés "controllers". FluxCD propose des contrôleurs pour le déploiement d'applications, la mise à jour de l'image, la gestion des événements et la gestion des canaux de publication.

En résumé, les deux outils sont similaires dans leur utilisation de GitOps pour synchroniser l'état du cluster avec un référentiel Git, mais Argo CD est plus axé sur la gestion des applications et offre des fonctionnalités plus avancées, tandis que FluxCD suit une approche plus modulaire et fournit des fonctionnalités par le biais de plugins appelés contrôleurs. Le choix entre les deux dépendra des besoins spécifiques de chaque organisation en matière de déploiement continu.

En fin de compte, le choix entre Argo CD et Flux CD dépend des besoins et des préférences de chaque équipe de développement. Les deux outils offrent des fonctionnalités similaires et sont tous deux capables de gérer le déploiement continu des applications sur Kubernetes.

Outils :

Repos :

  • https://github.com/flux-subsystem-argo/flamingo
  • https://github.com/flux-subsystem-argo/fsa
  • https://github.com/herveleclerc/flamingo


Image générée par Dall-E :

Note : Ce billet de blog n'est pas fait pour vous initier au GitOps grâce aux outils ArgoCD et Flux !.

Donc, nous ne verrons pas en détail les mécanismes qui nous permettent de synchroniser un repo git avec des applications déployées dans un cluster kubernetes, mais de voir le fonctionnement coordonné d'ArgoCD et de flux dans Flamingo.

Par simplicité, nous modifierons directement dans l'interface d'ArgoCD certains paramètres pour voir les changements plutôt que les enregistrer dans un repo et attendre la synchronisation.

Libre à vous d'implémenter ensuite le tout dans une approche 100% gitops.

Le projet Flamingo

Flamingo est un projet intéressant permettant de bénéficier et de combiner les meilleures fonctionnalités de Flux et d'ArgoCD en une seule solution.

Flamingo patch ArgoCD en lui ajoutant un sous-système Flux.

Ce que je n'aime pas dans ArgoCD

Si on déploie un chart helm par une "custom resource" de type Application. Cette resource, définie dans ArgoCD, fait l'équivalent d'un helm template.

ArgoCD déploie le manifeste résultant. On perd dans ce cas la possibilité d'utiliser des commandes via la CLI helm. ex: helm list ne donnera évidemment rien.

Ce que je n'aime pas dans FluxCD

FluxCD est un "outil" gitops très puissant, mais il ne possède pas d'interface graphique.

Weaveworks propose un dashboard simple, mais n'ayant pas beaucoup de fonctionnalité.

À l'inverse ArgoCD propose une interface graphique puissante permettant aux différentes équipes d'un projet de travailler ensemble. ArgoCD propose les notions de projets, de teams, d'utilisateurs avec une gestion des droits fine.

L'approche de Flamigo

Avoir dans un cluster kubernetes les 2 outils gitops travaillant en collaboration. Cela permet par exemple d'avoir une interface unifiée pour suivre dans ArgoCD des projets déployés soient par ArgoCD, soit par Flux, soit par les 2 en même temps.

Le "patch" de Flamingo sur ArgoCD permet de gérer soit en ligne de commande soit en dans l'interface graphique des ressources Flux.

Si l'on déploie une application basée sur un chart Helm on pourra demander à ce que les ressources Flux soient créées automatiquement.

On pourra donc utiliser la commande helm ou flux en ligne de commande

Comment Flamingo fonctionne

Loopback Reconciliation

Une Loopback Reconciliation est une fonctionnalité de Flamingo qui permet de synchroniser les applications déployées à l'aide de l'approche GitOps. La fonction est activée si le flag FluxSubsystem est mis à "true" dans l'interface utilisateur (UI) d'ArgoCD ou bien sûr dans le manifeste d'une application.

Worflow de la "Loopback Reconciliation"

  1. Le manifeste d'une application est créé ou déployé soit en mode Kustomize ou Helm
  2. Flamingo convertit l'application ArgoCD en objets Kustomization ou HelmRelease, l'objet la source sera déduite des précédents objets. Si les objets existent déjà, Flamingo les utilisera comme références plutôt que d'en créer de nouvelles.
  3. Flamingo synchronise ou réconcilie l'état de l'application ArgoCD avec les états des objets Flux comme état souhaité. La réconciliation d'ArgoCD native n'est pas utilisée et est remplacée par celle de Flux.

Déploiement de Flamingo

Les pré-requis pour utiliser flamingo :

  • un cluster kubernetes
  • La CLI de flux (https://fluxcd.io/docs/cmd/)
  • La CLI d'ArgoCD (https://argo-cd.readthedocs.io/en/stable/cli_installation/)
  • la CLI d'helm (https://helm.sh/)

Installer flux sur le cluster

flux install

Flamingo peut être déployé de 3 facons différentes:

Au préalable déterminez quelle version de flamingo vous allez utiliser

Flux ArgoCD Image
v0.41 v2.6 v2.6.6-fl.4-main-0d5eae51
v0.41 v2.5 v2.5.15-fl.3-main-0d5eae51
v0.41 v2.4 v2.4.27-fl.3-main-0d5eae51
v0.38 v2.3 v2.3.13-fl.3-main-b0b6148f
v0.37 v2.2 v2.2.16-fl.3-main-2bba0ae6
export FSA_VERSION=v2.6.6-fl.4-main-0d5eae51
  • En faisant un upgrade d'un ArgoCD existant, simplement en remplaçant l'image ArgoCD par celle modifiée de flamingo
kustomize build https://github.com/flux-subsystem-argo/flamingo//release?ref=${FSA_VERSION} \
  | yq e '. | select(.kind=="Deployment" or .kind=="StatefulSet")' - \
  | kubectl  -n argocd apply -f - 

Cette méthode est intéressante, si vous avez un ArgoCD correspondant à Flamingo déjà configuré (rbac, users, plugins, etc).

  • En remplacant tout l'ArgoCD déjà déployé (les configurations d'ArgoCD seront remises à 0 !)
kubectl  -n argocd apply -k https://github.com/flux-subsystem-argo/flamingo//release?ref=${FSA_VERSION}
  • En installant Flamingo de zéro
kubectl create ns argocd
kubectl  -n argocd apply -k https://github.com/flux-subsystem-argo/flamingo//release?ref=${FSA_VERSION}

Alternative à cette dernière possibilité :

Vous pouvez aussi utiliser le package OCI que j'ai créé à partir du répertoire manifests dans le repo (https://github.com/herveleclerc/flaming). Le package est stocké dans une registry publique de github (ghcr.io/herveleclerc/manifests/argocd)

Déployez le manifeste suivant:

cat <<EOF | kubectl apply -f -
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
  name: flamingo-demo
  namespace: flux-system
spec:
  interval: 30s
  url: oci://ghcr.io/herveleclerc/manifests/argocd
  ref:
    tag: 1.0.1
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: flamingo-demo
  namespace: flux-system
spec:
  targetNamespace: argocd
  prune: true
  interval: 2m
  path: "./init"
  sourceRef:
    kind: OCIRepository
    name: flamingo-demo
    namespace: flux-system
  timeout: 3m
EOF

La première ressource définit une Custom Resource de type OCIRepository permettant d'aller chercher des manifestes packagés au format OCI dans une registry sur github

La deuxième une Kustomization permettant de déployer les manifestes contenus dans le répertoire init du package OCI.

Cette Kustomization déploie donc Flamingo (FSA).

Accéder à l'interface d'ArgoCD

  • Récupérer le mot de passe de l'administrateur avec la commande suivante :
kubectl  -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

Petite Note : Saviez vous qu'il existe un plugin pour kubectl très sympa pour décoder les mots de passe des "secrets"?

Il suffit de le déployer par l'utilitaire krew. Ensuite pour décoder un secret il suffit de faire :

kubectl view-secret -n argocd argocd-initial-admin-secret

Plus simple non ? 😜

  • Aller sur l'interface en proxyfiant le port 443 d'ArgoCD
kubectl port-forward  -n argocd svc/argocd-server 9000:443

Vous pouvez maintenant acceder à l'interface d'ArgoCD en tapant l'url https://localhost:9000 dans votre navigateur.

Vous devriez avoir cette interface :

user : admin
password: la valeur retournée du secret argocd-initial-admin-secret 

Bravo ! vous êtes dans l'interface principale d'ArgoCD

Pour nos tests, nous allons utiliser un chart helm permettant de déployer une petite application Web conçue en Go qui rassemble les bonnes pratiques pour exécuter des microservices dans Kubernetes : PodInfo


Premier test : Déployer un chart Helm avec ArgoCD

cat <<EOF | kubectl apply -f -
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: aa-podinfo-helm-no-fsa
  namespace: argocd
  finalizers:
    - resources-finalizer. argocd.argoproj.io
spec:
  destination:
    namespace: podinfo-helm-no-fsa
    server: 'https://kubernetes.default.svc'
  source:
    repoURL: 'https://stefanprodan.github.io/podinfo'
    targetRevision: 6.3.5
    chart: podinfo
  project: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Notez les finalizers qui dans nos démonstrations permettront de supprimer les ressources associées à l'application si on supprime celle-ci dans l'interface ou si on utilise la commande :

kubectl delete application ....

Dans l'interface ArgoCD vous avez une nouvelle application déployée :

Si vous cliquez sur cette application vous voyez sa composition :

Pour voir les resources déployées sur le cluster :

kubectl get all -n podinfo-helm-no-fsa 


NAME                                          READY   STATUS    RESTARTS   AGE
pod/aa-podinfo-helm-no-fsa-596b4879dc-w4q5v   1/1     Running   0          20s

NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
service/aa-podinfo-helm-no-fsa   ClusterIP   10.0.231.182   <none>        9898/TCP,9999/TCP   20s

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/aa-podinfo-helm-no-fsa   1/1     1            1           20s

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/aa-podinfo-helm-no-fsa-596b4879dc   1         1         1       20s
  • Cliquez sur le bouton "APP DETAILS"

  • Cliquez sur l'onglet "PARAMETERS"

  • Cliquez sur le bouton "EDIT"

  • Modifiez la valeur de replicaCount et mettez 3 par exemple

  • Cliquer sur le bouton "SAVE" (en haut)

  • Vérifiez que vous avez dans l'interface ArgoCD maintenant 3 pods.

En ligne de commande :

kubectl get deploy -n podinfo-helm-no-fsa
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
aa-podinfo-helm-no-fsa   3/3     3            3           5m56s

Si vous tapez la commande :

flux get all -n podinfo-helm-no-fsa

la commande ne renvoie rien, c'est normal !

Si vous tapez la commande :

helm list -n podinfo-helm-no-fsa

NAME    NAMESPACE   REVISION    UPDATED STATUS  CHART   APP VERSION

ArgoCD ne déploie pas un chart mais un manifeste généré par l'équivalent d'une commande helm template par ArgoCD

Votre chart helm n'existe pas en tant que tel dans le cluster kubernetes


Deuxieme test : Déployer un chart Helm avec ArgoCD et le Flux Sub System activé

Déployez ce manifeste

Notez que la seule différence avec le précédent sont les 2 directives de synchronsation:

- AutoCreateFluxResources=true
- FluxSubsystem=true
cat <<EOF | kubectl apply -f -
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: bb-podinfo-helm-with-fsa
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: podinfo-helm-with-fsa
    server: 'https://kubernetes.default.svc'
  source:
    repoURL: 'https://stefanprodan.github.io/podinfo'
    targetRevision: 6.3.5
    chart: podinfo
  project: default
  syncPolicy:
    automated:
      prune: true
    syncOptions:
      - AutoCreateFluxResources=true
      - CreateNamespace=true
      - FluxSubsystem=true
EOF

Dans l'interface d'argoCD vous verrez :

Si vous cliquez sur l'application pour voir le détail vous verrez dans un premier temps cela

La boucle de réconciliation d'ArgoCD, n'a pas encore tourné donc le résultat est donc partiel.

Par contre on voit que 2 objets flux on été créé :

  • helmrepository : qui est une "custom resource" qui représente un repo helm.
  • helmrelease qui est une "custom resource" qui représente une release helm.

Maintenant en ligne de commande tapez la commande :

helm list -n podinfo-helm-with-fsa

NAME                        NAMESPACE               REVISION    UPDATED                                 STATUS      CHART           APP VERSION
bb-podinfo-helm-with-fsa    podinfo-helm-with-fsa   1           2023-03-21 08:07:31.163611065 +0000 UTC deployed    podinfo-6.3.5   6.3.5

On a bien une release du chart podinfo déployée.

Si vous tapez la commande flux suivante :

flux get all -n podinfo-helm-with-fsa


NAME                                    REVISION        SUSPENDED   READY   MESSAGE
helmrepository/bb-podinfo-helm-with-fsa sha256:61f94c20 False       True    stored artifact: revision 'sha256:61f94c20'

NAME                                                        REVISION    SUSPENDED   READY   MESSAGE
helmchart/podinfo-helm-with-fsa-bb-podinfo-helm-with-fsa    6.3.5       False       True    pulled 'podinfo' chart with version '6.3.5'

NAME                                    REVISION    SUSPENDED   READY   MESSAGE
helmrelease/bb-podinfo-helm-with-fsa    6.3.5       False       True    Release reconciliation succeeded

On voit bien les "custom resources" créées par le sous-système flux

  • helmrepository
  • helmchart
  • helmrelease

En ligne de commande, pour voir le déploiement de l'application:

kubectl get deploy -n podinfo-helm-with-fsa

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
bb-podinfo-helm-with-fsa   1/1     1            1           16m

Une fois la boucle de synchronisation/reconciliation effectuée l'interface d'argoCD présente l'application de cette manière

Vous pouvez toujours modifier les paramètres au niveau de l'application comme sur le premier test.

Par exemple, changez le replicaCount à 4. (APP DETAILS->PARAMETERS->EDIT->SAVE)

Vous pourrez voir en tapant la commande que vous êtes passé en revision 2 :

helm list -n podinfo-helm-with-fsa
NAME                        NAMESPACE               REVISION    UPDATED                                 STATUS      CHART           APP VERSION
bb-podinfo-helm-with-fsa    podinfo-helm-with-fsa   2           2023-03-21 08:38:00.020354528 +0000 UTC deployed    podinfo-6.3.5   6.3.5

et que votre application a été mise à l'échelle à 4.

kubectl get deploy -n podinfo-helm-with-fsa
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
bb-podinfo-helm-with-fsa   4/4     4            4           11m

Après la boucle de réconciliation l'interface argoCD présente :

Si vous intervenez directement sur le chart helm en changeant une valeur en exécutant un un upgrade du chart.

Changement de replicaCount

kubectl patch -n podinfo-helm-with-fsa \
        helmrelease bb-podinfo-helm-with-fsa \
        --type='json' -p='[{"op": "replace", "path": "/spec/values/replicaCount", "value":"2"}]'
  • Vérifiez que vous êtes passé à la révison 3 (helm list -n podinfo-helm-with-fsa)

  • verifier que vous avez bien les custom resources de flux modifiées aussi (flux get all -n podinfo-helm-with-fsa)

Vous devriez avoir ca :

Par contre vous aller avoir un problème si vous synchronisez car le système va détecter que les données ne sont pas synchronisées au niveau des paramètres de l'application.

Veuillez changer la valeur du paramètre replicaCount.

Bon, Flamingo ne sait pas modifier les paramètes de l'application dans le manifeste de l'application.


Troisième test : Déployer une application basée sur un package OCI et Flux

cat <<EOF | kubectl apply -f -
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cc-podinfo-oci
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: podinfo
    server: https://kubernetes.default.svc
  project: default
  source:
    path: "./podinfo"
    repoURL: oci://ghcr.io/herveleclerc/manifests/argocd
    targetRevision: 1.0.5
  syncPolicy:
    syncOptions:
    - ApplyOutOfSyncOnly=false
    - FluxSubsystem=true
    - AutoCreateFluxResources=true
    - CreateNamespace=true
    automated:
      prune: true
      selfHeal: true
EOF
  • Création de l'application

  • Synchronisation

Une fois la synchonisation passée nous avons une présentation des ressources flux dans l'interface d'argoCD

Notez maintenant l'affichage de la kustomization flux cc-podinfo-oci

Si vous tapez la commande :

flux get all -n podinfo
NAME                            REVISION                SUSPENDED   READY   MESSAGE
ocirepository/cc-podinfo-oci    1.0.5@sha256:02b143dd   False       True    stored artifact for digest '1.0.5@sha256:02b143dd'

NAME                    REVISION        SUSPENDED   READY   MESSAGE
helmrepository/podinfo  sha256:61f94c20 False       True    stored artifact: revision 'sha256:61f94c20'

NAME                        REVISION    SUSPENDED   READY   MESSAGE
helmchart/podinfo-podinfo   5.0.3       False       True    pulled 'podinfo' chart with version '5.0.3'

NAME                REVISION    SUSPENDED   READY   MESSAGE
helmrelease/podinfo 5.0.3       False       True    Release reconciliation succeeded

NAME                            REVISION                SUSPENDED   READY   MESSAGE
kustomization/cc-podinfo-oci    1.0.5@sha256:02b143dd   False       True    Applied revision: 1.0.5@sha256:02b143dd

Dans le détail

Les manifestes du répertoire podinfo contenus dans le package OCI argocd:1.0.5 vont être déployés au travers de FSA.

Les manifestes contenus dans le package OCI sont :

---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: podinfo
  namespace: podinfo
spec:
  interval: 1m
  url: https://stefanprodan.github.io/podinfo  
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: podinfo
  namespace: podinfo
spec:
  interval: 5m
  chart:
    spec:
      chart: podinfo
      version: 6.3.5
      sourceRef:
        kind: HelmRepository
        name: podinfo

Cette fois on déploie des "custom resources" flux qui seront synchronisés avec ArgoCD.

FSA a créé :

  • helmrepo
  • helmrelease
  • kustomization
  • helmchart

Si vous tapez la commande :

helm list -n podinfo

NAME    NAMESPACE   REVISION    UPDATED                                 STATUS      CHART           APP VERSION
podinfo podinfo     1           2023-03-21 09:46:32.480300242 +0000 UTC deployed    podinfo-5.0.3   5.0.3

a href="#" id="tconclusions" style="visibility: hidden">

Conclusions

Flamingo nous permet d'avoir une gestion des ressources flux dans argoCD. Le projet est jeune et doit bien évidemment mûrir et acquérir de nouvelles fonctionnalités. Le principal problème à ce jour est que lorsqu'on supprime un application même si son finalizer est positionné les ressources flux ne sont pas supprimées et doivent être néttoyées "à la main" par des commandes flux.

ex:

flux delete helmrelease bb-podinfo-helm-with-fsa -n podinfo-helm-with-fsa
flux delete source helm bb-podinfo-helm-with-fsa  -n podinfo-helm-with-fsa

Découvrez les technologies d'alter way