Triển khai canary tự động với Flagger và Istio

Triển khai canary tự động với Flagger và Istio

CD được công nhận là một hoạt động phần mềm doanh nghiệp và là sự phát triển tự nhiên của các nguyên tắc CI đã được thiết lập. Tuy nhiên, CD vẫn còn khá hiếm, có lẽ do sự phức tạp trong quản lý và nỗi sợ triển khai thất bại ảnh hưởng đến tính khả dụng của hệ thống.

Người gắn cờ là một toán tử Kubernetes mã nguồn mở nhằm mục đích loại bỏ các mối quan hệ khó hiểu. Nó tự động hóa việc thúc đẩy triển khai canary bằng cách sử dụng bù đắp lưu lượng truy cập Istio và số liệu Prometheus để phân tích hành vi của ứng dụng trong quá trình triển khai được quản lý.

Dưới đây là hướng dẫn từng bước để thiết lập và sử dụng Flagger trên Google Kubernetes Engine (GKE).

Thiết lập cụm Kubernetes

Bạn bắt đầu bằng cách tạo cụm GKE bằng tiện ích bổ sung Istio (nếu bạn chưa có tài khoản GCP, bạn có thể đăng ký đây - để nhận tín dụng miễn phí).

Đăng nhập vào Google Cloud, tạo dự án và bật tính năng thanh toán cho dự án đó. Cài đặt tiện ích dòng lệnh gcloud và cấu hình dự án của bạn với gcloud init.

Đặt dự án, vùng tính toán và vùng mặc định (thay thế PROJECT_ID cho dự án của bạn):

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

Kích hoạt dịch vụ GKE và tạo một cụm với các tiện ích bổ sung HPA và 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

Lệnh trên sẽ tạo một nhóm nút mặc định bao gồm hai VM n1-standard-2 (vCPU: 2, RAM 7,5 GB, ổ đĩa: 30 GB). Lý tưởng nhất là các thành phần Istio nên được tách biệt khỏi khối lượng công việc của chúng, nhưng không có cách nào dễ dàng để chạy các nhóm Istio trên nhóm nút chuyên dụng. Tệp kê khai Istio được coi là chỉ đọc và GKE sẽ hoàn nguyên mọi thay đổi như liên kết với nút hoặc tách khỏi nhóm.

Thiết lập thông tin xác thực cho kubectl:

gcloud container clusters get-credentials istio

Tạo ràng buộc vai trò quản trị viên cụm:

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

Cài đặt công cụ dòng lệnh Quản lý:

brew install kubernetes-helm

Homebrew 2.0 hiện cũng có sẵn cho Linux.

Tạo tài khoản dịch vụ và ràng buộc vai trò cụm cho Tiller:

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

Mở rộng Tiller trong không gian tên kube-system:

helm init --service-account tiller

Bạn nên cân nhắc việc sử dụng SSL giữa Helm và Tiller. Để biết thêm thông tin về việc bảo vệ cài đặt Helm của bạn, hãy xem docs.helm.sh

Xác nhận cài đặt:

kubectl -n istio-system get svc

Sau vài giây, GCP sẽ gán địa chỉ IP bên ngoài cho dịch vụ istio-ingressgateway.

Thiết lập Cổng vào Istio

Tạo địa chỉ IP tĩnh có tên istio-gatewaysử dụng địa chỉ IP cổng 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

Bây giờ bạn cần một miền internet và quyền truy cập vào công ty đăng ký DNS của mình. Thêm hai bản ghi A (thay thế example.com vào miền của bạn):

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

Xác minh rằng ký tự đại diện DNS đang hoạt động:

watch host test.istio.example.com

Tạo một cổng Istio chung để cung cấp các dịch vụ bên ngoài lưới dịch vụ qua 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:
        - "*"

Lưu tài nguyên trên dưới dạng public-gateway.yaml và sau đó áp dụng nó:

kubectl apply -f ./public-gateway.yaml

Không có hệ thống sản xuất nào cung cấp dịch vụ trên Internet mà không có SSL. Để bảo mật cổng vào Istio của bạn bằng trình quản lý chứng chỉ, CloudDNS và Let's Encrypt, vui lòng đọc tài liệu Người gắn cờ G.K.E.

Cài đặt người gắn cờ

Tiện ích bổ sung GKE Istio không bao gồm phiên bản Prometheus giúp dọn dẹp dịch vụ đo từ xa Istio. Vì Flagger sử dụng số liệu HTTP Istio để thực hiện phân tích canary nên bạn cần triển khai cấu hình Prometheus sau, tương tự như cấu hình đi kèm với lược đồ Istio Helm chính thức.

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

Thêm kho lưu trữ Flagger Helm:

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

Mở rộng Người gắn cờ sang không gian tên istio-systembằng cách bật thông báo 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

Bạn có thể cài đặt Flagger ở bất kỳ không gian tên nào miễn là nó có thể giao tiếp với dịch vụ Istio Prometheus trên cổng 9090.

Flagger có bảng điều khiển Grafana để phân tích chim hoàng yến. Cài đặt Grafana trong không gian tên 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

Đưa Grafana thông qua một cổng mở bằng cách tạo một dịch vụ ảo (thay thế example.com vào miền của bạn):

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

Lưu tài nguyên trên dưới dạng grafana-virtual-service.yaml và sau đó áp dụng nó:

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

Khi đi đến http://grafana.istio.example.com Trình duyệt của bạn sẽ chuyển hướng bạn đến trang đăng nhập Grafana.

Triển khai ứng dụng web bằng Flagger

Flagger triển khai Kubernetes và, nếu cần, tự động điều chỉnh theo chiều ngang (HPA), sau đó tạo một loạt đối tượng (triển khai Kubernetes, dịch vụ ClusterIP và dịch vụ ảo Istio). Các đối tượng này đưa ứng dụng vào lưới dịch vụ và quản lý việc phân tích và quảng cáo canary.

