Deploiuri canary automate cu Flagger și Istio

Deploiuri canary automate cu Flagger și Istio

CD a fost recunoscut ca o practică de software corporativ și reprezintă rezultatul evoluției naturale a principiilor CI. Cu toate acestea, CD rămâne o practică destul de rară, posibil din cauza dificultății în gestionarea sa și a fricii de deploiuri eșuate, care pot afecta disponibilitatea sistemului.

Flagger este un operator Kubernetes cu cod deschis, care își propune să elimine relațiile confuze. Acesta automatizează promovarea deploiurilor canary folosind înclinarea traficului Istio și metrici Prometheus pentru a analiza comportamentul aplicației în timpul desfășurării controlate.

Mai jos se află un ghid pas cu pas pentru configurarea și utilizarea Flagger în Google Kubernetes Engine (GKE).

Configurarea clusterului Kubernetes

Începeți prin a crea un cluster GKE cu extensia Istio (dacă nu aveți un cont GCP, vă puteți înregistra aici pentru a obține credite gratuite).

Conectați-vă la Google Cloud, creați un proiect și activați facturarea pentru acesta. Instalați utilitarul de linie de comandă gcloud și configurați proiectul cu ajutorul gcloud init.

Setați proiectul implicit, regiunea de calcul și zona (înlocuiți PROJECT_ID cu proiectul dumneavoastră):

gcloud config set project PROJECT_ID
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-a

Activați serviciul GKE și creați un cluster cu HPA și extensiile 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_PERMISSIVE

Comanda de mai sus va crea un grup de noduri implicit, care include două VM-uri n1-standard-2 (vCPU: 2, RAM 7,5 GB, disk: 30 GB). Ideal ar fi să izolați componentele Istio de sarcinile de lucru, dar nu există o modalitate simplă de a rula poduri Istio pe un grup dedicat de noduri. Manifestele Istio sunt considerate doar în citire, iar GKE va anula orice modificări, cum ar fi legarea de nod sau detașarea de pod.

Configurați acreditivele pentru kubectl:

gcloud container clusters get-credentials istio

Creați o legătură de rol pentru administratorul clusterului:

kubectl create clusterrolebinding "cluster-admin-$(whoami)" 
--clusterrole=cluster-admin 
--user="$(gcloud config get-value core/account)"

Instalați instrumentul de linie de comandă Helm:

brew install kubernetes-helm

Homebrew 2.0 este acum de asemenea disponibil pentru Linux.

Creează un cont de serviciu și leagă rolul de cluster pentru Tiller:

kubectl -n kube-system create sa tiller && 
kubectl create clusterrolebinding tiller-cluster-rule 
--clusterrole=cluster-admin 
--serviceaccount=kube-system:tiller

Dezvoltă Tiller în namespace kube-system:

helm init --service-account tiller

Ar trebui să luați în considerare utilizarea SSL între Helm și Tiller. Pentru informații suplimentare despre securizarea instalării Helm, consultați docs.helm.sh

Confirmă setările:

kubectl -n istio-system get svc

După câteva secunde, GCP ar trebui să aloce o adresă IP externă pentru serviciu istio-ingressgateway.

Configurarea gateway-ului de intrare Istio

Creează o adresă IP statică numită istio-gateway, folosind adresa IP a gateway-ului 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-central1

Acum ai nevoie de un domeniu internet și acces la registratorul tău DNS. Adaugă două înregistrări A (înlocuiește example.com cu domeniul tău):

istio.example.com   A ${GATEWAY_IP}
*.istio.example.com A ${GATEWAY_IP}

Asigură-te că wildcard-ul DNS funcționează:

watch host test.istio.example.com

Creează un gateway public Istio pentru a oferi servicii dincolo de service mesh prin 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:
        - "*"

Salvează resursa de mai sus ca public-gateway.yaml, apoi aplic-o:

kubectl apply -f ./public-gateway.yaml

Niciun sistem de producție nu ar trebui să ofere servicii pe internet fără SSL. Pentru a securiza gateway-ului de intrare Istio cu cert-manager, CloudDNS și Let's Encrypt, te rugăm să citești documentație Flagger GKE.

Instalarea Flagger

Extinderea GKE Istio nu include o instanță Prometheus, care se ocupă de curățarea serviciului de telemetrie Istio. Deoarece Flagger utilizează metrici Istio HTTP pentru a efectua analiza canary, trebuie să desfășori următoarea configurație Prometheus, similară cu cea furnizată cu schema oficială Istio Helm.

REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yaml

Adaugă repository-ul Flagger Helm:

helm repo add flagger [https://flagger.app](https://flagger.app/)

Dezvoltă Flagger în namespace istio-system, activând notificările 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=flagger

Poți instala Flagger în orice namespace, atâta timp cât acesta poate interacționa cu serviciul Istio Prometheus prin portul 9090.

Flagger dispune de un panou de monitorizare Grafana pentru analiza canary. Instalați Grafana în spațiul de nume 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-me

Deschideți Grafana printr-un gateway deschis, creând un serviciu virtual (înlocuiți example.com cu domeniul dumneavoastră):

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-grafana

Salvați resursa de mai sus ca grafana-virtual-service.yaml, apoi aplicați-o:

kubectl apply -f ./grafana-virtual-service.yaml

Când accesați http://grafana.istio.example.com în browser, ar trebui să fiți redirecționat către pagina de logare Grafana.

Dezvoltarea aplicațiilor web cu Flagger

Flagger implementează Kubernetes și, dacă este necesar, scalarea automată orizontală (HPA), apoi creează o serie de obiecte (implementări Kubernetes, servicii ClusterIP și servicii virtuale Istio). Aceste obiecte expun aplicația în service mesh și gestionează analiza canary și promovarea.

Deploiuri canary automate cu Flagger și Istio

Creează un spațiu de nume de test cu implementarea Istio Sidecar activată:

REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/namespaces/test.yaml

Creează o implementare și un instrument de scalare automată orizontală a pod-urilor:

kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml
kubectl apply -f ${REPO}/artifacts/canaries/hpa.yaml

Desfășurați un serviciu de testare a sarcinii pentru a genera trafic în timpul analizei canary:

helm upgrade -i flagger-loadtester flagger/loadtester 
--namespace=test

Creează o resursă canary personalizată (înlocuiți example.com cu domeniul tău):

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/"

Salvați resursa de mai sus ca podinfo-canary.yaml, apoi aplicați-o:

kubectl apply -f ./podinfo-canary.yaml

Analiza de mai sus, în cazul în care reușește, va fi executată timp de cinci minute, verificând metricele HTTP la fiecare jumătate de minut. Puteți determina timpul minim necesar pentru verificarea și promovarea implementării canary folosind următoarea formulă: interval * (maxWeight / stepWeight). Câmpurile Canary CRD sunt documentate aici.

În câteva secunde, Flagger va crea obiecte 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/podinfo

Deschideți browserul și accesați app.istio.example.com, ar trebui să vedeți numărul versiunii aplicației demo.

Analiza și promovarea automată canary

Flagger implementează un ciclu de management care mută treptat traficul pe canary, măsurând în același timp indicatorii cheie de performanță, cum ar fi rata de succes a solicitărilor HTTP, timpul mediu de răspuns și disponibilitatea podului. Pe baza analizei KPI, canary este promovat sau oprit, iar rezultatele analizei sunt publicate în Slack.

Deploiuri canary automate cu Flagger și Istio

Deschiderea unui deployment canary se declanșează la modificarea unuia dintre următoarele obiecte:

  • Specificația PodSpec (imaginea containerului, comenzi, porturi, variabile de mediu etc.)
  • ConfigMaps sunt montate ca volume sau transformate în variabile de mediu
  • Secretele sunt montate ca volume sau transformate în variabile de mediu

Lansarea unui deployment canary la actualizarea imaginii containerului:

kubectl -n test set image deployment/podinfo 
podinfod=quay.io/stefanprodan/podinfo:1.4.1

Flagger detectează că versiunea deployment-ului a fost modificată și începe să o analizeze:

kubectl -n test describe canary/podinfo

Evenimente:

Nouă revizie detectată podinfo.test
Scalare podinfo.test
Așteptând finalizarea rollout-ului podinfo.test: 0 din 1 replici actualizate sunt disponibile
Avansare greutate canary podinfo.test 5
Avansare greutate canary podinfo.test 10
Avansare greutate canary podinfo.test 15
Avansare greutate canary podinfo.test 20
Avansare greutate canary podinfo.test 25
Avansare greutate canary podinfo.test 30
Avansare greutate canary podinfo.test 35
Avansare greutate canary podinfo.test 40
Avansare greutate canary podinfo.test 45
Avansare greutate canary podinfo.test 50
Copierea specificației șablonului podinfo.test în podinfo-primary.test
Așteptând finalizarea rollout-ului podinfo-primary.test: 1 din 2 replici actualizate sunt disponibile
Promoția completă! Scalarea în jos a podinfo.test

În timpul analizei, rezultatele canary pot fi monitorizate folosind Grafana:

Deploiuri canary automate cu Flagger și Istio

Vă rugăm să rețineți: dacă noi modificări sunt aplicate în legătură cu deploymentul în timpul analizei canary, Flagger va reporni faza de analiză.

Compuneți o listă a tuturor «canarelor» din clusterul dvs.:

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:07Z

Dacă ați activat notificările Slack, veți primi următoarele mesaje:

Deploiuri canary automate cu Flagger și Istio

Rollback automat

În timpul analizei canary, pot fi generate erori sintetice HTTP 500 și o întârziere mare a răspunsului pentru a verifica dacă Flagger va opri deployment-ul.

Creați un pod de testare și efectuați următoarea acțiune:

kubectl -n test run tester 
--image=quay.io/stefanprodan/podinfo:1.2.1 
-- ./podinfo --port=9898
kubectl -n test exec -it tester-xx-xx sh

Generarea erorilor HTTP 500:

watch curl http://podinfo-canary:9898/status/500

Generarea întârzierii:

watch curl http://podinfo-canary:9898/delay/1

Când numărul de verificări eșuate atinge o valoare limită, traficul este redirecționat înapoi către canalul principal, canary-ul este scalat la zero, iar desfășurarea este marcată ca eșuată.

Erorile canary și vârfurile întârzierilor sunt înregistrate ca evenimente Kubernetes și sunt stocate de Flagger în format JSON:

kubectl -n istio-system logs deployment/flagger -f | jq .msg

Începerea desfășurării canary pentru podinfo.test
Avansare podinfo.test canary greutate 5
Avansare podinfo.test canary greutate 10
Avansare podinfo.test canary greutate 15
Oprire a ratei de succes a avansării podinfo.test 69.17% < 99%
Oprire a ratei de succes a avansării podinfo.test 61.39% < 99%
Oprire a ratei de succes a avansării podinfo.test 55.06% < 99%
Oprire a ratei de succes a avansării podinfo.test 47.00% < 99%
Oprire a ratei de succes a avansării podinfo.test 37.00%  500ms
Oprire a duratei cererii de avansare podinfo.test 1.600s > 500ms
Oprire a duratei cererii de avansare podinfo.test 1.915s > 500ms
Oprire a duratei cererii de avansare podinfo.test 2.050s > 500ms
Oprire a duratei cererii de avansare podinfo.test 2.515s > 500ms
Rollback-ul podinfo.test a fost inițiat deoarece pragul verificărilor eșuate a fost atins 10
Canary eșuat! Scalarea în jos a podinfo.test

Dacă ați activat notificările Slack, veți primi un mesaj atunci când termenul de execuție este depășit sau când se atinge numărul maxim de verificări eșuate în timpul analizei:

Deploiuri canary automate cu Flagger și Istio

În concluzie

Lansarea unui service mesh, cum ar fi Istio, pe lângă Kubernetes va oferi metrici automate, jurnale și protocoale, dar desfășurarea sarcinilor de lucru depinde în continuare de instrumente externe. Flagger își propune să schimbe această situație, adăugând Istio posibilități de livrare progresivă.

Flagger este compatibil cu orice soluții CI/CD pentru Kubernetes, iar analiza canary poate fi ușor extinsă prin webhooks pentru executarea testelor de integrare/acceptare, teste de încărcare sau orice alte verificări personalizate. Deoarece Flagger este declarat și reacționează la evenimentele Kubernetes, poate fi utilizat în pipeline-urile GitOps împreună cu Weave Flux sau JenkinsX. Dacă utilizați JenkinsX, puteți instala Flagger cu extensiile jx.

Flagger este susținut Weaveworks și oferă desfășurări canary în Weave Cloud. Proiectul este testat pe GKE, EKS și pe hardware gol cu kubeadm.

Dacă aveți sugestii pentru îmbunătățirea Flagger, vă rugăm să trimiteți o întrebare sau un PR pe GitHub la stefanprodan/flagger. Contribuțiile sunt mai mult decât binevenite!

Mulțumesc Rey Chan.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster