การปรับใช้ Canary อัตโนมัติด้วย Flagger และ Istio

การปรับใช้ Canary อัตโนมัติด้วย Flagger และ Istio

CD ได้รับการยอมรับว่าเป็นแนวปฏิบัติด้านซอฟต์แวร์สำหรับองค์กร และเป็นผลมาจากวิวัฒนาการตามธรรมชาติของหลักการ CI ที่จัดตั้งขึ้น อย่างไรก็ตาม ซีดียังค่อนข้างหายาก อาจเป็นเพราะความซับซ้อนในการจัดการและความกลัวการปรับใช้ที่ล้มเหลวซึ่งส่งผลต่อความพร้อมใช้งานของระบบ

ผู้รายงานปัญหา เป็นโอเปอเรเตอร์ Kubernetes แบบโอเพ่นซอร์สที่มีจุดมุ่งหมายเพื่อขจัดความสัมพันธ์ที่สับสน ดำเนินการส่งเสริมการปรับใช้ canary โดยอัตโนมัติโดยใช้ Istio traffic offset และ Prometheus metrics เพื่อวิเคราะห์พฤติกรรมของแอปพลิเคชันระหว่างการเปิดตัวที่มีการจัดการ

ด้านล่างนี้เป็นคำแนะนำทีละขั้นตอนในการตั้งค่าและใช้ Flagger บน Google Kubernetes Engine (GKE)

การตั้งค่าคลัสเตอร์ Kubernetes

คุณเริ่มต้นด้วยการสร้างคลัสเตอร์ GKE ด้วยโปรแกรมเสริม Istio (หากคุณไม่มีบัญชี GCP คุณสามารถสมัคร ที่นี่ - เพื่อรับเครดิตฟรี).

ลงชื่อเข้าใช้ Google Cloud สร้างโครงการ และเปิดใช้งานการเรียกเก็บเงิน ติดตั้งยูทิลิตี้บรรทัดคำสั่ง จีคลาวด์ และตั้งค่าโครงการของคุณด้วย gcloud init.

ตั้งค่าโปรเจ็กต์เริ่มต้น พื้นที่คำนวณ และโซน (แทนที่ PROJECT_ID สำหรับโครงการของคุณ):

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

เปิดใช้บริการ GKE และสร้างคลัสเตอร์ด้วยโปรแกรมเสริม HPA และ 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

คำสั่งดังกล่าวจะสร้าง Node Pool เริ่มต้นที่มี VM สองตัว n1-standard-2 (vCPU: 2, RAM 7,5 GB, ดิสก์: 30 GB) ตามหลักการแล้ว คุณควรแยกส่วนประกอบ Istio ออกจากปริมาณงานของคุณ แต่ไม่มีวิธีที่ง่ายในการเรียกใช้ Istio Pods ในกลุ่มโหนดเฉพาะ รายการ Istio ถือเป็นแบบอ่านอย่างเดียวและ GKE จะเลิกทำการเปลี่ยนแปลงใดๆ เช่น การลิงก์กับโหนดหรือแยกออกจากพ็อด

ตั้งค่าข้อมูลรับรองสำหรับ kubectl:

gcloud container clusters get-credentials istio

สร้างการเชื่อมโยงบทบาทผู้ดูแลระบบคลัสเตอร์:

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

ติดตั้งเครื่องมือบรรทัดคำสั่ง หางเสือ:

brew install kubernetes-helm

Homebrew 2.0 พร้อมใช้งานแล้วสำหรับ ลินุกซ์.

สร้างบัญชีบริการและการผูกบทบาทของคลัสเตอร์สำหรับ Tiller:

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

ขยาย Tiller ในเนมสเปซ kube-system:

helm init --service-account tiller

คุณควรพิจารณาใช้ SSL ระหว่าง Helm และ Tiller สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการป้องกันการติดตั้ง Helm โปรดดูที่ docs.helm.sh

ยืนยันการตั้งค่า:

kubectl -n istio-system get svc

หลังจากนั้นไม่กี่วินาที GCP ควรกำหนดที่อยู่ IP ภายนอกสำหรับบริการ istio-ingressgateway.

