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
Фармони боло як ҳавзи гиреҳи пешфарз, аз ҷумла ду VM эҷод мекунад n1-standard-2
(vCPU: 2, RAM 7,5 ГБ, диск: 30 ГБ). Идеалӣ, шумо бояд ҷузъҳои Istio-ро аз сарбории худ ҷудо кунед, аммо роҳи осони иҷро кардани Istio Pods дар ҳавзи махсуси гиреҳҳо вуҷуд надорад. Манифестҳои Истио танҳо барои хондан ҳисобида мешаванд ва 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, нигаред
Танзимотро тасдиқ кунед:
kubectl -n istio-system get svc
Пас аз чанд сония, GCP бояд барои хидмат суроғаи IP-и беруна таъин кунад istio-ingressgateway
.
Танзими Gateway Istio Ingress
Суроғаи 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
Барои пешниҳоди хидматҳо берун аз шабакаи хидматрасонӣ тавассути HTTP як шлюзи умумии Istio эҷод кунед:
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 бо менеҷери сертификат, CloudDNS ва Let's Encrypt, лутфан хонед
Насбкунии Flagger
Иловаи GKE Istio намунаи Prometheus-ро дар бар намегирад, ки хидмати телеметрии Istio-ро тоза мекунад. Азбаски Flagger барои анҷом додани таҳлили канарӣ метрикаи Istio HTTP-ро истифода мебарад, шумо бояд конфигуратсияи зерини 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 барои таҳлили канария мебошад. 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
Графанаро тавассути як дарвозаи кушода тавассути эҷоди хидмати виртуалӣ фош кунед (иваз 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) эҷод мекунад. Ин объектҳо барномаро ба шабакаи хидматрасонӣ фош мекунанд ва таҳлил ва пешрафти канаро назорат мекунанд.
Фазои номи санҷиширо бо тазриқи 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
Барои тавлиди трафик ҳангоми таҳлили канария хидмати боркунии санҷиширо ҷобаҷо кунед:
helm upgrade -i flagger-loadtester flagger/loadtester
--namepace=test
Захираи махсуси канарияро эҷод кунед (иваз кунед 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-ро тафтиш мекунад. Шумо метавонед бо истифода аз формулаи зерин вақти ҳадди ақалро барои тасдиқ ва пешбурди ҷойгиркунии канария муайян кунед: interval * (maxWeight / stepWeight)
. Майдонҳои Canary CRD ҳуҷҷатгузорӣ карда шудаанд
Пас аз чанд сония, Flagger объектҳои канариро эҷод мекунад:
# 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
, шумо бояд рақами версияро бинед
Таҳлили худкори канария ва таблиғ
Flagger як ҳалқаи назоратро амалӣ мекунад, ки трафикро тадриҷан ба канария интиқол медиҳад ва ҳангоми чен кардани ченакҳои калидии иҷроиш ба монанди суръати муваффақияти дархости HTTP, давомнокии миёнаи дархост ва саломатии поддонҳо. Дар асоси таҳлили KPI, канария пешбарӣ ё қатъ карда мешавад ва натиҷаҳои таҳлил дар 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
Ҳангоми таҳлил натиҷаҳои канариро тавассути Grafana пайгирӣ кардан мумкин аст:
Лутфан таваҷҷӯҳ намоед, ки агар дар ҷараёни таҳлили канария тағйироти нав ба ҷойгиркунӣ татбиқ карда шаванд, 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-ро фаъол карда бошед, шумо паёмҳои зеринро хоҳед гирифт:
Бозгашти худкор
Ҳангоми таҳлили канарӣ, шумо метавонед хатогиҳои синтетикии 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
Вақте ки шумораи санҷишҳои ноком ба ҳадди ниҳоӣ мерасад, трафик ба канали ибтидоӣ бармегардад, канарӣ ба сифр баробар мешавад ва ҷойгиркунӣ ҳамчун ноком қайд карда мешавад.
Хатогиҳои канарӣ ва таъхирҳои таъхир ҳамчун рӯйдодҳои 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 мувофиқ аст ва таҳлили канариро бо осонӣ васеъ кардан мумкин аст.
Flagger дастгирӣ карда мешавад
Агар шумо барои беҳтар кардани Flagger пешниҳоде дошта бошед, лутфан масъала ё PR-ро дар GitHub ирсол кунед
Спасибо
Манбаъ: will.com