αααΈααΈααααΌαααΆαααα½αααααΆααααΆααΆααΆαα’αα»αααααααααα·ααΈαα ααααΆα α αΎαααΆααααααααααΆααα·ααααααααααααΆαα·αααααααΆααα CI αααααΆααααααΎαα‘αΎαα ααααααΆαααΆααααα αααΈααΈαα ααααααααΆαα αααα ααααΆαααααΆαααααΆααααα»αααααΆαααααΆαααααααααα αα·αααΆααααααααΆα ααααΆαααΆαααααααΆαααααααΆααα ααααααααΆαααααααΆαα’αΆα ααααΆαααααααααααα
ααΆαααααααααααΊααΆααΆαααααΆαααΆααα αΆαααααα»αααΆαααα‘αΎα αα·αααααΎααααΆαα 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
ααΆααααααααΆααΆαααΎααΉααααααΎααααα»αααααΆααααααΆαααΎα αα½αααΆαα 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 α₯α‘αΌααααααααΆααααααΆαααααααα
αααααΎαααααΈααααΆαααα αα·αααΆαα ααα½ααΆααΈααΆαααα»ααααααΆαα 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 α αααααΆααααααααΆαααααααα’αααΈααΆαααΆαααΆαααΆαααα‘αΎααα½ααα»ααααα·ααΆαααααα’ααα ααΌαααΎα
αααααΆααααΆααααααα
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 ααΌαα’αΆα
ααΆαααα‘αΎαααα
αααααα·ααΈαααααα 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)α ααααα»ααΆαααααααΆααααααΆααααααα·ααΈαα αααααΆαααααΆ αα·ααααααααααααΆααα·ααΆα αα·ααααααααΆαα
αααααΎαβααα βαααααβααΆαααααβααΆαα½αβααΉαβααΆαβα αΆαα 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 ααααΌαααΆαααααα‘αΎα αα ααααααααααα»αα½ααααα»αα ααααααααα»ααΆααααααααααΆααααααΌαα
- ααΆαααααααΆα 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 ααΉαα αΆααααααΎαααααΆααααΆααα·ααΆαα‘αΎααα·αα
ααααΎαααααΈ 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 α’αααα’αΆα αααααΎαααα α»α 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 α’αααααΉαααα½αααΆαααΆααα½ααα ααααααα α½αααααα α¬α ααα½αα’αα·ααααΆααααΆααααα½ααα·αα·αααααααααΆααααααα»αααΆααα·ααΆαααααΌαααΆαααΆααααα
αα αααα»αααα ααααΈααααα·ααααΆα
ααΆαααααΎαααΆααααααΆαααααΆααΌα
ααΆ Istio ααααααααΎ Kubernetes ααΉααααααααΌαααΆαααΆααααα αααααα ααα» αα·ααα·ααΈααΆααααααααααααααααα· ααα»ααααααΆαααΆαααααααΆαααααα»αααΆαααΆααα
ααα’αΆαααααααΎα§αααααααΆααααα
α Flagger ααΆαααααααααΆααααααΌαααΆααααααααααααααααΆα Istio
Flagger ααΊααααΌαααααΆααΆαα½ααααααααααΆα Kubernetes CI/CD ααΆαα½α α αΎαααΆααα·ααΆα Canary α’αΆα
ααααΌαααΆααααααΈααααΆαααΆααααα½αααΆαα½α
αααααΆαα·ααααΌαααΆαααΆαααα
ααααα·αααΎα’αααααΆαααΆαααααααααααααΎααααΈαααααα’ Flagger ααΌααααααΌααααα αΆ α¬ PR αα
ααΎ GitHub αα
ααααααΈα
ααααα: www.habr.com