GitOps z Flux i AWS EKS
Cześć! W dzisiejszym wpisie zagłębimy się w temat GitOps omawiając, jak to podejście zmienia sposób automatyzacji wdrożeń aplikacji i zarządzania infrastrukturą. Przeanalizujemy czym jest GitOps, jak narzędzia GitOps integrują się z repozytoriami kodu i jakie korzyści oraz wyzwania wiążą się z jego wdrożeniem. Do praktycznego przykładu wykorzystamy FluxCD, które będzie synchronizowało zmiany w repozytorium z klastrem Kubernetes uruchomionym na AWS EKS. Zapraszam do lektury!
Spis treści
Co to jest GitOps?
GitOps to podejście do automatycznego wdrażania i zarządzania infrastrukturą oraz aplikacjami. Opiera się na takiej zasadzie, że cała konfiguracja infrastruktury jest przechowywana w repozytorium kodu. Narzędzie GitOps monitoruje to repozytorium jak i stan rzeczywistej infrastruktury automatycznie wprowadzając korekty aby stan infrastruktury zawsze odpowiadał deklaracjom zapisanym w kodzie.
GitOps łączy w sobie dwie kluczowe koncepcje: infrastruktura jako kod (IaC) oraz ciągłe dostarczanie (CD).
Podejście to oferuje szereg korzyści, ale wiąże się także z pewnymi ograniczeniami, o których warto wiedzieć przed podjęciem decyzji o jego wdrożeniu. Szczegóły w tej kwestii omówię w dalszej części wpisu.
Tradycyjne podejście do CD
Zanim przejdziemy do omówienia w jaki sposób wygląda wdrażanie zmian i ich monitorowanie przy użyciu narzędzi GitOps w pierwszej kolejności warto przyjrzeć się standardowemu procesowi budowy i wdrażania oprogramowania, który do tej pory był stosowany w większości projektów.
W tradycyjnym podejściu programiści przesyłają swoje zmiany do repozytorium kodu korzystając z różnych strategii zarządzania gałęziami (branching). W repozytorium często działają githooki, które uruchamiają procesy w zewnętrznych systemach. Systemy te bazując na zawartości repozytorium i dostarczonych zmianach budują aplikację.
Proces ciągłej integracji (CI) tworzy artefakty – mogą to być obrazy Docker, pliki JAR czy inne wykonywalne pakiety. Po zakończeniu budowy często wymagane jest ręczne wyzwolenie wdrożenia nowej wersji aplikacji na środowisko choć w niektórych projektach proces ten jest w pełni zautomatyzowany. W tradycyjnym podejściu narzędzia używane do CI i CD często są tymi samymi systemami.
CD z użyciem GitOps
W przypadku podejścia GitOps proces wdrażania zmian różni się od tradycyjnego modelu choć początek jest podobny. Programista tworzy nowy kod i przesyła go do repozytorium. Następnie uruchamiany jest proces CI, który buduje nową wersję aplikacji i zapisuje gotowy artefakt w magazynie, przygotowując go do wdrożenia.
W podejściu GitOps zakładamy jednak, że cała definicja infrastruktury – nie tylko kod źródłowy – znajduje się w repozytorium. Jeśli chcemy wprowadzić zmiany w działającej infrastrukturze wówczas aktualizacja konfiguracji w repozytorium staje się częścią procesu CI. W praktyce oznacza to, że CI nie tylko buduje aplikację, ale także modyfikuje odpowiednie pliki konfiguracyjne w repozytorium aby odzwierciedlić zmiany.
Krok ten oznaczony na diagramie jako „Config update” automatycznie informuje system GitOps o wprowadzonych zmianach. Warto zaznaczyć, że istnieją również alternatywne rozwiązania, w których proces CI nie odpowiada za aktualizację repozytorium. Jedno z takich podejść zostanie omówione później.
Narzędzie GitOps stale monitoruje zawartość naszego repozytorium. Gdy wykryje jakiekolwiek różnice między zapisanymi definicjami, a aktualnym stanem infrastruktury wówczas automatycznie podejmie działania by dostosować infrastrukturę do pożądanego stanu. Dzięki temu zapewniamy zgodność rzeczywistego środowiska z konfiguracją opisaną w repozytorium.
Plusy i minusy GitOps
GitOps oferuje wiele korzyści. Nie jest jednak uniwersalnym rozwiązaniem dla każdego projektu. W niektórych przypadkach, w szczególności jeśli nie stosujemy dodatkowych dobrych praktyk może wprowadzić więcej problemów niż korzyści. Poniżej przedstawiam zestawienie najważniejszych zalet i wad GitOps.
Zalety:
- Spójność i powtarzalność wdrożeń
Dzięki automatyzacji cały proces wdrażania jest przewidywalny, a stan infrastruktury odzwierciedla definicje zapisane w repozytorium. - Wyższa produktywność programistów
Programiści nie muszą zajmować się procesem wdrażania – operują wyłącznie na poziomie Gita, który jest narzędziem dobrze im znanym. - Krótsze przestoje
Automatyczne rollbacki w przypadku niezgodności lub błędów zmniejszają ryzyko i czas awarii. - Skrócony czas dostarczania oprogramowania
Zmiany są automatycznie wdrażane po zatwierdzeniu w repozytorium, co redukuje czas potrzebny na ręczne procesy. - Lepsza przejrzystość SDLC (Software Development Lifecycle)
Wszystkie zmiany, konfiguracje i historia są widoczne w repozytorium, co ułatwia zrozumienie i zarządzanie cyklem życia oprogramowania. - Wiele dodatkowych korzyści
Automatyzacja zmniejsza ryzyko błędów ludzkich, wspiera lepsze praktyki DevOps i ułatwia skalowanie procesów.
Wady:
- Duża liczba repozytoriów
W dużych projektach może być konieczne utrzymanie wielu repozytoriów dla aplikacji, konfiguracji i infrastruktury, co komplikuje zarządzanie. - Konflikty w Git
Przy wysokiej częstotliwości zmian i częstych pushy od systemu CI mogą pojawić się konflikty, które trzeba ręcznie rozwiązywać. - Trudności w audycie
Duża ilość konfiguracji w repozytoriach może utrudniać szybkie znalezienie interesującej części. - Problemy z przechowywaniem sekretów
GitOps sam w sobie nie rozwiązuje kwestii bezpiecznego zarządzania sekretami.
Wymienione wyżej zalety i wady GitOps mogą, ale nie muszą odnosić się do Twojego projektu. Wszystko zależy od poziomu dojrzałości procesów i dobrych praktyk, które już funkcjonują w Twojej organizacji.
Jeśli w konfiguracjach panuje chaos GitOps może dodatkowo skomplikować zarządzanie infrastrukturą, zamiast je usprawnić. Natomiast w przypadku dobrze utrzymanej higieny kodu i spójnych procesów GitOps może stać się cennym narzędziem do automatyzacji i przyspieszenia wdrożeń.
Ważne jest, aby nie wdrażać tego podejścia w sposób bezrefleksyjny. Zamiast tego warto rozpocząć od eksperymentów na mniejszym projekcie. Pozwoli to przetestować podejście w kontrolowanych warunkach i wyciągnąć wnioski przed rozszerzeniem GitOps na większe i bardziej złożone części infrastruktury.
FluxCD
Flux (często nazywane też FluxCD) to jedno z najpopularniejszych narzędzi GitOps, które zaprojektowano do ścisłej współpracy z Kubernetes. Jego działanie opiera się na Custom Resource Definitions (CRD), które pozwalają na synchronizację różnych źródeł kodu z klastrem Kubernetes.
W FluxCD kluczowymi obiektami są:
- GitRepository – definiuje źródło kodu, z którego Flux pobiera dane.
- Kustomization – określa zasoby, które mają zostać zsynchronizowane z klastrem.
Flux obsługuje popularne platformy hostujące repozytoria takie jak GitHub, GitLab czy Bitbucket, co czyni go elastycznym i uniwersalnym rozwiązaniem. Dokumentację Flux znajdziemy w tym miejscu.
Wdrożenie aplikacji na klaster Kubernetes z wykorzystaniem Flux
W tej części wpisu pokażę, jak krok po kroku wykorzystać podejście GitOps do wdrożenia aplikacji na klastrze Kubernetes. Na potrzeby tego przykładu użyjemy statycznej strony internetowej hostowanej w kontenerze. Oto etapy, które przeprowadzimy:
- Stworzenie klastra AWS EKS oraz repozytorium Amazon ECR
Wykorzystamy do tego narzędzie Terraform, aby zautomatyzować proces tworzenia infrastruktury. - Instalacja Flux w klastrze Kubernetes
Flux będzie odpowiadał za śledzenie repozytorium z konfiguracją aplikacji i synchronizację z klastrem. - Budowa obrazu kontenera dla aplikacji w wersji 1.0.0
Przygotujemy i opublikujemy pierwszy obraz kontenera w Amazon ECR. - Dodanie aplikacji do klastra Kubernetes
Zdefiniujemy konfigurację aplikacji, aby Flux mógł wdrożyć ją w klastrze. - Automatyczne śledzenie nowych wydań w Amazon ECR
Skonfigurujemy Flux tak, aby automatycznie wykrywał nowe wersje obrazu aplikacji. - Wydanie nowej wersji aplikacji 1.0.1
Wypuścimy aktualizację aplikacji, aby zobaczyć, jak Flux automatycznie wdraża nową wersję.
Poniżej znajdziesz architekturę naszego rozwiązania.
W rozwiązaniu skorzystamy z trzech repozytoriów:
- AWS EKS i Amazon ECR
Repozytorium to zawiera konfigurację Terraform naszej infrastruktury, w tym klaster AWS EKS oraz repozytorium Amazon ECR.
Link: AWS EKS i Amazon ECR - FluxCD
To repozytorium zawiera konfigurację FluxCD, który będzie odpowiedzialny za synchronizację aplikacji i infrastruktury z naszym klastrem Kubernetes.
Link: FluxCD - Web-app
Repozytorium zawiera kod źródłowy naszej aplikacji – statycznej strony internetowej, która zostanie uruchomiona w kontenerze.
Link: Web-app
Infrastruktura
Aby stworzyć klaster Kubernetes i magazyn obrazów Docker w Amazon ECR skorzystamy z usług AWS oraz narzędzia Terraform. Proces jest prosty i sprowadza się do kilku komend, które uruchamiamy w repozytorium kodu Terraform dołączonym do tego wpisu.
Jak działa HashiCorp Terraform ?
Jeśli nie jesteś zaznajomiony z tym narzędziem warto najpierw zrozumieć w jaki sposób Terraform pozwala na tworzenie i zarządzanie infrastrukturą. Terraform to narzędzie, które umożliwia definiowanie infrastruktury jako kodu (IaC). Jeśli chcesz zgłębić temat i dowiedzieć się, jak działa Terraform zachęcam do zapoznania się z moim wpisem, który dostępny jest pod tym linkiem: HashiCorp Terraform: Infrastruktura jako kod
FluxCD
Kolejnym krokiem jest pobranie Flux CLI oraz użycie go do zainstalowania kontrolerów Flux w klastrze Kubernetes. Instrukcja instalacji jest inna w zależności od systemu operacyjnego. Kiedy Flux CLI jest już zainstalowane kolejnym zadaniem jest zaktualizowanie pliku kubeconfig, który pozwala Fluxowi na komunikację z naszym klastrem Kubernetes w AWS EKS. Wykonujemy aws eks update-kubeconfig --region eu-central-1 --name Git-Ops-al2023
. Następnie warto upewnić się, że wersja Flux i Kubernetes są ze sobą kompatybilne: flux check --pre
Aby zbootstrapować Flux musimy dostarczyć mu token z uprawnieniami, które umożliwią stworzenie repozytorium na naszym GitHubie. W tym celu należy wygenerować token dostępu do GitHub z odpowiednimi uprawnieniami i przypisać go do zmiennej środowiskowej GITHUB_TOKEN
. Dodatkowo musimy przypisać pasujący username do zmiennej GITHUB_USER
. Uruchamiamy poniższe polecenie:
flux bootstrap github \
--token-auth=false \
--owner=red-devops \
--repository=FluxCD \
--branch=main \
--path=./clusters/dev-cluster \
--components-extra image-reflector-controller,image-automation-controller
Dokładne informacje na temat każdej flagi znajdziecie w dokumentacji, ale w naszym przykładzie szczególnie istotna jest flaga --components-extra
. Potrzebujemy tych dodatkowych kontrolerów, aby Flux mógł automatycznie pobierać wersje kontenerów z Amazon ECR.
Warto wspomnieć kilka słów na temat struktury folderów w naszych repozytoriach. W tym rozwiązaniu zastosowałem podejście, w którym kod aplikacji znajduje się w osobnym repozytorium niż jego definicje w Kustomize. Dzięki temu oddzielamy kod aplikacji od jego konfiguracji, co ułatwia zarządzanie i pozwala na stosowanie tego podejścia do starszych aplikacji. Istnieje również inne podejście, w którym zarówno kod aplikacji, jak i jego definicje dla Kubernetesa znajdują się w tym samym repozytorium. Nie ma jednoznacznej odpowiedzi, które z tych podejść jest lepsze – więcej na ten temat można znaleźć na stronie Flux.
Struktura naszego repo na ten moment wygląda następująco.
Web-app auto release
Zanim będziemy mogli wdrożyć naszą aplikację na klaster musimy najpierw zbudować pierwszą wersję 1.0.0. W repozytorium na GitHubie FluxCD-Web-app umieściłem prosty Dockerfile, plik index.html oraz definicje dla GitHub Actions w pliku ci.yml widocznym niżej.
name: "Web-App-CI"
on:
push:
branches:
- main
env:
REGION: eu-central-1
APPLICATION_NAME: web-app
jobs:
build_and_published:
name: Build and published image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set web-app version
run: |
APP_VERSION=$(grep -oP '(?<=version )[\d.]+(?=</h1>)' index.html)
echo "web-app version: $APP_VERSION"
echo "APP_VERSION=$APP_VERSION" >> "$GITHUB_ENV"
- name: Docker build
run: |
docker build -t ${{ env.APPLICATION_NAME }}:$APP_VERSION .
- name: Push to ECR
uses: jwalton/gh-ecr-push@v2
with:
access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
region: ${{ env.REGION }}
local-image: ${{ env.APPLICATION_NAME }}:$APP_VERSION
image: ${{ env.APPLICATION_NAME }}:$APP_VERSION
GitHub Actions będzie automatycznie budować nowy obraz kontenera i wypychać go do Amazon ECR za każdym razem gdy pojawi się nowy commit na branchu main. Warto zauważyć, że wersja kontenera jest ustawiana za pomocą zmiennej APP_VERSION
, która jest pobierana z pliku index.html.
Po wypchnięciu pierwszej wersji obrazu do GitHub i odczekaniu kilku chwil możemy zauważyć, że obraz jest już gotowy do użycia. Aby to sprawdzić możemy użyć poniższego polecenia: aws ecr list-images --repository-name web-app | jq -r '.imageIds[].imageTag'
Dodanie aplikacji do klastra
Aby wdrożyć aplikację na klaster, musimy dostarczyć Flux definicję aplikacji, którą ma śledzić. Do tego celu potrzebujemy dwóch elementów. Po pierwsze, definicji repozytorium kodu typu GitRepository, aby Flux wiedział, gdzie szukać definicji. Po drugie definicji typu Kustomization, która określa, jakie obiekty Kubernetes mają być synchronizowane. Więcej informacji na ten temat można znaleźć tutaj.
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: web-app
namespace: default
spec:
interval: 30s
ref:
branch: main
url: ssh://git@github.com:22/Red-DevOps/FluxCD.git
secretRef:
name: web-app-auth
Jak można zauważyć, aby powyższy obiekt działał prawidłowo musimy stworzyć secret web-app-auth, który autoryzuje połączenie z repozytorium. Istnieje kilka metod autoryzacji, ale w tym przypadku wykorzystałem autoryzację po kluczu SSH. Możemy to zrobić za pomocą następującego polecenia: flux create secret git web-app-auth --namespace=default --url=ssh://git@github.com/red-devops/FluxCD --private-key-file=./id_rsa
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: web-app
namespace: default
spec:
interval: 30m0s
path: ./infra/web-app/deploy
prune: true
retryInterval: 2m0s
sourceRef:
kind: GitRepository
name: web-app
targetNamespace: default
timeout: 3m0s
wait: true
W Kustomization określamy, gdzie znajdują się definicje naszej aplikacji oraz w jakim repozytorium Flux ma ich szukać. Możemy także ustawić dodatkowe elementy, takie jak interwał czyli w jakich odstępach czasu Flux ma sprawdzać zmiany w konfiguracji i synchronizować stan klastra.
Zanim jednak wprowadzimy te zmiany musimy jeszcze dodać definicję aplikacji w odpowiedniej ścieżce ./infra/web-app/deploy
i wypchnąć ją do zdalnego repozytorium, w którym Flux będzie jej szukał.
Struktura plików na ten moment wygląda następująco:
Plik kustomization.yaml
jest bardzo prosty – wskazuje na pozostałe dwie definicje znajdujące się w folderze.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
Oba powyższe pliki są typowymi obiektami Kubernetes, tj. deployment.yaml i service.yaml dlatego pomijam ich szczegółowe omówienie. Kod jest dostępny na GitHubie, więc jeśli chcecie sprawdzić definicje wspomnianych plików tam z łatwością je odnajdziecie.
Po wypchnięciu zmian do zdalnego repozytorium wrzucamy nowe definicje do klastra za pomocą poniższych poleceń:kubectl -n default apply -f infra/web-app/web-app-source.yaml
kubectl -n default apply -f infra/web-app/web-app-kustomization.yaml
Aby sprawdzić czy aplikacja serwuje stronę poprawnie możemy przekierować połączenie i zweryfikować jej działanie. kubectl port-forward svc/web-app 8080:80
Automatyczne śledzenie nowych wydań w Amazon ECR z Flux
Wygląda na to, że nasza aplikacja działa prawidłowo. Pierwsza część zadania za nami, ale jeśli chcemy, aby Flux automatycznie zmieniał wersje aplikacji musielibyśmy ręcznie zmieniać wersję kontenera w pliku ./infra/web-app/deploy/deployment.yaml
. W naszym przypadku chcemy, aby Flux automatycznie odczytywał wersje z Amazon ECR i aktualizował definicje w tym pliku.
Aby to osiągnąć podczas bootstrapowania Fluxa zainstalowaliśmy dwa dodatkowe komponenty: image-reflector-controller oraz image-automation-controller. Teraz dodamy trzy dodatkowe obiekty do naszego klastra. Pomogą one w automatycznej aktualizacji wersji. Będą to:
image-policy.yaml
image-repository.yaml
image-update-automation.yaml
Te obiekty pozwolą Fluxowi na monitorowanie nowych wydań w Amazon ECR oraz automatyczne aktualizowanie definicji aplikacji w Kubernetes, bez potrzeby manualnej ingerencji.
Przyjrzyjmy się tym trzem definicjom.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: web-app
namespace: default
spec:
imageRepositoryRef:
name: web-app
policy:
semver:
range: 1.0.x
W tym pliku określamy referencje do repozytorium oraz to, na jaką zmianę Flux ma reagować.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
name: web-app
namespace: default
spec:
image: <AWS_ACCOUNT>.dkr.ecr.eu-central-1.amazonaws.com/web-app
interval: 1h
provider: generic
secretRef:
name: regcred
Drugi plik, tak jak przy definicji repozytorium kodu określa gdzie Flux będzie szukał nowych wersji obrazów. Podobnie jak wcześniej musimy się zautoryzować za pomocą sekretu regcred
. Ja utworzyłem ten sekret za pomocą polecenia:
kubectl create secret docker-registry regcred \
--docker-server=${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/web-app \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password) \
--namespace=default
I ostatni plik, który jest chyba najbardziej interesujący.
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: web-app-update
namespace: default
spec:
interval: 30m
sourceRef:
kind: GitRepository
name: web-app
git:
checkout:
ref:
branch: main
commit:
author:
email: fluxcdbot@users.noreply.github.com
name: fluxcdbot
messageTemplate: |-
Automated image update by Flux
push:
branch: main
update:
path: ./infra/web-app/deploy/deployment.yaml
strategy: Setters
W tym pliku określamy repozytorium kodu, plik, strategię, autora i kilka innych informacji związanych ze zmianami, które Flux wprowadzi w momencie spełnienia warunku z obiektu ImagePolicy. Warto zwrócić uwagę na jeden kluczowy element, który jest niezbędny, aby nasza zmiana zadziałała. Mimo że wskazujemy plik, w którym zmiana ma wystąpić Flux nie wie, w której dokładnie linijce, i w którym miejscu ma tę zmianę wprowadzić.
Aby rozwiązać ten problem musieliśmy użyć specjalnej składni w tym pliku. Jeśli spojrzymy na fragment kodu deployment.yaml
zauważymy, że dla parametru image
po komentarzu znajduje się informacja, która mówi ImageUpdateAutomation, gdzie dokładnie ma wprowadzić zmianę. Jest to # {"$imagepolicy": "default:web-app"}
...
containers:
- name: web-app
image: <AWS_ACCOUNT>.dkr.ecr.eu-central-1.amazonaws.com/web-app:1.0.0 # {"$imagepolicy": "default:web-app"}
ports:
- name: http
containerPort: 80
protocol: TCP
...
Podobnie jak wcześniej wprowadzamy teraz wszystkie 3 nowe definicje do Kubernetes za pomocą polecenia: kubectl -n default apply -f <ścieżka_do_pliku>
Po zastosowaniu tych zmian możemy sprawdzić, co mówią logi ImageUpdateAutomation za pomocą polecenia: kubectl describe ImageUpdateAutomation
Repozytorium jest aktualne i nie trzeba wprowadzać zmian.
Wydajemy nową wersję aplikacji 1.0.1
Spróbujmy wydać nową wersję aplikacji 1.0.1 i sprawdźmy, czy Flux poprawnie przeprowadzi cały proces. Zobaczymy jak Flux najpierw wykryje nowy obraz, potem zaktualizuje definicję deploymentu, a na koniec zaktualizuje infrastrukturę zgodnie z nową definicją deploymentu.
Pierwszym krokiem jest wypchnięcie zmian do repozytorium Flux-web-app. Po utworzeniu nowego obrazu czekamy aż Flux wykona swoje zadanie. Możemy jednak przyspieszyć ten proces wykonując polecenie: flux reconcile image repository web-app -n default
Polecenie to wymusi natychmiastowe sprawdzenie nowych obrazów przez Flux i zaktualizowanie konfiguracji aplikacji w Kubernetes.
Widzimy, że Flux wykrył dwa tagi w zadeklarowanym repozytorium, co oznacza, że nasza nowa wersja aplikacji (1.0.1) została prawidłowo zidentyfikowana.
ImageUpdateAutomation również wykonał swoje zadanie i zaktualizował definicję w repozytorium commitując nową wersję aplikacji. Dzięki temu Flux zaktualizował definicję deploymentu w Kubernetes uwzględniając nowy obraz kontenera, co umożliwiło automatyczne wdrożenie nowej wersji aplikacji na klastrze.
Na koniec wykonujemy ostatnie sprawdzenie by upewnić się, że aplikacja działa poprawnie w nowej wersji.
Podsumowanie
W dzisiejszym wpisie omówiliśmy podejście GitOps oraz w jaki sposób wykorzystać FluxCD w celu automatyzacji deploymentu aplikacji na klastrze Kubernetes. Zaczynając od podstaw przypomnę, że GitOps to podejście, w którym cała infrastruktura oraz konfiguracja aplikacji są przechowywane w repozytorium Git, a narzędzia GitOps (takie jak FluxCD) monitorują zmiany w repozytorium i automatycznie synchronizują stan rzeczywisty z tym zapisanym w Git.
Pierwszym krokiem w naszym przykładzie było stworzenie klastra AWS EKS i magazynu obrazów Amazon ECR przy użyciu Terraform. Następnie zainstalowaliśmy FluxCD i skonfigurowaliśmy go do synchronizacji z naszym repozytorium kodu, co pozwoliło na automatyczne wdrożenie aplikacji.
Przygotowaliśmy aplikację webową, zbudowaliśmy jej obraz kontenera, a dzięki zintegrowanym GitHub Actions proces budowania obrazu i przesyłania go do Amazon ECR był całkowicie zautomatyzowany. W momencie, gdy nowy obraz pojawiał się w ECR wówczas FluxCD monitorował te zmiany i synchronizował odpowiednie definicje w Kubernetes, umożliwiając automatyczne wdrożenie aplikacji.
Dodatkowo, aby zapewnić automatyczne śledzenie wersji kontenera w Amazon ECR zastosowaliśmy komponenty takie jak image-reflector-controller
i image-automation-controller
, które automatycznie aktualizują definicje deploymentu w przypadku wykrycia nowej wersji obrazu.
Podsumowując należy zaznaczyć, że GitOps to podejście, które może znacznie uprościć procesy CI/CD automatyzując wdrożenia oraz synchronizację infrastruktury z repozytorium kodu. Warto jednak pamiętać, że kluczem do sukcesu w tym podejściu jest przestrzeganie dobrych praktyk i odpowiednia organizacja repozytoriów w zespole.