การกำหนดค่า Istio Ingress Gateway

สร้างที่อยู่ IP แบบคงที่พร้อมชื่อ istio-gatewayใช้ที่อยู่ IP ของเกตเวย์ 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

ตอนนี้คุณต้องมีโดเมนอินเทอร์เน็ตและเข้าถึงผู้รับจดทะเบียน DNS ของคุณ เพิ่มสองระเบียน A (แทนที่ example.com ไปยังโดเมนของคุณ):

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

ตรวจสอบว่าไวด์การ์ด DNS ใช้งานได้:

watch host test.istio.example.com

สร้างเกตเวย์ Istio ทั่วไปเพื่อให้บริการภายนอกตาข่ายบริการผ่าน 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:
        - "*"

บันทึกทรัพยากรด้านบนเป็น public-gateway.yaml แล้วนำไปใช้:

kubectl apply -f ./public-gateway.yaml

ไม่มีระบบการผลิตใดควรให้บริการบนอินเทอร์เน็ตโดยไม่มี SSL เพื่อรักษาความปลอดภัยเกตเวย์ขาเข้าของ Istio ด้วย cert-manager, CloudDNS และ Let's Encrypt โปรดอ่าน เอกสาร แฟลกเกอร์ G.K.E.

การติดตั้งแฟลกเกอร์

ส่วนเสริม GKE Istio ไม่รวมอินสแตนซ์ Prometheus ที่ล้างข้อมูลบริการการวัดและส่งข้อมูลทางไกลของ Istio เนื่องจาก Flagger ใช้เมตริก Istio HTTP เพื่อทำการวิเคราะห์ canary คุณจึงต้องปรับใช้การกำหนดค่า Prometheus ต่อไปนี้ ซึ่งคล้ายกับการกำหนดค่าที่มาพร้อมกับ Istio Helm schema อย่างเป็นทางการ

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

เพิ่มที่เก็บ Flagger Helm:

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

ขยาย Flagger เป็นเนมสเปซ istio-systemโดยเปิดใช้งานการแจ้งเตือน 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

คุณสามารถติดตั้ง Flagger ในเนมสเปซใดก็ได้ ตราบใดที่สามารถสื่อสารกับบริการ Istio Prometheus บนพอร์ต 9090

Flagger มีแดชบอร์ด Grafana สำหรับการวิเคราะห์นกขมิ้น ติดตั้ง Grafana ในเนมสเปซ 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

เปิดเผย Grafana ผ่านเกตเวย์แบบเปิดโดยสร้างบริการเสมือน (แทนที่ example.com ไปยังโดเมนของคุณ):

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

บันทึกทรัพยากรด้านบนเป็น grafana-virtual-service.yaml แล้วนำไปใช้:

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

เมื่อย้ายไป http://grafana.istio.example.com ในเบราว์เซอร์ คุณควรถูกนำไปที่หน้าเข้าสู่ระบบของ Grafana

การปรับใช้เว็บแอปพลิเคชันด้วย Flagger

Flagger ปรับใช้ Kubernetes และปรับขนาดโดยอัตโนมัติ (HPA) จากนั้นสร้างชุดของอ็อบเจ็กต์ (การปรับใช้ Kubernetes, บริการ ClusterIP และบริการเสมือน Istio) ออบเจ็กต์เหล่านี้เปิดเผยแอปพลิเคชันไปยังตาข่ายบริการและควบคุมการวิเคราะห์และความคืบหน้าของคานารี

การปรับใช้ Canary อัตโนมัติด้วย Flagger และ Istio

สร้างเนมสเปซทดสอบโดยเปิดใช้งานการฉีด Istio Sidecar:

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

สร้างการปรับใช้และเครื่องมือปรับขนาดอัตโนมัติของพ็อด:

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

ใช้บริการโหลดทดสอบเพื่อสร้างการรับส่งข้อมูลระหว่างการวิเคราะห์ Canary:

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

สร้างทรัพยากร canary แบบกำหนดเอง (แทนที่ example.com ไปยังโดเมนของคุณ):

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

