
CD zostało uznane za praktykę korporacyjnego oprogramowania, będąc wynikiem naturalnej ewolucji ustalonych zasad CI. Niemniej jednak CD wciąż jest dość rzadkim zjawiskiem, być może z powodu trudności w zarządzaniu oraz strachu przed nieudanymi wdrożeniami, które wpływają na dostępność systemu.
jest operatorem Kubernetes o otwartym kodzie źródłowym, którego celem jest eliminacja skomplikowanych interakcji. Automatyzuje on promowanie wdrożeń canary, wykorzystując rozkład ruchu Istio oraz metryki Prometheus do analizy zachowania aplikacji podczas kontrolowanego wdrażania.
Poniżej znajduje się krok po kroku przewodnik po konfiguracji i używaniu Flagger w Google Kubernetes Engine (GKE).
Konfiguracja klastra Kubernetes
Zaczynasz od utworzenia klastra GKE z rozszerzeniem Istio (jeśli nie masz konta GCP, możesz się zarejestrować aby otrzymać darmowe kredyty).
Zaloguj się do Google Cloud, utwórz projekt i włącz dla niego fakturowanie. Zainstaluj narzędzie wiersza poleceń i skonfiguruj swój projekt używając gcloud init.
Ustaw projekt domyślny, region obliczeń i strefę (zastąp PROJECT_ID swoim projektem):
gcloud config set project PROJECT_ID
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-aWłącz usługę GKE i utwórz klaster z HPA i rozszerzeniami Istio:
gcloud services enable container.googleapis.com
K8S_VERSION=$(gcloud beta container get-server-config --format=json | jq -r '.validMasterVersions[0]')
gcloud beta container clusters create istio
--cluster-version=${K8S_VERSION}
--zone=us-central1-a
--num-nodes=2
--machine-type=n1-standard-2
--disk-size=30
--enable-autorepair
--no-enable-cloud-logging
--no-enable-cloud-monitoring
--addons=HorizontalPodAutoscaling,Istio
--istio-config=auth=MTLS_PERMISSIVEPodana powyżej komenda stworzy domyślny pul nadziwia, który zawiera dwie VM n1-standard-2 (vCPU: 2, RAM 7,5 GB, dysk: 30 GB). Idealnie byłoby izolować komponenty Istio od swoich obciążeń roboczych, jednak nie ma prostego sposobu na uruchomienie podów Istio w dedykowanym pul nadziwia. Manifesty Istio są traktowane jako dostępne tylko do odczytu, a GKE będzie anulować wszelkie zmiany, jak np. przywiązywanie do węzła czy odpinanie od podu.
Skonfiguruj dane uwierzytelniające dla kubectl:
gcloud container clusters get-credentials istioUtwórz powiązanie roli administratora klastra:
kubectl create clusterrolebinding "cluster-admin-$(whoami)"
--clusterrole=cluster-admin
--user="$(gcloud config get-value core/account)"Zainstaluj narzędzie wiersza poleceń :
brew install kubernetes-helmHomebrew 2.0 jest teraz również dostępny dla .
Utwórz konto usługi i powiązanie roli klastra dla Tiller:
kubectl -n kube-system create sa tiller &&
kubectl create clusterrolebinding tiller-cluster-rule
--clusterrole=cluster-admin
--serviceaccount=kube-system:tillerWdróż Tiller w namespace kube-system:
helm init --service-account tillerPowinieneś rozważyć użycie SSL między Helm a Tiller. Aby uzyskać więcej informacji na temat zabezpieczenia instalacji Helm, zobacz
Potwierdź ustawienia:
kubectl -n istio-system get svcPo kilku sekundach GCP powinien przypisać zewnętrzny adres IP do usługi istio-ingressgateway.
Konfiguracja bramy wejściowej Istio
Utwórz statyczny adres IP o nazwie istio-gateway, używając adresu IP bramy Istio:
export GATEWAY_IP=$(kubectl -n istio-system get svc/istio-ingressgateway -ojson | jq -r .status.loadBalancer.ingress[0].ip)
gcloud compute addresses create istio-gateway --addresses ${GATEWAY_IP} --region us-central1Teraz potrzebujesz domeny internetowej i dostępu do swojego rejestratora DNS. Dodaj dwie wpisy A (zastąp example.com swoją domeną):
istio.example.com A ${GATEWAY_IP}
*.istio.example.com A ${GATEWAY_IP}Upewnij się, że wildcard DNS działa:
watch host test.istio.example.comUtwórz ogólną bramę Istio, aby udostępniać usługi poza siecią usługową przez HTTP:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: public-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"Zachowaj powyższy zasób jako public-gateway.yaml, a następnie zastosuj go:
kubectl apply -f ./public-gateway.yamlŻaden system produkcyjny nie powinien udostępniać usług w Internecie bez SSL. Aby zabezpieczyć bramę wejściową Istio za pomocą cert-managera, CloudDNS i Let’s Encrypt, przeczytaj proszę Flagger GKE.
Instalacja Flagger
Nakładka GKE Istio nie obejmuje instancji Prometheus, która zajmuje się zbieraniem telemetrii Istio. Ponieważ Flagger wykorzystuje metryki HTTP Istio do przeprowadzania analizy canary, musisz wdrożyć następującą konfigurację Prometheus, podobną do tej, która jest dostarczana z oficjalnym schematem Istio Helm.
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yamlDodaj repozytorium Flagger Helm:
helm repo add flagger [https://flagger.app](https://flagger.app/)Wdróż Flagger w namespace istio-system, włączając powiadomienia Slack:
helm upgrade -i flagger flagger/flagger
--namespace=istio-system
--set metricsServer=http://prometheus.istio-system:9090
--set slack.url=https://hooks.slack.com/services/YOUR-WEBHOOK-ID
--set slack.channel=general
--set slack.user=flaggerMożesz zainstalować Flagger w dowolnym namespace, o ile może wchodzić w interakcję z usługą Istio Prometheus przez port 9090.
Flagger ma pulpit nawigacyjny Grafana do analizy canary. Zainstaluj Grafana w namespace istio-system:
helm upgrade -i flagger-grafana flagger/grafana
--namespace=istio-system
--set url=http://prometheus.istio-system:9090
--set user=admin
--set password=change-meOtwórz Grafanę przez publiczny bramkę, tworząc usługi wirtualne (zastąp example.com twoją domeną):
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: grafana
namespace: istio-system
spec:
hosts:
- "grafana.istio.example.com"
gateways:
- public-gateway.istio-system.svc.cluster.local
http:
- route:
- destination:
host: flagger-grafanaZapisz powyższy zasób jako grafana-virtual-service.yaml, a następnie go zastosuj:
kubectl apply -f ./grafana-virtual-service.yamlPrzechodząc do http://grafana.istio.example.com w przeglądarce powinieneś zostać przekierowany na stronę logowania do Grafany.
Rozpocznij wdrażanie aplikacji webowych z Flagger
Flagger wdraża Kubernetes i, w razie potrzeby, automatyczne skalowanie poziome (HPA), a następnie tworzy szereg obiektów (wdrożenia Kubernetes, usługi ClusterIP i wirtualne usługi Istio). Te obiekty odsłaniają aplikację w service mesh i zarządzają analizą i promowaniem canary.
Utwórz testową przestrzeń nazw z włączonym wprowadzeniem Istio Sidecar:
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/namespaces/test.yamlUtwórz wdrożenie i narzędzie automatyzujące poziome skalowanie podów:
kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml
kubectl apply -f ${REPO}/artifacts/canaries/hpa.yamlRozpocznij usługę testową do generowania ruchu podczas analizy canary:
helm upgrade -i flagger-loadtester flagger/loadtester
--namespace=testUtwórz zasób canary dla użytkownika (zastąp example.com swoją domeną):
apiVersion: flagger.app/v1alpha3
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
progressDeadlineSeconds: 60
autoscalerRef:
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
name: podinfo
service:
port: 9898
gateways:
- public-gateway.istio-system.svc.cluster.local
hosts:
- app.istio.example.com
canaryAnalysis:
interval: 30s
threshold: 10
maxWeight: 50
stepWeight: 5
metrics:
- name: istio_requests_total
threshold: 99
interval: 30s
- name: istio_request_duration_seconds_bucket
threshold: 500
interval: 30s
webhooks:
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
cmd: "hey -z 1m -q 10 -c 2 http://podinfo.test:9898/"Zapisz powyższy zasób jako podinfo-canary.yaml, a następnie go zastosuj:
kubectl apply -f ./podinfo-canary.yamlPowyższa analiza, w przypadku sukcesu, będzie trwała przez pięć minut z kontrolą metryk HTTP co pół minuty. Możesz określić minimalny czas potrzebny do sprawdzenia i promowania wdrożenia canary, stosując następujący wzór: interval * (maxWeight / stepWeight). Pola CRD canary są dokumentowane .
Po kilku sekundach Flagger utworzy obiekty canary:
# applied
deployment.apps/podinfo
horizontalpodautoscaler.autoscaling/podinfo
canary.flagger.app/podinfo
# generated
deployment.apps/podinfo-primary
horizontalpodautoscaler.autoscaling/podinfo-primary
service/podinfo
service/podinfo-canary
service/podinfo-primary
virtualservice.networking.istio.io/podinfoOtwórz przeglądarkę i przejdź do app.istio.example.com, powinieneś zobaczyć numer wersji .
Automatyczna analiza canary i wdrażanie
Flagger realizuje cykl zarządzania, który stopniowo przenosi ruch na canary, jednocześnie mierząc kluczowe wskaźniki wydajności, takie jak wskaźnik udanych żądań HTTP, średni czas trwania żądań i dostępność poda. Na podstawie analizy KPI canary jest promowany lub przerwany, a wyniki analizy publikowane są w Slack.
Wdrażanie canary zaczyna się po zmianie jednego z poniższych obiektów:
- Wdrażanie PodSpec (obraz kontenera, polecenie, porty, env itd.)
- ConfigMaps montowane jako wolumeny lub przekształcane w zmienne środowiskowe
- Sekrety montowane jako wolumeny lub przekształcane w zmienne środowiskowe
Rozpoczęcie wdrażania canary po aktualizacji obrazu kontenera:
kubectl -n test set image deployment/podinfo
podinfod=quay.io/stefanprodan/podinfo:1.4.1Flagger wykrywa, że wersja wdrożenia się zmieniła i zaczyna ją analizować:
kubectl -n test describe canary/podinfo
Zdarzenia:
Nowa wersja wykryta podinfo.test
Skalowanie w górę podinfo.test
Czekam na zakończenie wdrażania podinfo.test: 0 z 1 zaktualizowanych replik dostępnych
Rozwój wagi canary podinfo.test 5
Rozwój wagi canary podinfo.test 10
Rozwój wagi canary podinfo.test 15
Rozwój wagi canary podinfo.test 20
Rozwój wagi canary podinfo.test 25
Rozwój wagi canary podinfo.test 30
Rozwój wagi canary podinfo.test 35
Rozwój wagi canary podinfo.test 40
Rozwój wagi canary podinfo.test 45
Rozwój wagi canary podinfo.test 50
Kopiowanie specyfikacji szablonu podinfo.test do podinfo-primary.test
Czekam na zakończenie wdrażania podinfo-primary.test: 1 z 2 zaktualizowanych replik dostępnych
Promocja zakończona! Skalowanie w dół podinfo.testPodczas analizy wyniki canary można śledzić za pomocą Grafana:
Uwaga: jeśli nowe zmiany zostaną zastosowane do wdrożenia podczas analizy canary, Flagger zrestartuje fazę analizy.
Sporządź listę wszystkich "canary" w swoim klastrze:
watch kubectl get canaries --all-namespaces
NAMESPACE NAME STATUS WEIGHT LASTTRANSITIONTIME
test podinfo Progressing 15 2019-01-16T14:05:07Z
prod frontend Succeeded 0 2019-01-15T16:15:07Z
prod backend Failed 0 2019-01-14T17:05:07ZJeśli włączyłeś powiadomienia Slack, otrzymasz następujące wiadomości:
Automatyczny rollback
Podczas analizy canary można generować syntetyczne błędy HTTP 500 i wysoką latencję, aby sprawdzić, czy Flagger nie zatrzyma wdrożenia.
Utwórz testowy pod i wykonaj w nim następujące działanie:
kubectl -n test run tester
--image=quay.io/stefanprodan/podinfo:1.2.1
-- ./podinfo --port=9898
kubectl -n test exec -it tester-xx-xx shGenerowanie błędów HTTP 500:
watch curl http://podinfo-canary:9898/status/500Generowanie latencji:
obserwuj curl http://podinfo-canary:9898/delay/1Gdy liczba nieudanych kontroli osiągnie próg, ruch jest kierowany z powrotem do głównego kanału, canary jest skalowane do zera, a wdrożenie oznaczane jest jako nieudane.
Błędy canary i szczyty opóźnień są rejestrowane jako zdarzenia Kubernetes i zapisywane przez Flagger w formacie JSON:
kubectl -n istio-system logs deployment/flagger -f | jq .msg
Rozpoczęcie wdrożenia canary dla podinfo.test
Zwiększanie wagi canary podinfo.test do 5
Zwiększanie wagi canary podinfo.test do 10
Zwiększanie wagi canary podinfo.test do 15
Zatrzymanie postępu podinfo.test wskaźnik sukcesu 69,17% < 99%
Zatrzymanie postępu podinfo.test wskaźnik sukcesu 61,39% < 99%
Zatrzymanie postępu podinfo.test wskaźnik sukcesu 55,06% < 99%
Zatrzymanie postępu podinfo.test wskaźnik sukcesu 47,00% < 99%
Zatrzymanie postępu podinfo.test wskaźnik sukcesu 37,00% 500ms
Zatrzymanie postępu podinfo.test czas realizacji żądania 1,600s > 500ms
Zatrzymanie postępu podinfo.test czas realizacji żądania 1,915s > 500ms
Zatrzymanie postępu podinfo.test czas realizacji żądania 2,050s > 500ms
Zatrzymanie postępu podinfo.test czas realizacji żądania 2,515s > 500ms
Wycofanie podinfo.test osiągnięto próg nieudanych kontroli 10
Canary nie powiodło się! Zmniejszenie skali podinfo.testJeśli włączyłeś powiadomienia Slack, otrzymasz wiadomość, gdy zostanie przekroczony limit czasu lub osiągnięta maksymalna liczba nieudanych kontroli podczas analizy:
Na zakończenie
Uruchomienie service mesh, takiego jak Istio, oprócz Kubernetes, zapewni automatyczne metryki, logi i protokoły, ale wdrożenie obciążeń roboczych nadal zależy od zewnętrznych narzędzi. Flagger dąży do zmiany tej sytuacji, dodając możliwości Istio .
Flagger jest kompatybilny z dowolnymi rozwiązaniami CI/CD dla Kubernetes, a analizę canary można łatwo rozszerzyć za pomocą do wykonywania testów integracyjnych/akceptacyjnych, testów obciążeniowych lub innych niestandardowych kontroli. Ponieważ Flagger jest deklaratywny i reaguje na zdarzenia Kubernetes, można go używać w potokach GitOps razem z lub . Jeśli używasz JenkinsX, możesz zainstalować Flagger jako rozszerzenia jx.
Flagger jest wspierany przez i zapewnia wdrożenia canary w . Projekt jest testowany na GKE, EKS i „gołym metalu” z kubeadm.
Jeśli masz propozycje dotyczące ulepszenia Flaggera, prosimy o przesłanie pytania lub PR na GitHubie pod adresem . Wkłady są mile widziane!
Dziękuję .
Źródło: habr.com
