Ще използваме Gitlab CI и ръчен GitOps за внедряване и използване на Canary внедряване в Kubernetes

Статиите от този цикъл:
- (тази статия)
- Canary внедряване с помощта на Istio
- Canary внедряване с помощта на Jenkins-X Istio Flagger
Ще извършваме Canary внедряване ръчно чрез GitOps и създаване/промяна на основните ресурси на Kubernetes. Тази статия е предназначена предимно за запознаване с начина, по който работи Canary внедряването в Kubernetes, тъй като има по-ефективни методи за автоматизация, които ще разгледаме в следващите статии.

Canary разгръщане
При стратегията за Canary обновление новите версии се прилагат първо само за част от потребителите. Чрез мониторинг, данни от логовете, ръчно тестване или други канали за обратна връзка, релизът се тества преди да бъде приложен за всички потребители.
Kubernetes внедряване (rolling update)
Стратегията по подразбиране за внедряване в Kubernetes е rolling-update, при която се стартира определен брой подове с нови версии на образите. Ако те са създадени без проблеми, старите версии на подовете се завършват, а новите подове се създават паралелно.
GitOps
В това примера използваме GitOps, тъй като:
- използваме Git като единственият източник на истина
- използваме Git операции за изграждане и внедряване (не са нужни команди освен git tag/merge)
Пример
Да вземем добра практика — да имаме един репозиторий за код на приложения и един за инфраструктура.
Репозиторий за приложения
Това е много прост API на Python+Flask, който връща отговор във формат JSON. Ще изградим пакета чрез GitlabCI и ще пуснем резултата в Gitlab Registry. В регистрат ни имаме две различни версии на релизите:
wuestkamp/k8s-deployment-example-app:v1wuestkamp/k8s-deployment-example-app:v2
Единствената разлика между тях е промяната на връщания JSON файл. Използваме това приложение за максимално проста визуализация на версията, с която взаимодействаме.
Инфраструктурен репозиторий
В този репозиторий ще внедряваме чрез GitlabCI в Kubernetes, .gitlab-ci.yml изглежда следния начин:
image: traherom/kustomize-docker
before_script:
- printenv
- kubectl version
stages:
- deploy
deploy test:
stage: deploy
before_script:
- echo $KUBECONFIG
script:
- kubectl get all
- kubectl apply -f i/k8s
only:
- master
За да го стартирате самостоятелно, ще ви е необходим клъстер, можете да използвате Gcloud:
gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b
gcloud compute firewall-rules create incoming-80 --allow tcp:80Трябва да направите форк и да създадете променлива KUBECONFIG в GitlabCI, която ще съдържа конфигурация за достъп kubectl до вашия клъстер.
Как да получите идентификационни данни за кластера (Gcloud) можете да прочетете .
Инфраструктурен Yaml
В инфраструктурния репозиторий имаме service:
apiVersion: v1
kind: Service
metadata:
labels:
id: app
name: app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
id: app
type: LoadBalancerИ внедряване в deploy.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
selector:
matchLabels:
id: app
type: main
template:
metadata:
labels:
id: app
type: main
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
name: app
resources:
limits:
cpu: 100m
memory: 100MiИ още един deployment в deploy-canary.yaml:
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 0
selector:
matchLabels:
id: app
type: canary
template:
metadata:
labels:
id: app
type: canary
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
name: app
resources:
limits:
cpu: 100m
memory: 100MiОбърнете внимание, че app-deploy в момента няма определени реплики.
Изпълнение на началния деплой
За да стартирате началния deployment, можете да стартирате GitlabCI pipeline ръчно в master клона. След това kubectl трябва да изведе следното:

Виждаме app deployment с 10 реплики и app-canary с 0. Има също LoadBalancer, от който можем да се свързваме чрез curl чрез External IP:
while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

Виждаме, че нашето тестово приложение връща само “v1”.
Изпълнение на Canary деплоя
Стъпка 1: пускане на нова версия за част от потребителите
Настроихме броя на репликите на 1 в файл deploy-canary.yaml и изображението на новата версия:
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1
selector:
matchLabels:
id: app
type: canary
template:
metadata:
labels:
id: app
type: canary
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
name: app
resources:
limits:
cpu: 100m
memory: 100MiВ файла deploy.yaml премахнахме броя на репликите до 9:
kind: Deployment
metadata:
name: app
spec:
replicas: 9
selector:
matchLabels:
id: app
...Тласкаме тези промени в репозитория, от който ще се стартира деплой (чрез GitlabCI) и накрая виждаме:

Нашият Service ще сочи към двата деплоя, тъй като и двата имат селектор app. Поради случайното разпределение по подразбиране в Kubernetes, трябва да видим различни отговори на ~ 10% от запитванията:

Настоящото състояние на нашето приложение (GitOps, взето от Git като Single Source Of Truth) е наличието на два deployments с активни реплики, по един за всяка версия.
~10% от потребителите се запознават с новата версия и неволно я тестват. Сега е време да проверим наличието на грешки в логовете и данните за мониторинг за откриване на проблеми.
Стъпка 2: пускане на нова версия за всички потребители
Решихме, че всичко е минало добре и сега трябва да развием новата версия за всички потребители. За целта просто актуализираме deploy.yaml инсталирайки новата версия на изображението и броя на репликите, равен на 10. В deploy-canary.yaml Ние задаваме броя на репликите на обратно 0. След деплой резултатът ще бъде следният:

В обобщение
За мен стартирането на деплоя ръчно по този начин помага да разбера как лесно може да се конфигурира с помощта на k8s. Тъй като Kubernetes позволява актуализации чрез API, тези стъпки могат да бъдат автоматизирани чрез скриптове.
Още една неща, която трябва да реализираме, е точката за достъп на тестера (LoadBalancer или чрез Ingress), през която може да се получи достъп само до новата версия. Тя може да бъде използвана за ръчен преглед.
В следващите статии ще разгледаме други автоматизирани решения, които реализират повечето от това, което направихме.
Също така прочетете и други статии в нашия блог:
Източник: habr.com