บันทึกทรัพยากรด้านบนเป็น podinfo-canary.yaml แล้วนำไปใช้:

kubectl apply -f ./podinfo-canary.yaml

หากการวิเคราะห์ข้างต้นสำเร็จ จะทำงานเป็นเวลาห้านาที โดยจะตรวจสอบเมตริก HTTP ทุกครึ่งนาที คุณสามารถกำหนดเวลาขั้นต่ำที่จำเป็นในการตรวจสอบและส่งเสริมการปรับใช้ canary โดยใช้สูตรต่อไปนี้: interval * (maxWeight / stepWeight). มีการจัดทำเอกสารฟิลด์ Canary CRD ที่นี่.

หลังจากผ่านไปสองสามวินาที Flagger จะสร้างวัตถุ 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

เปิดเบราว์เซอร์และไปที่ app.istio.example.comคุณควรเห็นหมายเลขเวอร์ชัน แอพสาธิต.

การวิเคราะห์และการส่งเสริมนกขมิ้นโดยอัตโนมัติ

ตัวตั้งค่าสถานะใช้ลูปควบคุมที่ค่อยๆ ย้ายการรับส่งข้อมูลไปยัง Canary ในขณะที่วัดเมตริกประสิทธิภาพหลัก เช่น อัตราความสำเร็จของคำขอ HTTP ระยะเวลาคำขอโดยเฉลี่ย และความสมบูรณ์ของพ็อด จากการวิเคราะห์ KPI Canary จะได้รับการเลื่อนระดับหรือขัดจังหวะ และเผยแพร่ผลการวิเคราะห์ไปยัง Slack

การปรับใช้ Canary อัตโนมัติด้วย Flagger และ Istio

การปรับใช้งาน Canary จะถูกทริกเกอร์เมื่อหนึ่งในออบเจ็กต์ต่อไปนี้เปลี่ยนแปลง:

  • ปรับใช้ PodSpec (อิมเมจคอนเทนเนอร์, คำสั่ง, พอร์ต, env ฯลฯ)
  • ConfigMaps ติดตั้งเป็นไดรฟ์ข้อมูลหรือแมปกับตัวแปรสภาพแวดล้อม
  • ข้อมูลลับจะถูกติดตั้งเป็นไดรฟ์ข้อมูลหรือแปลงเป็นตัวแปรสภาพแวดล้อม

เรียกใช้การปรับใช้ canary เมื่ออัปเดตอิมเมจคอนเทนเนอร์:

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

ตัวตั้งค่าสถานะตรวจพบว่าเวอร์ชันการปรับใช้มีการเปลี่ยนแปลงและเริ่มแยกวิเคราะห์:

kubectl -n test describe canary/podinfo

Events:

New revision detected podinfo.test
Scaling up podinfo.test
Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Advance podinfo.test canary weight 20
Advance podinfo.test canary weight 25
Advance podinfo.test canary weight 30
Advance podinfo.test canary weight 35
Advance podinfo.test canary weight 40
Advance podinfo.test canary weight 45
Advance podinfo.test canary weight 50
Copying podinfo.test template spec to podinfo-primary.test
Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available
Promotion completed! Scaling down podinfo.test

ในระหว่างการวิเคราะห์ สามารถติดตามผลคานารีได้โดยใช้ Grafana:

การปรับใช้ Canary อัตโนมัติด้วย Flagger และ Istio

โปรดทราบว่าหากมีการใช้การเปลี่ยนแปลงใหม่กับการปรับใช้ในระหว่างการวิเคราะห์ Canary Flagger จะเริ่มต้นขั้นตอนการวิเคราะห์ใหม่

ทำรายการนกคีรีบูนทั้งหมดในคลัสเตอร์ของคุณ:

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

หากคุณเปิดใช้งานการแจ้งเตือน Slack คุณจะได้รับข้อความต่อไปนี้:

การปรับใช้ Canary อัตโนมัติด้วย Flagger และ Istio

ย้อนกลับอัตโนมัติ

