αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ Canary αžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αž‡αžΆαž˜αž½αž™ Flagger αž“αž·αž„ Istio

αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ Canary αžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αž‡αžΆαž˜αž½αž™ Flagger αž“αž·αž„ Istio

αžŸαŸŠαžΈαžŒαžΈαžαŸ’αžšαžΌαžœαž”αžΆαž“αž‘αž‘αž½αž›αžŸαŸ’αž‚αžΆαž›αŸ‹αžαžΆαž‡αžΆαž€αžΆαžšαž’αž“αž»αžœαžαŸ’αžαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŸαž αž‚αŸ’αžšαžΆαžŸ αž αžΎαž™αž‡αžΆαž›αž‘αŸ’αž’αž•αž›αž“αŸƒαž€αžΆαžšαžœαž·αžœαžαŸ’αžαž“αŸαž’αž˜αŸ’αž˜αž‡αžΆαžαž·αž“αŸƒαž‚αŸ„αž›αž€αžΆαžšαžŽαŸ CI αžŠαŸ‚αž›αž”αžΆαž“αž”αž„αŸ’αž€αžΎαžαž‘αžΎαž„αŸ” αž‘αŸ„αŸ‡αž™αŸ‰αžΆαž„αžŽαžΆαž€αŸαžŠαŸ„αž™ αžŸαŸŠαžΈαžŒαžΈαž“αŸ…αžαŸ‚αž€αž˜αŸ’αžšαžŽαžΆαžŸαŸ‹ αž”αŸ’αžšαž αŸ‚αž›αž‡αžΆαžŠαŸ„αž™αžŸαžΆαžšαžαŸ‚αž—αžΆαž–αžŸαŸ’αž˜αž»αž‚αžŸαŸ’αž˜αžΆαž‰αž“αŸƒαž€αžΆαžšαž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„ αž“αž·αž„αž€αžΆαžšαž—αŸαž™αžαŸ’αž›αžΆαž…αž“αŸƒαž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™αžŠαŸ‚αž›αž”αžšαžΆαž‡αŸαž™ αžŠαŸ‚αž›αž”αŸ‰αŸ‡αž–αžΆαž›αŸ‹αžŠαž›αŸ‹αž—αžΆαž–αž’αžΆαž…αžšαž€αž”αžΆαž“αž“αŸƒαž”αŸ’αžšαž–αŸαž“αŸ’αž’αŸ”

αž‘αž„αŸ‹αž‡αžΆαžαž· αž‚αžΊαž‡αžΆαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžš Kubernetes αž”αŸ’αžšαž—αž–αž”αžΎαž€αž…αŸ†αž αžŠαŸ‚αž›αž˜αžΆαž“αž‚αŸ„αž›αž”αŸ†αžŽαž„αž›αž»αž”αž”αŸ†αž”αžΆαžαŸ‹αž‘αŸ†αž“αžΆαž€αŸ‹αž‘αŸ†αž“αž„αžŠαŸ‚αž›αž…αŸ’αžšαž”αžΌαž€αž…αŸ’αžšαž”αž›αŸ‹αŸ” αžœαžΆαž’αŸ’αžœαžΎαž±αŸ’αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αž€αž˜αŸ’αž˜αž“αŸƒαž€αžΆαžšαž›αžΎαž€αž€αž˜αŸ’αž–αžŸαŸ‹αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ Canary αžŠαŸ„αž™αž”αŸ’αžšαžΎαž’αž»αž αŸ’αžœαžŸαž·αžαž…αžšαžΆαž…αžšαžŽαŸ Istio αž“αž·αž„αž˜αŸ‰αŸ‚αžαŸ’αžš Prometheus αžŠαžΎαž˜αŸ’αž”αžΈαžœαž·αž—αžΆαž‚αž₯αžšαž·αž™αžΆαž”αžαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž€αŸ†αž‘αž»αž„αž–αŸαž›αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŠαŸ‚αž›αž”αžΆαž“αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αŸ”

αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αž“αŸαŸ‡αž‚αžΊαž‡αžΆαž€αžΆαžšαžŽαŸ‚αž“αžΆαŸ†αž‡αžΆαž‡αŸ†αž αžΆαž“αŸ—αž€αŸ’αž“αž»αž„αž€αžΆαžšαžŠαŸ†αž‘αžΎαž„ αž“αž·αž„αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹ Flagger αž“αŸ…αž›αžΎ Google Kubernetes Engine (GKE)αŸ”

αž€αžΆαžšαžŠαŸ†αž‘αžΎαž„αž€αŸ’αžšαž»αž˜ Kubernetes

αž’αŸ’αž“αž€αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αžŠαŸ„αž™αž”αž„αŸ’αž€αžΎαžαž…αž„αŸ’αž€αŸ„αž˜ GKE αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž”αž“αŸ’αžαŸ‚αž˜ Istio (αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αž·αž“αž˜αžΆαž“αž‚αžŽαž“αžΈ GCP αž’αŸ’αž“αž€αž’αžΆαž…αž…αž»αŸ‡αžˆαŸ’αž˜αŸ„αŸ‡αž”αžΆαž“ αž“αŸ…αž‘αžΈαž“αŸαŸ‡ - αžŠαžΎαž˜αŸ’αž”αžΈαž‘αž‘αž½αž›αž”αžΆαž“αž₯αžŽαž‘αžΆαž“αž₯αžαž‚αž·αžαžαŸ’αž›αŸƒ) αŸ”

αž…αžΌαž› Google Cloud αž”αž„αŸ’αž€αžΎαžαž‚αž˜αŸ’αžšαŸ„αž„ αž“αž·αž„αž”αžΎαž€αž€αžΆαžšαž…αŸαž‰αžœαž·αž€αŸ’αž€αž™αž”αžαŸ’αžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžœαžΆαŸ” αžŠαŸ†αž‘αžΎαž„αž§αž”αž€αžšαžŽαŸαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž”αž“αŸ’αž‘αžΆαžαŸ‹αž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆ gcloud αž“αž·αž„αžšαŸ€αž”αž…αŸ†αž‚αž˜αŸ’αžšαŸ„αž„αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αž‡αžΆαž˜αž½αž™ 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

αž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆαžαžΆαž„αž›αžΎαž“αžΉαž„αž”αž„αŸ’αž€αžΎαžαž€αŸ’αžšαž»αž˜αžαŸ’αž“αžΆαŸ†αž„αž›αŸ†αž“αžΆαŸ†αžŠαžΎαž˜ αžšαž½αž˜αž‘αžΆαŸ†αž„ VMs αž–αžΈαžš n1-standard-2 (vCPU: 2, RAM 7,5 GB, ថអស: 30 GB) αŸ” αžαžΆαž˜αž§αžαŸ’αžŠαž˜αž‚αžαž· αž’αŸ’αž“αž€αž‚αž½αžšαžαŸ‚αž‰αŸ‚αž€αžŸαž˜αžΆαžŸαž’αžΆαžαž» Istio αž…αŸαž‰αž–αžΈαž”αž“αŸ’αž‘αž»αž€αž€αžΆαžšαž„αžΆαžšαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž˜αž·αž“αž˜αžΆαž“αžœαž·αž’αžΈαž„αžΆαž™αžŸαŸ’αžšαž½αž›αž€αŸ’αž“αž»αž„αž€αžΆαžšαžŠαŸ†αžŽαžΎαžšαž€αžΆαžš Istio Pods αž“αŸ…αž€αŸ’αž“αž»αž„αž€αŸ’αžšαž»αž˜αžαŸ’αž“αžΆαŸ†αž„αž‡αžΆαž€αŸ‹αž›αžΆαž€αŸ‹αž“αŸ„αŸ‡αž‘αŸαŸ” Istio manifests αžαŸ’αžšαžΌαžœαž”αžΆαž“αž…αžΆαžαŸ‹αž‘αž»αž€αžαžΆαž”αžΆαž“αžαŸ‚αž’αžΆαž“ αž αžΎαž™ GKE αž“αžΉαž„αž˜αž·αž“αž’αŸ’αžœαžΎαžœαž·αž‰αž“αžΌαžœαž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžŽαžΆαž˜αž½αž™ αžŠαžΌαž…αž‡αžΆαž€αžΆαžšαž—αŸ’αž‡αžΆαž”αŸ‹αž‘αŸ… node αž¬αž€αžΆαžšαž•αŸ’αžŠαžΆαž…αŸ‹αž…αŸαž‰αž–αžΈ pod αž˜αž½αž™αŸ”

