CD прызнана ў якасці практыкі карпаратыўнага праграмнага забеспячэння, гэта – вынік натуральнай эвалюцыі ўстояных прынцыпаў CI. Аднак CD па-ранейшаму даволі рэдкая з'ява, магчыма, з-за складанасці кіравання і страху перад няўдалымі дэплоямі, якія ўплываюць на даступнасць сістэмы.
Ніжэй прыведзена пакрокавае кіраўніцтва па наладзе і выкарыстанні 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
Прыведзеная вышэй каманда створыць пул нод па змаўчанні, які ўключае дзве ВМ n1-standard-2
(vCPU: 2, RAM 7,5 GB, дыск: 30 GB). У ідэале варта ізаляваць кампаненты Istio ад сваіх працоўных нагрузак, але простага спосабу запуску подаў Istio у вылучаным пуле нод не існуе. Маніфесты 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 гл.
Пацвердзіце наладкі:
kubectl -n istio-system get svc
Праз некалькі секунд GCP павінен прызначыць вонкавы IP-адрас для сэрвісу istio-ingressgateway
.
Настройка ўваходнага шлюза Istio
Стварыце статычны 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. Дадайце два запісы А (заменіце example.com
на свой дамен):
istio.example.com A ${GATEWAY_IP}
*.istio.example.com A ${GATEWAY_IP}
Пераканайцеся, што падстановачны сімвал DNS працуе:
watch host test.istio.example.com
Стварыце агульны шлюз Istio для прадастаўлення паслуг па-за межамі service mesh па 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, прачытайце, калі ласка,
Ўстаноўка Flagger
Надбудова 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/)
Разгарніце 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 для canary аналізу. Усталюйце 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). Гэтыя аб'екты раскрываюць прыкладанне ў service mesh і кіруюць canary аналізам і прасоўваннем.
Стварыце тэставы неймспейс з уключаным укараненнем 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 аналіз і прасоўванне
Flagger рэалізуе цыкл кіравання, які паступова перамяшчае трафік на canary, адначасова вымяраючы ключавыя паказчыкі прадукцыйнасці, напрыклад, узровень паспяховасці HTTP-запытаў, сярэднюю працягласць запытаў і працаздольнасць пода. На аснове аналізу KPI canary прасоўваецца ці перарываецца, а вынікі аналізу публікуюцца ў Slack.
Canary дэплой запускаецца пры змене аднаго з наступных аб'ектаў:
- Дэплой PodSpec (вобраз кантэйнера, каманда, парты, env і г.д.)
- ConfigMaps мантуюцца як тамы або зменьваюцца ў зменныя асяроддзя
- Сакрэты мантуюцца як тамы або зменьваюцца ў зменныя асяроддзі
Запуск canary дэплою пры абнаўленні выявы кантэйнера:
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 перазапусціць фазу аналізу.
Складзіце спіс усіх «канарэек» у вашым кластары:
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, то атрымаеце паведамленне, калі будзе перавышаны крайні тэрмін выканання ці дасягненні максімальнай колькасці няўдалых праверак падчас аналізаў:
У заключэнне
Запуск service mesh, напрыклад, Istio, у дадатак да Kubernetes падасць аўтаматычныя метрыкі, логі і пратаколы, але дэплой працоўных нагрузак усё яшчэ залежыць ад вонкавых прылад. Flagger імкнецца змяніць гэтую сітуацыю, дадаючы Istio магчымасці
Flagger сумяшчальны з любымі CI/CD-рашэннямі для Kubernetes, і канарэчны аналіз можна лёгка пашырыць з дапамогай
Flagger падтрымліваецца
Калі ў вас ёсць прапановы па паляпшэнні Flagger, калі ласка, адпраўце пытанне ці PR на GitHub па адрасе
Дзякуй
Крыніца: habr.com