Dziś opowiemy o zasadach i modelach GitOps oraz jak te modele są realizowane na platformie OpenShift. Interaktywne przewodniki na ten temat są dostępne. .

Mówiąc krótko, GitOps to zestaw praktycznych metod korzystania z pull-requestów Git do zarządzania konfiguracjami infrastruktury i aplikacji. Repozytorium Git w ramach GitOps jest traktowane jako jedyne źródło informacji o stanie systemu, a wszelkie zmiany tego stanu są w pełni śledzone i podlegają audytowi.
Pomysł śledzenia zmian w GitOps nie jest nowy; podejście to od dawna i praktycznie wszędzie stosowane jest przy pracy z kodem źródłowym aplikacji. GitOps realizuje podobne funkcje (przeglądy, pull-requesty, tagi itd.) podczas zarządzania konfiguracjami infrastruktury i aplikacji oraz oferuje analogiczne korzyści, jak w przypadku zarządzania kodem źródłowym.
Dla GitOps nie ma żadnej akademickiej definicji ani zatwierdzonego zbioru zasad, istnieje tylko zbiór zasad, na których opiera się ta praktyka:
- Deklaratywne opisy systemu są przechowywane w repozytorium Git (konfiguracje, monitorowanie itd.).
- Zmiany stanu są realizowane poprzez pull-requesty.
- Stan działających systemów jest dopasowywany do danych w repozytorium za pomocą push-requestów Git.
Zasady GitOps
- Definicje systemów są opisywane jako kod źródłowy.
Konfiguracja systemów jest traktowana jako kod, dlatego można ją przechowywać i automatycznie wersjonować w repozytorium Git, które stanowi jedyne źródło prawdy. Takie podejście umożliwia łatwe wdrażanie (rollout) i cofanie (rollback) zmian w systemach.
- Pożądany stan i konfiguracja systemów są określane i wersjonowane w Git.
Przechowując i wersjonując w Git pożądany stan systemów, uzyskuje się możliwość łatwego wdrażania i cofania zmian w systemach oraz aplikacjach. Możemy także korzystać z mechanizmów bezpieczeństwa Git do kontroli własności kodu i potwierdzania jego autentyczności.
- Zmiany w konfiguracjach mogą być automatycznie stosowane za pomocą pull-requestów.
Korzystając z pull requestów Git, możemy łatwo zarządzać tym, jak zmiany są stosowane do konfiguracji w repozytorium. Na przykład, mogą być one przekazywane do przeglądu innym członkom zespołu lub poddawane testom CI.
I w tym samym czasie nie musimy rozdawać uprawnień administratora na prawo i lewo. Aby wykonać commit zmian w konfiguracji, użytkownicy muszą mieć odpowiednie uprawnienia w repozytorium Git, gdzie przechowywane są te konfiguracje.
- Rozwiązywanie problemu niekontrolowanego dryfu konfiguracji
Kiedy pożądany stan systemu jest przechowywany w repozytorium Git, pozostaje nam tylko znaleźć oprogramowanie, które kontroluje, czy aktualny stan systemu odpowiada jego pożądanemu stanowi. Jeśli tak nie jest, to to oprogramowanie powinno – w zależności od ustawień – albo samodzielnie usunąć niespójność, albo powiadomić nas o dryfie konfiguracji.
Modele GitOps dla OpenShift
Reconciler zasobów w klastrze
Zgodnie z tym modelem w klastrze istnieje kontroler, który odpowiada za porównywanie zasobów Kubernetes (plików YAML) w repozytorium Git z rzeczywistymi zasobami klastra. Przy wykryciu rozbieżności kontroler wysyła powiadomienia i może podjąć działania mające na celu usunięcie niespójności. Ten model GitOps jest wykorzystywany w Anthos Config Management i Weaveworks Flux.