αžšαŸ€αž”αž…αŸ†αž›αž·αžαž·αžαžŸαž˜αŸ’αž‚αžΆαž›αŸ‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ 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 αž₯αž‘αžΌαžœαž“αŸαŸ‡αž€αŸαž˜αžΆαž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž•αž„αžŠαŸ‚αžšαŸ” Linux.

αž”αž„αŸ’αž€αžΎαžαž‚αžŽαž“αžΈαžŸαŸαžœαžΆαž€αž˜αŸ’αž˜ αž“αž·αž„αž€αžΆαžšαž…αž„αžαž½αž“αžΆαž‘αžΈαž‡αžΆαž€αŸ’αžšαž»αž˜αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ TillerαŸ–

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

αž–αž„αŸ’αžšαžΈαž€ Tiller αž€αŸ’αž“αž»αž„ namespace kube-system:

helm init --service-account tiller

αž’αŸ’αž“αž€αž‚αž½αžšαžαŸ‚αž–αž·αž…αžΆαžšαžŽαžΆαž”αŸ’αžšαžΎ SSL αžšαžœαžΆαž„ Helm αž“αž·αž„ Tiller αŸ” αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž–αŸαžαŸŒαž˜αžΆαž“αž”αž“αŸ’αžαŸ‚αž˜αž’αŸ†αž–αžΈαž€αžΆαžšαž€αžΆαžšαž–αžΆαžšαž€αžΆαžšαžŠαŸ†αž‘αžΎαž„αž˜αž½αž€αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αžŸαžΌαž˜αž˜αžΎαž› 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 αž•αŸ’αž›αžΌαžœαž€αžΆαžšαŸ”

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

αž–αž„αŸ’αžšαžΈαž€αž‘αž„αŸ‹αž‡αžΆαžαž·αž‘αŸ…αž…αž“αŸ’αž›αŸ„αŸ‡αžˆαŸ’αž˜αŸ„αŸ‡ 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 αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαžœαž·αž—αžΆαž‚ Canary αŸ” αžŠαŸ†αž‘αžΎαž„ Grafana αž€αŸ’αž“αž»αž„ 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-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 αž“αŸ…αž€αŸ’αž“αž»αž„ browser αž’αŸ’αž“αž€αž‚αž½αžšαžαŸ‚αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŠαžΉαž€αž“αžΆαŸ†αž‘αŸ…αž€αžΆαž“αŸ‹αž‘αŸ†αž–αŸαžšαž…αžΌαž› 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 metrics αžšαŸ€αž„αžšαžΆαž›αŸ‹αž€αž“αŸ’αž›αŸ‡αž“αžΆαž‘αžΈαŸ” αž’αŸ’αž“αž€αž’αžΆαž…αž€αŸ†αžŽαžαŸ‹αž–αŸαž›αžœαŸαž›αžΆαž’αž”αŸ’αž”αž”αžšαž˜αžΆαžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž€αžΆαžšαžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαžŸαž»αž–αž›αž—αžΆαž– αž“αž·αž„αž›αžΎαž€αž€αž˜αŸ’αž–αžŸαŸ‹αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ 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 αžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·