Triển khai canary tự động với Flagger và Istio

Tạo một không gian tên thử nghiệm khi bật triển khai Istio Sidecar:

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

Tạo một công cụ triển khai và chia tỷ lệ theo chiều ngang tự động cho nhóm:

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

Triển khai dịch vụ kiểm tra tải để tạo lưu lượng truy cập trong quá trình phân tích canary:

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

Tạo tài nguyên canary tùy chỉnh (thay thế example.com vào miền của bạn):

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

Lưu tài nguyên trên dưới dạng podinfo-canary.yaml rồi áp dụng nó:

kubectl apply -f ./podinfo-canary.yaml

Phân tích trên, nếu thành công, sẽ chạy trong XNUMX phút, kiểm tra số liệu HTTP cứ nửa phút một lần. Bạn có thể xác định thời gian tối thiểu cần thiết để kiểm tra và thúc đẩy quá trình triển khai canary bằng công thức sau: interval * (maxWeight / stepWeight). Các trường CRD Canary được ghi lại đây.

Sau vài giây, Flagger sẽ tạo các đối tượng 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

Mở trình duyệt của bạn và đi đến app.istio.example.com, bạn sẽ thấy số phiên bản ứng dụng demo.

Phân tích và quảng bá chim hoàng yến tự động

Người gắn cờ triển khai một vòng điều khiển để di chuyển dần lưu lượng truy cập đến canary trong khi đo lường các chỉ số hiệu suất chính như tỷ lệ thành công của yêu cầu HTTP, thời lượng yêu cầu trung bình và tình trạng của nhóm. Dựa trên phân tích KPI, chim hoàng yến được thăng chức hoặc chấm dứt hợp đồng và kết quả phân tích được công bố trên Slack.

Triển khai canary tự động với Flagger và Istio

Triển khai Canary được kích hoạt khi một trong các đối tượng sau thay đổi:

  • Triển khai PodSpec (hình ảnh vùng chứa, lệnh, cổng, env, v.v.)
  • Bản đồ cấu hình được gắn dưới dạng khối hoặc được chuyển đổi thành biến môi trường
  • Bí mật được gắn dưới dạng khối lượng hoặc chuyển đổi thành biến môi trường

Chạy triển khai canary khi cập nhật hình ảnh vùng chứa:

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

Người gắn cờ phát hiện phiên bản triển khai đã thay đổi và bắt đầu phân tích nó:

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

Trong quá trình phân tích, kết quả canary có thể được theo dõi bằng Grafana:

Triển khai canary tự động với Flagger và Istio

Xin lưu ý: nếu những thay đổi mới được áp dụng cho quá trình triển khai trong quá trình phân tích canary, Người gắn cờ sẽ khởi động lại giai đoạn phân tích.

Lập danh sách tất cả các chim hoàng yến trong cụm của bạn:

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

Nếu bạn đã bật thông báo Slack, bạn sẽ nhận được các thông báo sau:

Triển khai canary tự động với Flagger và Istio

Tự động quay lại

Trong quá trình phân tích canary, bạn có thể tạo ra lỗi HTTP 500 tổng hợp và độ trễ phản hồi cao để kiểm tra xem Người gắn cờ có dừng triển khai hay không.

Tạo nhóm thử nghiệm và thực hiện những việc sau trong đó:

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

Tạo lỗi HTTP 500:

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

Tạo độ trễ:

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

Khi số lần kiểm tra không thành công đạt đến ngưỡng, lưu lượng truy cập sẽ được định tuyến trở lại kênh chính, kênh canary được chia tỷ lệ về XNUMX và quá trình triển khai được đánh dấu là không thành công.

Lỗi Canary và mức tăng đột biến về độ trễ được ghi lại dưới dạng sự kiện Kubernetes và được Flagger ghi lại ở định dạng 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

Nếu bạn đã bật thông báo Slack, bạn sẽ nhận được thông báo khi vượt quá thời hạn hoàn thành hoặc đạt số lượng đánh giá không thành công tối đa trong một phân tích:

Triển khai canary tự động với Flagger và Istio

Kết luận

Việc chạy lưới dịch vụ như Istio trên Kubernetes sẽ cung cấp số liệu, nhật ký và nhật ký tự động, nhưng việc triển khai khối lượng công việc vẫn phụ thuộc vào các công cụ bên ngoài. Flagger nhằm mục đích thay đổi điều này bằng cách thêm các khả năng của Istio giao hàng tiến bộ.

Flagger tương thích với mọi giải pháp CI/CD cho Kubernetes và phân tích canary có thể dễ dàng mở rộng với webhook để thực hiện các thử nghiệm tích hợp/chấp nhận hệ thống, thử nghiệm tải hoặc bất kỳ thử nghiệm tùy chỉnh nào khác. Vì Flagger có tính khai báo và phản hồi các sự kiện Kubernetes nên nó có thể được sử dụng trong quy trình GitOps cùng với thông lượng dệt hoặc JenkinsX. Nếu bạn đang sử dụng JenkinsX, bạn có thể cài đặt Flagger với các tiện ích bổ sung jx.

Hỗ trợ người gắn cờ hàng dệt và cung cấp các triển khai canary trong Dệt mây. Dự án được thử nghiệm trên GKE, EKS và kim loại trần với kubeadm.

Nếu bạn có đề xuất cải thiện Trình gắn cờ, vui lòng gửi vấn đề hoặc PR trên GitHub tại stefanprodan/người gắn cờ. Đóng góp được chào đón nhiều hơn!

Cảm ơn Ray Tsang.

Nguồn: www.habr.com

Thêm một lời nhận xét