
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.
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 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ă ș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-aActivaț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_PERMISSIVEComanda 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 istioCreaț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ă :
brew install kubernetes-helmHomebrew 2.0 este acum de asemenea disponibil pentru .
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:tillerDezvoltă Tiller în namespace kube-system:
helm init --service-account tillerAr trebui să luați în considerare utilizarea SSL între Helm și Tiller. Pentru informații suplimentare despre securizarea instalării Helm, consultați
Confirmă setările:
kubectl -n istio-system get svcDupă 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-central1Acum 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.comCreează 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.yamlNiciun 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 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.yamlAdaugă 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=flaggerPoț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-meDeschideț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-grafanaSalvați resursa de mai sus ca grafana-virtual-service.yaml, apoi aplicați-o:
kubectl apply -f ./grafana-virtual-service.yamlCâ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.
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.yamlCreează 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.yamlDesfășurați un serviciu de testare a sarcinii pentru a genera trafic în timpul analizei canary:
helm upgrade -i flagger-loadtester flagger/loadtester
--namespace=testCreează 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.yamlAnaliza 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 .
Î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/podinfoDeschideți browserul și accesați app.istio.example.com, ar trebui să vedeți numărul versiunii .
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.
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.1Flagger 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:
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:07ZDacă ați activat notificările Slack, veți primi următoarele mesaje:
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 shGenerarea erorilor HTTP 500:
watch curl http://podinfo-canary:9898/status/500Generarea întârzierii:
watch curl http://podinfo-canary:9898/delay/1Câ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.testDacă 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:
Î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 .
Flagger este compatibil cu orice soluții CI/CD pentru Kubernetes, iar analiza canary poate fi ușor extinsă prin 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 sau . Dacă utilizați JenkinsX, puteți instala Flagger cu extensiile jx.
Flagger este susținut și oferă desfășurări canary în . 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 . Contribuțiile sunt mai mult decât binevenite!
Mulțumesc .
Sursa: habr.com