Flagger αž’αž“αž»αžœαžαŸ’αžαžšαž„αŸ’αžœαž·αž›αž‡αž»αŸ†αžαŸ’αžšαž½αžαž–αž·αž“αž·αžαŸ’αž™αžŠαŸ‚αž›αž•αŸ’αž›αžΆαžŸαŸ‹αž‘αžΈαž”αž“αŸ’αžαž·αž…αž˜αŸ’αžαž„ αŸ— αž…αžšαžΆαž…αžšαž‘αŸ…αž€αžΆαž“αŸ‹ Canary αžαžŽαŸˆαž–αŸαž›αžŠαŸ‚αž›αžœαžΆαžŸαŸ‹αžŸαŸ’αž‘αž„αŸ‹αž€αžΆαžšαž’αž“αž»αžœαžαŸ’αžαžŸαŸ†αžαžΆαž“αŸ‹αŸ—αžŠαžΌαž…αž‡αžΆαž’αžαŸ’αžšαžΆαž‡αŸ„αž‚αž‡αŸαž™αžŸαŸ†αžŽαžΎ HTTP αžšαž™αŸˆαž–αŸαž›αžŸαŸ’αž“αžΎαžŸαž»αŸ†αž‡αžΆαž˜αž’αŸ’αž™αž˜ αž“αž·αž„αžŸαž»αžαž—αžΆαž–αžšαž”αžŸαŸ‹ pod αŸ” αžŠαŸ„αž™αž•αŸ’αž’αŸ‚αž€αž›αžΎαž€αžΆαžšαžœαž·αž—αžΆαž‚ KPI Canary αžαŸ’αžšαžΌαžœαž”αžΆαž“αž•αŸ’αžŸαž–αŸ’αžœαž•αŸ’αžŸαžΆαž™ αž¬αžšαŸ†αžαžΆαž“ αž αžΎαž™αž›αž‘αŸ’αž’αž•αž›αž“αŸƒαž€αžΆαžšαžœαž·αž—αžΆαž‚αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ„αŸ‡αž–αž»αž˜αŸ’αž–αž•αŸ’αžŸαžΆαž™αž‘αŸ… Slack αŸ”

αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ Canary αžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αž‡αžΆαž˜αž½αž™ Flagger αž“αž·αž„ Istio

αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ Canary αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αž„αŸ’αž€αž‘αžΎαž„ αž“αŸ…αž–αŸαž›αžŠαŸ‚αž›αžœαžαŸ’αžαž»αž˜αž½αž™αž€αŸ’αž“αž»αž„αž…αŸ†αžŽαŸ„αž˜αžœαžαŸ’αžαž»αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαŸ–

  • αžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ PodSpec (αžšαžΌαž”αž—αžΆαž–αž€αž»αž„αžαžΊαž“αŸαžš αž–αžΆαž€αŸ’αž™αž”αž‰αŸ’αž‡αžΆ αž…αŸ’αžšαž€ env αŸ”αž›αŸ”)
  • ConfigMaps αžαŸ’αžšαžΌαžœβ€‹αž”αžΆαž“β€‹αž˜αŸ‰αŸ„αž“β€‹αž‡αžΆβ€‹αž—αžΆαž‚ αž¬β€‹αžαŸ’αžšαžΌαžœβ€‹αž”αžΆαž“β€‹αž•αŸ’αž‚αžΌαž•αŸ’αž‚αž„β€‹αž‘αŸ…β€‹αž“αžΉαž„β€‹αž’αžαŸαžšβ€‹αž”αžšαž·αžŸαŸ’αžαžΆαž“
  • αž’αžΆαžαŸŒαž€αŸ†αž”αžΆαŸ†αž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αž˜αŸ‰αŸ„αž“αž‡αžΆαž—αžΆαž‚ αž¬αž”αŸ†αž”αŸ’αž›αŸ‚αž„αž‘αŸ…αž‡αžΆαž’αžαŸαžšαž”αžšαž·αžŸαŸ’αžαžΆαž“

αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš Canary deploy αž“αŸ…αž–αŸαž›αž’αžΆαž”αŸ‹αžŠαŸαžαžšαžΌαž”αž—αžΆαž–αž€αž»αž„αžαžΊαž“αŸαžšαŸ–

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

