Csenge Papp

Papp Csenge

  · 10 min read

GitOps az Amazon EKS Capabilities platformon

Argo CD és Kargo a gyakorlatban – előnyök, kompromisszumok és tanulságok

Argo CD és Kargo a gyakorlatban – előnyök, kompromisszumok és tanulságok

Miért kezdtünk el foglalkozni ezzel a témával?

Mi a Codefactory-nál gyakran segítünk az ügyfeleinknek AWS infrastruktúrák tervezésében és megvalósításában. Ezen belül is sokat foglalkozunk EKS-alapú megoldásokkal. Legyen szó egy éppen alakuló startup-ról vagy egy már létező rendszer migrálásáról, a cél itt mindig az, hogy olyan CI/CD-folyamatokat alakíthassunk ki, ahol az applikáció automatikusan, verziózva kerül ki általában több környezetbe.

Ezért is keltette fel az érdeklődésünket, amikor 2025 végén, novemberben az AWS előállt egy újdonsággal, az EKS Capabilities-el. Ez az EKS szolgáltatás egy olyan új komponens, ami többek között lehetővé teszi, hogy az Argo CD-t menedzselt komponensként futtassunk EKS-en.

Alapvetően mi nem GitOps megközelítésben alakítjuk ki a CI/CD folyamatainkat, úgyhogy amellett, hogy megismerhetünk egy új AWS , illetve EKS natív megoldást, szerettük volna kipróbálni, hogy ez az irány merre halad és mennyit fejlődött az utóbbi időszakban.

Mi az a Gitops?

A GitOps egy olyan modell, ahol a rendszer, jelen esetben egy applikáció, kívánt állapota egy Git repository-ban deklaratív módon van tárolva. A Git repó tehát ebben az esetben nemcsak a forráskódot, hanem a telepítés konfigurációját és verzióját is tartalmazza. Nem szükséges külön pipeline a telepítéshez, az aktuális állapotot egy operátor vagy controller (például Argo CD) folyamatosan összehasonlítja a Gitben definiált kívánt állapottal, és ha eltérést talál, automatikusan korrigálja azt.

Ez több szempontból is vonzó megközelítés lehet:

  1. Átlátható: Minden változtatás követhető egy helyen, gitben.
  2. Reprodukálható: A repository alapján bármikor újra felhúzható e rendszer,
  3. Konzisztens: A controller folyamatosan figyeli a driftet és visszaállítja az eredeti állapotot
  4. Vizuális felületek: Az Argo Kargonak letisztult vizuális felületei vannak, ahogy barátságos módon látható a kitelepített verziók és esetleges hibák

Vannak viszont hátrányai is:

  1. Komplexitás: Egy pipeline-t több komponens vált fel (Argo CD, Kargo), ami bonyolultabbá, esetenként drágábbá teszi a rendszert
  2. Megszokás: A fejlesztők és üzemeltetők nem ehhez vannak szokva
  3. Verzióvisszaállás: Ha nem használunk Kargo-t akkor ez igen kényelmetlen, új kommitot igényel, amivel nehezebb hosszabb a feladat
  4. Hibakeresés: Ha valami nem működik, a hiba sokszor több komponensen keresztül jelentkezik, ami nehezíti a hiba megtalálását és kezelését.

A saját tapasztalatunk az, hogy bár a GitOps koncepciója elméletben nagyon elegáns, a gyakorlatban nem mindig ez a legegyszerűbb vagy leghatékonyabb megoldás. Sok ügyfél esetében egy klasszikus CI/CD pipeline érthetőbb, könnyebben üzemeltethető és kevesebb platformkomponenst is igényel.

Mi az AWS EKS Capabilities?

Az EKS Capabilities egy új koncepció az AWS EKS szolgáltatásán belül, amelynek célja, hogy bizonyos Kubernetes-natív eszközöket menedzselt szolgáltatásként lehessen használni. Ez azt jelenti, hogy ezek a komponensek az EKS platform részeként futnak, de nem a saját worker node-jainkon.

A jelenlegi Capability-k:

  • Argo CD: GitOps alapú telepítés
  • ACK (AWS Controllers for Kubernetes): AWS erőforrások kezelése Kubernetes API-n keresztül
  • KRO (Kubernetes Resource Orchestrator): komplex erőforrások és workflow-k kezelésére

Egy klasszikus Kubernetes megközelítésben az ilyen eszközöket általában magunknak kell telepíteni és üzemeltetni. Az EKS Capabilities esetén azonban ezek a feladatok az AWS-re hárulnak. Nekünk nem kell telepíteni, frissíteni és skálázni, csak a konfigurálással kell foglalkoznunk.

Ezen kívül például az Argo CD esetében a natív AWS SSO azonosítást tudjuk használni az Argo felületére való belépéskor is, ami lehetővé teszi, hogy a felhasználókat központilag egy helyen kezeljük.

Argo CD és Kargo a gyakorlatban - ábra 1: Amazon EKS cluster áttekintő
Ábra 1: Amazon EKS cluster áttekintő

Milyen megoldást építettünk és hogyan?

Kezdetnek egy egyszerű folyamatot szerettünk volna kialakítani, ezért készítettünk egy nagyon egyszerű demó appot. A célunk az volt, hogy legyen egy alkalmazás, ami verziózva buildelődik, majd a build után egyszerűen több környezetbe telepíthető. Fontos szempont volt az is, hogy a telepítések egy vizuális felületen keresztül kezelhetők legyenek, a változások Gitben legyenek követve, és szükség esetén könnyen vissza lehessen állni egy korábbi verzióra.

A megoldáshoz három külön repót hoztunk létre.

1. Infrastruktúra repó

Itt helyeztük el az összes szükséges AWS infrastruktúrához használt IaC kódot, amihez Opentofu-t és Terragruntot használtunk. A projekthez szükséges erőforrásokat, VPC-t, EKS-et és ECR-t publikus modulokkal telepítettük az egyszerűség kedvéért. A Kargo telepítést szintén a Terragrunton keresztül végeztük Helm chart segítségével.

A felépítés nagy vonalakban így nézett ki:

Argo CD és Kargo a gyakorlatban - ábra 2: Kubernetes telepítés GitOps-szal az Amazon EKS-en
Ábra 2: Kubernetes telepítés GitOps-szal az Amazon EKS-en

Az Argo CD Capabiltity-nél a beállításainál a jogosultságokat a már létező, Identity Centerben lévő felhasználókhoz, illetve csapatokhoz csatoltuk hozzá:

 argo_configuration = {
   argo_cd = {
     aws_idc = {
       idc_instance_arn = "arn:aws:sso:::instance/ssoins-000000000000"
     }
     namespace = "argocd"
     rbac_role_mapping = [{
       role = "ADMIN"
       identity = [
         # Admin Group Users
         {
           id   = "00000000-0000-0000-0000-000000000000"
           type = "SSO_GROUP"
         }
       ]
     }]
   }
 }

2. Application repo

Itt egy egyszerű alkalmazáskód kapott helyet, amit egy Github workflow új verzió tag létrejöttekor automatikusan feltett egy ECR image repóba. A cél innentől az volt, hogy az új image-ket a Kargo automatikusan felismerje és Argo CD segítségével telepíteni tudja Kubernetesre.

Argo CD és Kargo a gyakorlatban - ábra 3: Amazon EKS konténerképek
Ábra 3: Amazon EKS konténerképek

3. GitOps repó

Mivel szinte minden Kubernetes projektünkön használunk Helm chart-okat , itt is ezt a megközelítést szerettük volna alkalmazni. Így tehát ebben a repóban helyet kapott egy Helm chart, benne mindennel, ami az alkalmazás telepítéséhez szükséges. Ezen felül itt kaptak helyet az Argo CD és a Kargo config fájljai.

A felépítéshez találtunk egy jól strukturált példát a Kargo hivatalos dokumentációjában. Mindössze néhány módosításra volt szükség, főként az EKS-specifikus beállítások miatt.

Az Argo CD megfelelő működéséhez létrehoztunk:

  1. AppProject: Az Argo CD-ben az alkalmazások jogosultságait és telepítési hatókörét meghatározza meg.

    apiVersion: argoproj.io/v1alpha1
    kind: AppProject
    metadata:
      name: <PROJECT_NAME>
      namespace: argocd
    spec:
      clusterResourceWhitelist:
      - group: '*'
        kind: '*'
      destinations:
      - name: <CLUSTER_NAME>
      namespaceResourceWhitelist:
      - group: '*'
        kind: '*'
      sourceRepos:
      - <GITHUB_REPO_URL>
      sourceNamespaces:
      - argocd
      - <PROJECT_NAME>-dev
      - <PROJECT_NAME>-prod
  2. AppSet (ApplicationSet): több Application (egy alkalmazás telepítéséshez szükséges konfiguráció) automatikus generálására szolgáló komponens.

    apiVersion: argoproj.io/v1alpha1
    kind: ApplicationSet
    metadata:
      name: <PROJECT_NAME>
      namespace: argocd
    spec:
      generators:
      - list:
          elements:
          - stage: dev
          - stage: prod
      - git:
          repoURL: <SOURCE_REPO_URL>
          revision: HEAD
          directories:
          - path: env/*
      template:
        metadata:
          name: <PROJECT_NAME>-{{path.basename}}
          annotations:
            kargo.akuity.io/authorized-stage: argo-kargo-poc:{{path.basename}}
        spec:
          destination:
            namespace: <PROJECT_NAME>-{{path.basename}}
            name: <CLUSTER_NAME>
          project: <PROJECT_NAME>
          source:
            path: helm/<HELM_CHART_NAME>
            repoURL: <SOURCE_REPO_URL>
            helm:
              valueFiles:
              - "/env/{{path.basename}}/values.yaml"
              - "/env/{{path.basename}}/feature-flags.yaml"
  3. Cluster Registration: A Kubernetes cluster felvétele Argo CD-ben.

    apiVersion: v1
    kind: Secret
    metadata:
      name:<CLUSTER_NAME>
      namespace: argocd
      labels:
        argocd.argoproj.io/secret-type: cluster
    stringData:
      name: <CLUSTER_NAME>
      server: <CLUSTER_ARN>
      project: <PROJECT_NAME>
  4. GitHub Repo Secret: Ez ahhoz volt szükséges, hogy az Argo CD hozzáférhessen a github repóban tárolt információhoz.

    apiVersion: v1
    kind: Secret
    metadata:
     name: argocd-github
     namespace: argocd
     labels:
       argocd.argoproj.io/secret-type: repository
    stringData:
     type: git
     url: <GITHUB_REPO_URL>
     username: <USERNAME>
     password: <PAT_TOKEN>
     project: <PROJECT_NAME>

Az eredmény így nézett ki az Argo CD UI felületén:

Argo CD és Kargo a gyakorlatban - ábra 4: az Argo CD felhasználói felülete
Ábra 4: az Argo CD felhasználói felülete

A Kargo az előbbiekhez hasonlóan:

  1. Project: Az Argo CD projekthez hasonlóan az alkalmazás telepítő pipeline-ját fogja össze.

    apiVersion: kargo.akuity.io/v1alpha1
    kind: Project
    metadata:
      name: <PROJECT_NAME>
      annotations:
        # This annotation ensures Projects (Namespaces) ..
        # .. are created first when deployed via Argo CD
        argocd.argoproj.io/sync-wave: "-1"
  2. Warehouse: A telepítéshez szükséges artifaktok (például container image-ek vagy Git commitok) forrását definiálja és figyeli azok változását.

    apiVersion: kargo.akuity.io/v1alpha1
    kind: Warehouse
    metadata:
      name: application
      namespace: <PROJECT_NAMESPACE>
    spec:
      subscriptions:
      - image:
          repoURL: <ECR_REPO_URL>
          imageSelectionStrategy: SemVer
    
    ---
    apiVersion: kargo.akuity.io/v1alpha1
    kind: Warehouse
    metadata:
      name: gitops
      namespace: <PROJECT_NAMESPACE>
    spec:
      subscriptions:
      - git:
          branch: main
          commitSelectionStrategy: NewestFromBranch
          discoveryLimit: 20
          repoURL: <GITHUB_REPO_URL>
  3. Stage: Itt írtuk le a környezeteket.

    apiVersion: kargo.akuity.io/v1alpha1
    kind: Stage
    metadata:
      name: dev
      namespace: <PROJECT_NAMESPACE>
      annotations:
        kargo.akuity.io/color: green
        kargo.akuity.io/argocd-context: 
        '[{"name":"argo-kargo-poc-dev","namespace":"argocd"}]'
    spec:
      requestedFreight:
      - origin:
          kind: Warehouse
          name: application
        sources:
          direct: true
      - origin:
          kind: Warehouse
          name: gitops
        sources:
          direct: true
      promotionTemplate:
        spec:
          steps:
          - task:
              name: promote
    
    ---
    apiVersion: kargo.akuity.io/v1alpha1
    kind: Stage
    metadata:
      name: prod
      namespace: <PROJECT_NAMESPACE>
      annotations:
        kargo.akuity.io/color: purple
        kargo.akuity.io/argocd-context: 
        '[{"name":"argo-kargo-poc-prod","namespace":"argocd"}]'
    spec:
      requestedFreight:
      - origin:
          kind: Warehouse
          name: application
        sources:
          direct: true
      - origin:
          kind: Warehouse
          name: gitops
        sources:
          direct: true
      promotionTemplate:
        spec:
          steps:
            - task:
                name: promote
  4. PromotionTask: Meghatározza, hogyan történik egy új artifakt előléptetése egyik stage-ből a másikba (például test → production).

    apiVersion: kargo.akuity.io/v1alpha1
    kind: PromotionTask
    metadata:
      name: promote
      namespace: <PROJECT_NAMESPACE>
    spec:
      vars:
      - name: image
        value: <ECR_REPO_URL>
      - name: repoURL
        value: <SOURCE_REPO_URL>
      - name: branch
        value: main
    
      steps:
      - uses: git-clone
        config:
          repoURL: ${{ vars.repoURL }}
          checkout:
          - branch: ${{ vars.branch }}
            path: ./out
      - if: ${{ ctx.targetFreight.origin.name == "application" }}
        uses: yaml-update
        as: update-image
        config:
          path: ./out/env/${{ ctx.stage }}/values.yaml
          updates:
          - key: image.tag
            value: ${{ imageFrom( vars.image ).Tag }}
      - if: ${{ ctx.targetFreight.origin.name == "gitops" }}
        uses: git-clone
        config:
          repoURL: ${{ vars.repoURL }}
          checkout:
          - commit: ${{ commitFrom( vars.repoURL ).ID }}
            path: ./gitops
      - if: ${{ ctx.targetFreight.origin.name == "gitops" }}
        uses: copy
        config:
          inPath: ./gitops/base/feature-flags.yaml
          outPath: ./out/env/${{ ctx.stage }}/feature-flags.yaml
      - uses: git-commit
        as: commit
        config:
          path: ./out
          message: "${{
            ctx.targetFreight.origin.name == 'application' ? 
            'updated '+ctx.stage+' application to '+imageFrom( vars.image ).Tag :
            'updates '+ctx.stage+' gitops.yaml from '+commitFrom( vars.repoURL ).ID
            }}"
      - uses: git-push
        config:
          path: ./out
      - uses: argocd-update
        config:
          apps:
          - name: a<PROJECT_NAMESAPCE>-${{ ctx.stage }}
  5. GitHub Repo Secret: Biztosítja a hitelesített hozzáférést a GitHub repository-hoz.

    apiVersion: v1
    kind: Secret
    metadata:
      name: kargo-github
      namespace: <PROJECT_NAMESPACE>
      labels:
        kargo.akuity.io/cred-type: git
    stringData:
      repoURL: <GITHUB_REPO_URL>
      username: <USERNAME>
      password: <PAT_TOKEN>

Végeredmény

A Kargo UI felületén balra fent automatikusan megjelenik az új verzió, amit egyszerű drag-and-drop funkcióval ki is telepíthetünk. Egy pár másodperc múlva már indulnak is az új podok a clusteren, és a kirakott verziószáma is azonnal beíródik a Github repóba.

Argo CD és Kargo a gyakorlatban - ábra 5: Kargo dashboard deployment ábra
Ábra 5: Kargo dashboard deployment ábra

Milyen kihívásokkal találkoztunk?

Az Argo CD és a Kargo dokumentációján túl a hivatalos AWS dokumentációt is felhasználtuk a teljes folyamat összeállításához. A rendszer kialakítása összességében viszonylag egyszerűnek bizonyult. Az egyetlen komolyabb kihívást a jogosultságok megfelelő beállítása jelentette.

Több komponensnek kellett együttműködnie (AWS, Kubernetes, Argo CD, Kargo és GitHub), ezért fontos volt, hogy minden szükséges hozzáférés megfelelően legyen konfigurálva. Ennek beállítása során néhány nehézségbe ütköztünk, ezért itt összegyűjtöttük egy listába azokat a jogosultságokat és beállításokat, amelyek feltétlenül szükségesek.

  1. Argo CD ➛ EKS cluster

    A Capability telepítése során az Argo CD által használt IAM role bekerül az EKS access entry-k közé. Ennek köszönhetően az Argo CD képes kommunikálni a clusterrel és kezelni a Kubernetes erőforrásokat.

  2. Argo CD ➛ Github repó

    Ahhoz, hogy az Argo CD elérje a Github repóban tárolt konfigurációkat, egy Kubernetes Secret-ben tárolt PAT-tokent használtunk. Ha ennél biztonságosabb vagy rugalmasabb megoldásra van szükség, az autentikáció megvalósítható SSH kulccsal vagy GitHub App-on keresztül is. Ez lehetővé teszi a hozzáférések központi és auditálható kezelését, miközben elkerülhető a statikus tokenek közvetlen tárolása.

  3. Argo CD ➛ AWS felhasználók

    Ez a fent leírt módon közvetlenül az Argo CD Capability-ben állítottuk be, a már létező Identity Center group- jainkra. Erről az AWS dokumentációban tudtok bővebben olvasni.

  4. Kargo ➛ ECR repó

    A Kargo figyeli az AWS ECR-ben tárolt container image-eket, és ezek alapján kezeli az artifaktok promócióját a különböző stage-ek között. Az új image tagek követésével a Kargo automatikusan észlelni tudja az új verziókat, és a konfigurált promóciós folyamatnak megfelelően tovább tudja léptetni azokat a meghatározott környezeteken keresztül.

    Annak érdekében, hogy a Kargo hozzáférjen az ECR repository-hoz, EKS Pod Identity Association-t konfiguráltunk. Ez a mechanizmus lehetővé teszi, hogy egy Kubernetes ServiceAccount egy IAM role-t vehessen fel, amely biztosítja az AWS szolgáltatásokkal való kommunikációhoz szükséges jogosultságokat.

    A Kargo service accounthoz rendelt IAM role tartalmazza a szükséges ECR olvasási jogosultságokat:

    • ecr:DescribeImages
    • ecr:ListImages
    • ecr:BatchGetImage
  5. Kargo ➛ Github repó

    A Kargo a repository-ban található konfigurációk alapján végzi a telepítő pipeline lépéseit és a stage-ek közötti promóciót. Mi itt is egy Kubernetes Secretet használtunk, amiben tároltuk a szükséges GitHub PAT-tokent, de ebben az esetben is lehetőség van SSH kulcsos, vagy Github App-on keresztüli azonosításra is. A részletekről tudtok olvasni itt: managing-credentials .

Mire jutottunk?

A folyamat sikeres volt abból a szempontból, hogy a projekt elején kitűzött célokat sikerült megvalósítani. Az alkalmazás telepítése és verziókezelése viszonylag egyszerűen implementálható volt az Argo CD és a Kargo segítségével. A megoldás lehetővé tette, hogy az alkalmazást verziózott formában telepítsük egy Kubernetes clusterre két különböző környezetbe.

Emellett az Argo CD vizuális felületének köszönhetően a telepítési folyamat átláthatóvá vált. Könnyen követhető volt, hogy mely verzió fut az adott környezetben, milyen változások történtek, és hogy a cluster állapota megfelel-e a Git repositoryban definiált kívánt állapotnak.

A Gitops által hozzáadott értéket ebben az esetben pont ez az átláthatóság jelentette nekünk. A Kargo használatával mentesültünk az alól, hogy manuálisan kelljen változtatni a git repóban egy új verzió vagy egy esetleges visszaállás során. Tapasztalataink szerint ez nagy segítség lehet a fejlesztő- és üzemeltető csapatoknak. Ugyanakkor a jelenlegi tapasztalataink alapján számunkra még nem vált teljesen egyértelművé, hogy az ehhez kapcsolódó többleteszközök, üzemeltetési feladatok és esetleges költségek minden esetben arányban állnak-e az így elérhető előnyökkel.

A jövőben szeretnénk ezt a kísérletet kiegészíteni további automatizációs lépésekkel, például automatikus teszteléssel vagy akár több környezet kezelésével. Emellett érdekes irány lehet a GitOps alapú folyamatok kipróbálása nemcsak az alkalmazások telepítésére, hanem az infrastruktúra kezelésére is, például IaC megoldások integrálásával.

Felhasznált források


Kérdésed van? Írj nekünk, és mi segítünk megtalálni a számodra optimális megoldásokat.

Share:
Vissza a cikkekhez