Reconciler zasobów zewnętrznych (Push)
Ten model można traktować jako rodzaj poprzedniego, gdy mamy jeden lub więcej kontrolerów odpowiedzialnych za synchronizację zasobów w parach „repozytorium Git – klaster Kubernetes”. Różnicą jest to, że w każdym zarządzanym klastrze nie musi być oddzielnego kontrolera. Pary „Git – klaster k8s” często są definiowane jako opisy CRD (custom resources definition), w których można opisać, jak kontroler ma przeprowadzać synchronizację. W ramach tego modelu kontrolery porównują repozytorium Git określone w CRD z zasobami klastra Kubernetes, które również są określone w CRD, i wykonują odpowiednie działania na podstawie wyników porównania. W szczególności taki model GitOps jest wykorzystywany w ArgoCD.

GitOps na platformie OpenShift
Zarządzanie wieloma klastrami infrastruktury Kubernetes
Wraz z upowszechnieniem się Kubernetes i wzrostem popularności strategii wielochmurowych oraz obliczeń brzegowych (edge computing) rośnie także średnia liczba klastrów OpenShift przypadająca na jednego klienta.
Na przykład, przy użyciu obliczeń brzegowych, klastry jednego klienta mogą być wdrażane w setkach, a nawet tysiącach. W związku z tym zmuszony jest zarządzać kilkoma niezależnymi lub powiązanymi klastrami OpenShift w chmurze publicznej oraz on-premise.
W tym przypadku należy rozwiązać wiele problemów, w szczególności:
- Kontrolowanie, czy klastry są w identycznym stanie (konfiguracje, monitorowanie, magazyny itd.).
- Ponownie tworzenie (lub przywracanie) klastrów do znanego stanu.
- Tworzenie nowych klastrów na podstawie znanego stanu.
- Wdrażanie zmian na kilku klastrach OpenShift.
- Cofanie zmian na kilku klastrach OpenShift.
- Powiązywanie ztemplatyzowanych konfiguracji z różnymi środowiskami.
Konfiguracje aplikacji
W trakcie swojego cyklu życia aplikacje często przechodzą przez łańcuch klastrów (dev, stage itd.), zanim trafią do klastra produkcyjnego. Ponadto, z powodu wymagań dotyczących dostępności i skalowalności, klienci często wdrażają aplikacje jednocześnie na kilku klastrach on-premise lub w kilku regionach publicznej platformy chmurowej.
W związku z tym należy rozwiązać następujące zadania:
- Zapewnienie ruchu aplikacji (binarki, konfiguracje itd.) między klastrami (dev, stage itd.).
- Wdrażanie zmian w aplikacjach (binarki, konfiguracje itd.) na kilku klastrach OpenShift.
- Cofanie zmian w aplikacjach do poziomu poprzedniego znanego stanu.
Scenariusze zastosowania OpenShift GitOps
1. Wdrażanie zmian z repozytorium Git
Administrator klastra może przechowywać konfiguracje klastra OpenShift w repozytorium Git i automatycznie je stosować, aby bez większych trudności tworzyć nowe klastry i przekształcać je w stan identyczny z znanym stanem, który jest przechowywany w repozytorium Git.
2. Synchronizacja z Secret Manager
Administratorowi przyda się również możliwość synchronizowania obiektów secret OpenShift z odpowiednim oprogramowaniem, takim jak Vault, aby zarządzać nimi za pomocą specjalnie stworzonych do tego narzędzi.
3. Kontrola dryfu konfiguracji
Administrator będzie tylko zadowolony, jeśli OpenShift GitOps samodzielnie wykryje i zwróci uwagę na rozbieżności między rzeczywistymi konfiguracjami a tymi, które zostały określone w repozytorium, aby można było szybko reagować na dryf.
4. Powiadomienia o dryftach konfiguracji
Przydadzą się, gdy administrator chce na bieżąco dowiadywać się o przypadkach dryftu konfiguracji, aby szybko podejmować odpowiednie działania samodzielnie.
5. Ręczna synchronizacja konfiguracji w przypadku dryftu
Pozwala administratorowi synchronizować klaster OpenShift z repozytorium Git w przypadku dryftu konfiguracji, aby szybko przywrócić klaster do poprzedniego znanego stanu.
6. Automatyczna synchronizacja konfiguracji w przypadku dryftu
Administrator może również skonfigurować klaster OpenShift do automatycznej synchronizacji z repozytorium w przypadku wykrycia dryftu, aby konfiguracja klastra zawsze odpowiadała konfiguracjom w Gicie.
7. Wiele klastrów - jedno repozytorium
Administrator może przechowywać w jednym repozytorium Git konfiguracje kilku różnych klastrów OpenShift i wybiórczo je stosować w razie potrzeby.
8. Hierarchia konfiguracji klastrów (dziedziczenie)
Administrator może ustawić hierarchię konfiguracji klastrów w repozytorium (stage, prod, portfolio aplikacji itp. z dziedziczeniem). Innymi słowy, może określić, jak mają być stosowane konfiguracje - do jednego lub kilku klastrów.
Na przykład, jeśli administrator ustawi w repozytorium Git hierarchię 'Klastry produkcyjne (prod) → Klastry systemu X → Klastry produkcyjne systemu X', to do klastrów produkcyjnych systemu X stosowane będzie połączenie następujących konfiguracji:
- Konfiguracje wspólne dla wszystkich klastrów produkcyjnych.
- Konfiguracje dla klastra systemu X.
- Konfiguracje dla produkcyjnego klastra systemu X.
9. Szablony i nadpisywanie konfiguracji
Administrator może nadpisać zestaw odziedziczonych konfiguracji i ich wartości, aby lepiej dostosować konfigurację do konkretnego klastra, do którego będą stosowane.
10. Selektywne include'y i exclude'y dla konfiguracji, konfiguracje aplikacji
Administrator może ustawić warunki zastosowania lub braku zastosowania pewnych konfiguracji do klastrów o określonych cechach.
11. Wsparcie dla szablonów
Programiści mogą skorzystać z możliwości wyboru, jak będą definiowane zasoby aplikacji (Helm Chart, czysty yaml Kubernetes itp.), aby używać najbardziej odpowiedniego formatu dla każdej konkretnej aplikacji.
Narzędzia GitOps na platformie OpenShift
ArgoCD
ArgoCD wdraża model External Resource Reconcile i oferuje zcentralizowany interfejs do orkiestracji relacji między klastrami a repozytoriami Git w modelu 'jeden do wielu'. Wadami tego programu są brak możliwości zarządzania aplikacjami w przypadku awarii ArgoCD.
Flux
Flux wdraża model On-Cluster Resource Reconcile, a w związku z tym nie ma zcentralizowanego zarządzania repozytorium definicji, co stanowi jego słabość. Z drugiej strony, ze względu na brak centralizacji, możliwość zarządzania aplikacjami pozostaje nawet w przypadku awarii jednego klastra.
Instalacja ArgoCD na OpenShift
ArgoCD oferuje doskonały interfejs wiersza poleceń i konsolę internetową, dlatego tutaj nie będziemy omawiać Fluxa i innych alternatyw.
Aby wdrożyć ArgoCD na platformie OpenShift 4, wykonaj następujące kroki jako administrator klastra:
Wdrażanie komponentów ArgoCD na platformie OpenShift
# Create a new namespace for ArgoCD components
oc create namespace argocd
# Apply the ArgoCD Install Manifest
oc -n argocd apply -f https://raw.githubusercontent.com/argoproj/argo-cd/v1.2.2/manifests/install.yaml
# Get the ArgoCD Server password
ARGOCD_SERVER_PASSWORD=$(oc -n argocd get pod -l "app.kubernetes.io/name=argocd-server" -o jsonpath='{.items[*].metadata.name}')Dostosowanie serwera ArgoCD, aby był widoczny dla OpenShift Route
# Patch ArgoCD Server so no TLS is configured on the server (--insecure)
PATCH='{"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"argocd-server"}],"containers":[{"command":["argocd-server","--insecure","--staticassets","/shared/app"],"name":"argocd-server"}]}}}}'
oc -n argocd patch deployment argocd-server -p $PATCH
# Expose the ArgoCD Server using an Edge OpenShift Route so TLS is used for incoming connections
oc -n argocd create route edge argocd-server --service=argocd-server --port=http --insecure-policy=RedirectWdrażanie narzędzia CLI ArgoCD
# Download the argocd binary, place it under /usr/local/bin and give it execution permissions
curl -L https://github.com/argoproj/argo-cd/releases/download/v1.2.2/argocd-linux-amd64 -o /usr/local/bin/argocd
chmod +x /usr/local/bin/argocdZmiana hasła administratora serwera ArgoCD
# Get ArgoCD Server Route Hostname
ARGOCD_ROUTE=$(oc -n argocd get route argocd-server -o jsonpath='{.spec.host}')
# Login with the current admin password
argocd --insecure --grpc-web login ${ARGOCD_ROUTE}:443 --username admin --password ${ARGOCD_SERVER_PASSWORD}
# Update admin's password
argocd --insecure --grpc-web --server ${ARGOCD_ROUTE}:443 account update-password --current-password ${ARGOCD_SERVER_PASSWORD} --new-password Po wykonaniu tych kroków można pracować z serwerem ArgoCD za pośrednictwem konsoli internetowej ArgoCD WebUI lub narzędzia wiersza poleceń ArgoCD CLI.
GitOps – nigdy nie jest za późno
„Pociąg odjechał” – tak mówi się o sytuacji, gdy szansa na coś została stracona. W przypadku OpenShift chęć jak najszybszego rozpoczęcia korzystania z tej nowej platformy często tworzy taką sytuację w zarządzaniu i konserwacji tras, wdrożeń i innych obiektów OpenShift. Ale czy szansa na pewno została ostatecznie stracona?
Kontynuując cykl artykułów o , dzisiaj pokażemy, jak przekształcić ręcznie utworzoną aplikację i jej zasoby w proces, w którym wszystko zarządza narzędzie GitOps. W tym celu najpierw ręcznie wdrożymy aplikację httpd. Na zrzucie ekranu poniżej widać, jak tworzymy przestrzeń nazw, wdrożenie i usługę, a następnie wystawiamy tę usługę, aby utworzyć trasę.
oc create -f https://raw.githubusercontent.com/openshift/federation-dev/master/labs/lab-4-assets/namespace.yaml
oc create -f https://raw.githubusercontent.com/openshift/federation-dev/master/labs/lab-4-assets/deployment.yaml
oc create -f https://raw.githubusercontent.com/openshift/federation-dev/master/labs/lab-4-assets/service.yaml
oc expose svc/httpd -n simple-appTeraz mamy utworzoną ręcznie aplikację. Teraz trzeba ją przenieść pod zarządzanie GitOps bez utraty dostępności. Krótko mówiąc, robi się to w ten sposób:
- Tworzymy repozytorium Git dla kodu.
- Eksportujemy nasze aktualne obiekty i ładujemy je do repozytorium Git.
- Wybieramy i wdrażamy narzędzia GitOps.
- Dodajemy nasze repozytorium do tego narzędzia.
- Definiujemy aplikację w naszym narzędziu GitOps.
- Przeprowadzamy testowe uruchomienie aplikacji, korzystając z narzędzia GitOps.
- Synchronizujemy obiekty przy użyciu narzędzia GitOps.
- Włączamy oczyszczanie (pruning) i autosynchronizację obiektów.
Jak już wspomniano wcześniej, w GitOps istnieje jedno jedyne źródło informacji o wszystkich obiektach w klastrze(-ach) Kubernetes – repozytorium Git. Zakładamy, że w Twojej organizacji już używany jest repozytorium Git. Może być publiczne lub prywatne, ale musi być dostępne dla klastrów Kubernetes. Może to być to samo repozytorium, co dla kodu aplikacji, lub osobne repozytorium utworzone specjalnie dla wdrożeń. W repozytorium zaleca się mieć ścisłe uprawnienia, ponieważ będą tam przechowywane obiekty secret, trasy i inne rzeczy wrażliwe na bezpieczeństwo.
W naszym przykładzie stworzymy nowe publiczne repozytorium na GitHubie. Możesz je nazwać dowolnie, my użyjemy nazwy blogpost.
Jeśli pliki YAML obiektów nie były przechowywane lokalnie lub w Gicie, będziesz musiał skorzystać z binariów oc lub kubectl. Na poniższym zrzucie ekranu żądamy YAML dla naszej przestrzeni nazw, wdrożenia, usługi i trasy. Wcześniej sklonowaliśmy właśnie utworzone repozytorium i przeszliśmy do niego poleceniem cd.
oc get namespace simple-app -o yaml --export > namespace.yaml
oc get deployment httpd -o yaml -n simple-app --export > deployment.yaml
oc get service httpd -o yaml -n simple-app --export > service.yaml
oc get route httpd -o yaml -n simple-app --export > route.yamlTeraz poprawimy plik deployment.yaml, aby usunąć pole, którego Argo CD nie może zsynchronizować.
sed -i '/sgeneration: .*\/d' deployment.yamlPonadto należy zmienić trasę. Najpierw zdefiniujemy wieloliniową zmienną, a następnie zastąpimy ingress: null zawartością tej zmiennej.
export ROUTE=" ingress:
- conditions:
- status: 'True'
type: Admitted"
sed -i "s/ ingress: null/$ROUTE/g" route.yamlTeraz uporządkowaliśmy pliki, musimy je zapisać w repozytorium Git. Po tym repozytorium staje się jedynym źródłem informacji, a wszelkie ręczne zmiany obiektów powinny być surowo zabronione.
git commit -am 'initial commit of objects'
git push origin masterZakładamy, że ArgoCD jest już wdrożony (jak to zrobić – zobacz poprzedni ). Dlatego dodamy do Argo CD utworzone przez nas repozytorium, zawierające kod aplikacji z naszego przykładu. Upewnij się, że wskazujesz dokładnie to repozytorium, które stworzyłeś wcześniej.
argocd repo add https://github.com/cooktheryan/blogpostTeraz tworzymy aplikację. Aplikacja definiuje wartości, aby narzędzie GitOps wiedziało, które repozytorium i ścieżki używać, jaki OpenShift jest potrzebny do zarządzania obiektami, a także która konkretna gałąź repozytorium jest wymagana oraz czy zasoby powinny być automatycznie synchronizowane.
argocd app create --project default
--name simple-app --repo https://github.com/cooktheryan/blogpost.git
--path . --dest-server https://kubernetes.default.svc
--dest-namespace simple-app --revision master --sync-policy none Po skonfigurowaniu aplikacji w Argo CD, to narzędzie zaczyna sprawdzać już wdrożone obiekty pod kątem zgodności z definicjami w repozytorium. W naszym przykładzie automatyczna synchronizacja i czyszczenie są wyłączone, więc elementy nie zmieniają się na razie. Zauważ, że w interfejsie Argo CD nasza aplikacja będzie miała status „Out of Sync” (Nie zsynchronizowane), ponieważ brakuje etykiety, którą ustawia ArgoCD.
Właśnie dlatego, gdy nieco później uruchomimy synchronizację, ponowne wdrożenie obiektów nie zostanie wykonane.
Teraz przeprowadzimy próbne uruchomienie, aby upewnić się, że w naszych plikach nie ma błędów.
argocd app sync simple-app --dry-runJeśli nie ma błędów, możemy przejść do synchronizacji.
argocd app sync simple-appPo wykonaniu polecenia argocd get na naszej aplikacji, powinniśmy zobaczyć, że status aplikacji zmienił się na Healthy (Zdrowa) lub Synced (Zsynchronizowana). Oznaczać to będzie, że wszystkie zasoby w repozytorium Git są teraz zgodne z tymi, które zostały już wdrożone.
argocd app get simple-app
Name: simple-app
Project: default
Server: https://kubernetes.default.svc
Namespace: simple-app
URL: https://argocd-server-route-argocd.apps.example.com/applications/simple-app
Repo: https://github.com/cooktheryan/blogpost.git
Target: master
Path: .
Sync Policy:
Sync Status: Synced to master (60e1678)
Health Status: Healthy
... A teraz można już włączyć automatyczną synchronizację i czyszczenie, aby zapewnić, że nic nie będzie tworzone ręcznie oraz że za każdym razem, gdy obiekt zostanie utworzony lub zaktualizowany w repozytorium, będzie wykonywane wdrożenie.
argocd app set simple-app --sync-policy automated --auto-prune Zatem z powodzeniem przekształciliśmy aplikację pod zarządzanie GitOps, która początkowo w ogóle nie korzystała z GitOps.
Źródło: habr.com
