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). Ці об'єкти розкривають додаток у службі 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 та піки затримок реєструються як події 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