ในระหว่างการวิเคราะห์ Canary คุณสามารถสร้างข้อผิดพลาดสังเคราะห์ HTTP 500 และเวลาในการตอบสนองสูงเพื่อดูว่า Flagger จะหยุดการปรับใช้หรือไม่

สร้างพ็อดทดสอบและทำสิ่งต่อไปนี้:

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

สร้างข้อผิดพลาด HTTP 500:

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

การสร้างความล่าช้า:

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

เมื่อจำนวนการตรวจสอบที่ล้มเหลวถึงเกณฑ์ ทราฟฟิกจะถูกส่งกลับไปยังแชนเนลหลัก ปรับสเกล Canary เป็นศูนย์ และการปรับใช้จะถูกทำเครื่องหมายว่าล้มเหลว

ข้อผิดพลาด Canary และเวลาในการตอบสนองที่เพิ่มขึ้นจะถูกบันทึกเป็นเหตุการณ์ Kubernetes และบันทึกโดย Flagger ในรูปแบบ JSON:

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

Starting canary deployment for podinfo.test
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Halt podinfo.test advancement success rate 69.17% < 99%
Halt podinfo.test advancement success rate 61.39% < 99%
Halt podinfo.test advancement success rate 55.06% < 99%
Halt podinfo.test advancement success rate 47.00% < 99%
Halt podinfo.test advancement success rate 37.00% < 99%
Halt podinfo.test advancement request duration 1.515s > 500ms
Halt podinfo.test advancement request duration 1.600s > 500ms
Halt podinfo.test advancement request duration 1.915s > 500ms
Halt podinfo.test advancement request duration 2.050s > 500ms
Halt podinfo.test advancement request duration 2.515s > 500ms
Rolling back podinfo.test failed checks threshold reached 10
Canary failed! Scaling down podinfo.test

หากคุณเปิดใช้งานการแจ้งเตือน Slack คุณจะได้รับข้อความเมื่อเกินกำหนดเวลาหรือถึงจำนวนการตรวจสอบที่ล้มเหลวสูงสุดในการวิเคราะห์:

การปรับใช้ Canary อัตโนมัติด้วย Flagger และ Istio

ในข้อสรุป

การเรียกใช้ Service Mesh เช่น Istio เพิ่มเติมจาก Kubernetes จะให้เมตริก บันทึก และโปรโตคอลอัตโนมัติ แต่การปรับใช้ปริมาณงานยังคงขึ้นอยู่กับเครื่องมือภายนอก Flagger มีเป้าหมายที่จะเปลี่ยนแปลงสิ่งนี้โดยเพิ่มความสามารถ Istio การจัดส่งแบบก้าวหน้า.

Flagger เข้ากันได้กับโซลูชัน Kubernetes CI/CD และสามารถขยายการวิเคราะห์ Canary ได้อย่างง่ายดาย เว็บฮุค เพื่อดำเนินการรวมระบบ/ทดสอบการยอมรับ ทดสอบโหลด หรือตรวจสอบแบบกำหนดเองอื่นๆ เนื่องจาก Flagger เป็นผู้ประกาศและตอบสนองต่อเหตุการณ์ Kubernetes จึงสามารถใช้ใน GitOps ไปป์ไลน์พร้อมกับ สานฟลักซ์ หรือ เจนกินส์X. หากคุณใช้ JenkinsX คุณสามารถติดตั้ง Flagger ด้วย jx addons

รองรับแฟลกเกอร์ งานทอ และจัดเตรียมการปรับใช้ Canary ใน สานเมฆ. โปรเจ็กต์กำลังทดสอบบน GKE, EKS และ Bare Metal ด้วย kubeadm

หากคุณมีข้อเสนอแนะในการปรับปรุง Flagger โปรดส่งปัญหาหรือประชาสัมพันธ์เกี่ยวกับ GitHub ที่ สเตฟาน โปรแดน/แฟลกเกอร์. ยินดีต้อนรับการมีส่วนร่วมมากกว่า!

ขอบคุณ เรย์ซัง.

ที่มา: will.com

เพิ่มความคิดเห็น