Flagger αžšαž€αžƒαžΎαž‰αžαžΆαž€αŸ†αžŽαŸ‚αžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™αž”αžΆαž“αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžš αž αžΎαž™αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž‰αŸ‚αž€αžœαžΆαŸ–

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

αž€αŸ’αž“αž»αž„αž’αŸ†αž‘αž»αž„αž–αŸαž›αž“αŸƒαž€αžΆαžšαžœαž·αž—αžΆαž‚ αž›αž‘αŸ’αž’αž•αž› Canary αž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αžαžΆαž˜αžŠαžΆαž“αžŠαŸ„αž™αž”αŸ’αžšαžΎ GrafanaαŸ–

αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ Canary αžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž·αž‡αžΆαž˜αž½αž™ Flagger αž“αž·αž„ Istio

αžŸαžΌαž˜αž…αŸ†αžŽαžΆαŸ†αžαžΆ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžαŸ’αž˜αžΈαžαŸ’αžšαžΌαžœαž”αžΆαž“αž’αž“αž»αžœαžαŸ’αžαž…αŸ†αž–αŸ„αŸ‡αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™αž€αŸ†αž‘αž»αž„αž–αŸαž›αž€αžΆαžšαžœαž·αž—αžΆαž‚ Canary αž“αŸ„αŸ‡ Flagger αž“αžΉαž„αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αžŠαŸ†αžŽαžΆαž€αŸ‹αž€αžΆαž›αžœαž·αž—αžΆαž‚αž‘αžΎαž„αžœαž·αž‰αŸ”

αž’αŸ’αžœαžΎαž”αž‰αŸ’αž‡αžΈ Canaries αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž…αž„αŸ’αž€αŸ„αž˜αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ–

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

αž“αŸ…αž€αŸ’αž“αž»αž„αžŸαŸαž…αž€αŸ’αžαžΈαžŸαž“αŸ’αž“αž·αžŠαŸ’αž‹αžΆαž“

αž€αžΆαžšαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž”αžŽαŸ’αžαžΆαž‰αžŸαŸαžœαžΆαžŠαžΌαž…αž‡αžΆ Istio αž”αž“αŸ’αžαŸ‚αž˜αž›αžΎ Kubernetes αž“αžΉαž„αž•αŸ’αžαž›αŸ‹αž“αžΌαžœαž€αžΆαžšαžœαžΆαžŸαŸ‹αžœαŸ‚αž„ αž€αŸ†αžŽαžαŸ‹αž αŸαžαž» αž“αž·αž„αž–αž·αž’αžΈαž€αžΆαžšαžŠαŸ„αž™αžŸαŸ’αžœαŸαž™αž”αŸ’αžšαžœαžαŸ’αžαž· αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™αž”αž“αŸ’αž‘αž»αž€αž€αžΆαžšαž„αžΆαžšαž“αŸ…αžαŸ‚αž’αžΆαžŸαŸ’αžšαŸαž™αž›αžΎαž§αž”αž€αžšαžŽαŸαžαžΆαž„αž€αŸ’αžšαŸ…αŸ” Flagger αž˜αžΆαž“αž”αŸ†αžŽαž„αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžœαžΆαžŠαŸ„αž™αž”αž“αŸ’αžαŸ‚αž˜αžŸαž˜αžαŸ’αžαž—αžΆαž– Istio αž€αžΆαžšαž”αž‰αŸ’αž‡αžΌαž“αž”αž“αŸ’αž.

Flagger αž‚αžΊαžαŸ’αžšαžΌαžœαž‚αŸ’αž“αžΆαž‡αžΆαž˜αž½αž™αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™ Kubernetes CI/CD αžŽαžΆαž˜αž½αž™ αž αžΎαž™αž€αžΆαžšαžœαž·αž—αžΆαž‚ Canary αž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž–αž„αŸ’αžšαžΈαž€αž™αŸ‰αžΆαž„αž„αžΆαž™αžŸαŸ’αžšαž½αž›αž‡αžΆαž˜αž½αž™ webhooks αžŠαžΎαž˜αŸ’αž”αžΈαž’αž“αž»αžœαžαŸ’αžαž€αžΆαžšαžšαž½αž˜αž”αž‰αŸ’αž…αžΌαž›αž”αŸ’αžšαž–αŸαž“αŸ’αž’/αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž€αžΆαžšαž‘αž‘αž½αž›αž™αž€ αž€αžΆαžšαž’αŸ’αžœαžΎαžαŸαžŸαŸ’αžαž•αŸ’αž‘αž»αž€ αž¬αž€αžΆαžšαžαŸ’αžšαž½αžαž–αž·αž“αž·αžαŸ’αž™αž•αŸ’αž‘αžΆαž›αŸ‹αžαŸ’αž›αž½αž“αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαŸ” αžŠαŸ„αž™αžŸαžΆαžš Flagger αž‚αžΊαž‡αžΆαž€αžΆαžšαž”αŸ’αžšαž€αžΆαžŸ αž“αž·αž„αž†αŸ’αž›αžΎαž™αžαž”αž‘αŸ…αž“αžΉαž„αž–αŸ’αžšαžΉαžαŸ’αžαž·αž€αžΆαžšαžŽαŸ Kubernetes αžœαžΆαž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαž“αŸ…αž€αŸ’αž“αž»αž„ GitOps pipelines αžšαž½αž˜αž‡αžΆαž˜αž½αž™αž“αžΉαž„ Weave Flux ឬ αž‡αŸαž“αž‚αžΈαž“. αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž€αŸ†αž–αž»αž„αž”αŸ’αžšαžΎ JenkinsX αž’αŸ’αž“αž€αž’αžΆαž…αžŠαŸ†αž‘αžΎαž„ Flagger αž‡αžΆαž˜αž½αž™ jx addons αŸ”

αž‘αž„αŸ‹αž‡αžΆαžαž·αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‚αžΆαŸ†αž‘αŸ’αžš αž€αžΆαžšαž„αžΆαžšαžαŸ’αž”αžΆαž‰ αž“αž·αž„αž•αŸ’αžαž›αŸ‹αž“αžΌαžœαž€αžΆαžšαžŠαžΆαž€αŸ‹αž–αž„αŸ’αžšαžΆαž™ Canary αž“αŸ…αž€αŸ’αž“αž»αž„ αžαŸ’αž”αžΆαž‰αž–αž–αž€. αž‚αž˜αŸ’αžšαŸ„αž„αž“αŸαŸ‡αž€αŸ†αž–αž»αž„αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŸαžΆαž€αž›αŸ’αž”αž„αž“αŸ…αž›αžΎ GKE, EKS αž“αž·αž„αžŠαŸ‚αž€αž‘αž‘αŸαž‡αžΆαž˜αž½αž™ kubeadm αŸ”

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αžΆαž“αž€αžΆαžšαž•αŸ’αžŠαž›αŸ‹αž™αŸ„αž”αž›αŸ‹αžŠαžΎαž˜αŸ’αž”αžΈαž€αŸ‚αž›αž˜αŸ’αž’ Flagger αžŸαžΌαž˜αž”αž‰αŸ’αž‡αžΌαž“αž”αž‰αŸ’αž αžΆ ឬ PR αž“αŸ…αž›αžΎ GitHub αž“αŸ… Stefanprodan / αž’αŸ’αž“αž€αž”αž„αŸ’αž€αžΎαžαž‘αž„αŸ‹αž‡αžΆαžαž·. αž€αžΆαžšαž…αžΌαž›αžšαž½αž˜αž…αŸ†αžŽαŸ‚αž€αž›αžΎαžŸαž–αžΈαž€αžΆαžšαžŸαŸ’αžœαžΆαž‚αž˜αž“αŸ!

αžŸαŸ’αž‘αŸ’αžšαžΈαž˜ αžšαŸ‰αžΆαž™ αžαžΆαŸ†αž„.

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