Разгортванне прыкладанняў на некалькіх кластарах Kubernetes з Helm
Як Dailymotion выкарыстоўвае Kubernetes: разгортванне прыкладанняў
Мы ў Dailymotion пачалі выкарыстоўваць Kubernetes у прадакшэне 3 гады таму. Але разгортваць прыкладанні на некалькіх кластарах тое яшчэ задавальненне, таму ў апошнія некалькі гадоў мы імкнуліся палепшыць нашы інструменты і працоўныя працэсы.
З чаго пачалося
Тут мы раскажам, як мы разгортваем нашы прыкладанні на некалькіх кластарах Kubernetes па ўсім свеце.
Каб разгарнуць некалькі аб'ектаў Kubernetes зараз, мы выкарыстоўваем шлем, і ўсе нашы чарты захоўваюцца ў адным рэпазітары git. Каб разгарнуць поўны стэк прыкладанні з некалькіх сэрвісаў, мы выкарыстоўваем так званы абагульняючы чарт. Па сутнасці, гэта чарт, які аб'яўляе залежнасці і дазваляе ініцыялізаваць API і яго сэрвісы адной камандай.
Яшчэ мы напісалі невялікі скрыпт Python па-над Helm, каб рабіць праверкі, ствараць чарты, дадаваць сакрэты і разгортваць прыкладанні. Усе гэтыя задачы выконваюцца на цэнтральнай платформе CI з дапамогай выявы docker.
Пяройдзем да сутнасці.
Заўвага. Калі вы гэта праглядаеце, першы рэліз-кандыдат Helm 3 ужо быў абвешчаны. Асноўная версія змяшчае цэлы набор паляпшэнняў, закліканых вырашыць некаторыя праблемы, з якімі мы сутыкаліся ў мінулым.
Рабочы працэс распрацоўкі чартаў
Для прыкладанняў мы выкарыстоўваем галінаванне, і гэты ж падыход вырашылі прымяніць да чартам.
Галіна DEV выкарыстоўваецца для стварэння чартаў, якія будуць тэсціравацца на кластарах распрацоўкі.
Калі пул-рэквест перадаецца ў майстар, яны правяраюцца ў стэйджынгу.
Нарэшце, мы ствараем пул-рэквест, каб перадаць змены ў галіну prod і прымяніць іх у прадакшэне.
У кожнага асяроддзя ёсць свой прыватны рэпазітар, які захоўвае нашы чарты, і мы выкарыстоўваем Chartmuseum з вельмі карыснымі API. Такім чынам мы гарантуем строгую ізаляцыю паміж асяроддзямі і праверку чартаў у рэальных умовах, перш чым выкарыстоўваць іх у прадакшэне.
Рэпазітары чартаў у розных асяроддзях
Варта адзначыць, што калі распрацоўшчыкі адпраўляюць галіну dev, версія іх чарта аўтаматычна адпраўляецца ў dev Chartmuseum. Такім чынам усе распрацоўнікі выкарыстоўваюць адзін рэпазітар dev, і трэба ўважліва паказваць сваю версію чарта, каб выпадкова не выкарыстоўваць чые-небудзь змены.
Больш за тое, наш невялікі скрыпт Python правярае аб'екты Kubernetes па спецыфікацыях Kubernetes OpenAPI з дапамогай Kubeval, перш чым апублікаваць іх у Chartmusem.
Агульнае апісанне працоўнага працэсу распрацоўкі чарта
Настройка задач пайплайна па спецыфікацыі gazr.io для кантролю якасці (lint, unit-test).
Адпраўка выявы docker з інструментамі Python, якія разгортваюць нашы прыкладання.
Настройка асяроддзя па імені галіны.
Праверка файлаў yaml Kubernetes з дапамогай Kubeval.
Аўтаматычнае павелічэнне версіі чарта і яго бацькоўскіх чартаў (чартаў, якія залежаць ад змянянага чарта).
Адпраўка чарта ў Chartmuseum, які адпавядае яго асяроддзі
Упраўленне адрозненнямі ў кластарах
Федэрацыя кластараў
Быў час, калі мы выкарыстоўвалі федэрацыю кластараў Kubernetes, дзе можна было аб'яўляць аб'екты Kubernetes з адной канчатковай кропкі API. Але ўзніклі праблемы. Напрыклад, некаторыя аб'екты Kubernetes нельга было стварыць у канчатковым пункце федэрацыі, таму было складана абслугоўваць аб'яднаныя аб'екты і іншыя аб'екты для асобных кластараў.
Каб вырашыць праблему, мы сталі кіраваць кластарамі незалежна, што значна спрасціла працэс (выкарыстоўвалі першую версію federation; у другой нешта магло памяняцца).
Геаразмеркаваная платформа
Цяпер наша платформа размеркавана па 6 рэгіёнах - 3 лакальна і 3 у воблаку.
Размеркаванае разгортванне
Глабальныя значэнні Helm
4 глабальных значэння Helm дазваляюць вызначаць адрозненні паміж кластарамі. Для ўсіх нашых чартаў ёсць мінімальныя значэнні па змаўчанні.
Гэтыя значэнні дапамагаюць вызначыць кантэкст для нашых прыкладанняў і выкарыстоўваюцца для розных задач: маніторынг, трасіроўка, лагіраванне, здзяйсненне знешніх выклікаў, маштабаванне і г.д.
cloud: у нас ёсць гібрыдная платформа Kubernetes. Напрыклад, наш API разгортваецца ў зонах GCP і ў нашых датацэнтрах.
"env": некаторыя значэнні могуць змяняцца для непрацоўных асяроддзяў. Напрыклад, вызначэнні рэсурсаў і канфігурацыі аўтамаштабавання.
"region": гэтая інфармацыя дапамагае вызначаць размяшчэнне кластара і можа выкарыстоўвацца для вызначэння бліжэйшых канчатковых кропак для знешніх сэрвісаў.
"clusterName": калі і калі мы хочам вызначыць значэнне для асобнага кластара.
Вось канкрэтны прыклад:
{{/* Returns Horizontal Pod Autoscaler replicas for GraphQL*/}}
{{- define "graphql.hpaReplicas" -}}
{{- if eq .Values.global.env "prod" }}
{{- if eq .Values.global.region "europe-west1" }}
minReplicas: 40
{{- else }}
minReplicas: 150
{{- end }}
maxReplicas: 1400
{{- else }}
minReplicas: 4
maxReplicas: 20
{{- end }}
{{- end -}}
Прыклад шаблону Helm
Гэтая логіка вызначана ў дапаможным шаблоне, каб не засмечваць Kubernetes YAML.
Аб'ява прыкладання
Нашы інструменты разгортвання заснаваны на некалькіх файлах YAML. Ніжэй прыведзены прыклад таго, як мы аб'яўляем сэрвіс і яго тапалогію маштабавання (колькасць рэплік) у кластары.
Мы вызначылі агульныя правілы, якім неабходна прытрымлівацца пры запісе сакрэтаў у Vault.
Калі сакрэт адносіцца да пэўнага кантэксту або кластара, трэба дадаць канкрэтны запіс. (Тут у кантэксту cluster1 ёсць уласнае значэнне для сакрэту stack-app1-password).
У адваротным выпадку выкарыстоўваецца значэнне па змаўчанні.
Для кожнага пункта ў гэтым спісе ў сакрэт Kubernetes устаўляецца пара ключ-значэнне. Таму шаблон сакрэту ў нашых чартах вельмі просты.
Цяпер мы падзяляем распрацоўку чартаў і прыкладанняў. Гэта значыць, што распрацоўнікам даводзіцца працаваць у двух рэпазітарах git: адзін для прыкладання, а другі - для вызначэння яго разгортвання ў Kubernetes. 2 рэпазітара git - гэта 2 працоўных працэсу, і пачаткоўцу лёгка заблытацца.
Кіраваць абагульненымі чартамі клапотна
Як мы ўжо казалі, абагульненыя чарты вельмі зручныя для вызначэння залежнасцяў і хуткага разгортвання некалькіх прыкладанняў. Але мы выкарыстоўваем --reuse-values, Каб пазбегнуць перадачы ўсіх значэнняў кожны раз, калі мы разгортваем прыкладанне, якое ўваходзіць у гэты абагульнены чарт.
У працоўным працэсе бесперапыннай пастаўкі ў нас усяго два значэнні, якія мяняюцца рэгулярна: колькасць рэплік і тэг выявы (версія). Іншыя, больш стабільныя значэнні, мяняюцца ўручную, і гэта даволі складана. Больш за тое, адна памылка ў разгортванні абагульненага чарта можа прывесці да сур'ёзных збояў, як мы пераканаліся на ўласным досведзе.
Абнаўленне некалькіх файлаў канфігурацыі
Калі распрацоўшчык дадае новае прыкладанне, яму даводзіцца змяняць некалькі файлаў: аб'ява прыкладання, спіс сакрэтаў, даданне прыкладання ў залежнасці, калі яно ўваходзіць у абагульнены чарт.
Дазволы Jenkins занадта пашыраны ў Vault
Цяпер у нас ёсць адзін AppRole, які чытае ўсе сакрэты з Vault.
Працэс адкату не аўтаматызаваны
Для адкату трэба выканаць каманду на некалькіх кластарах, а гэта багата памылкамі. Мы выконваем гэтую аперацыю ўручную, каб гарантавана пазначыць правільны ідэнтыфікатар версіі.
Мы рухаемся ў бок GitOps
Наша мэта
Мы хочам вярнуць чарт у рэпазітар прыкладання, якое ён разгортвае.
Рабочы працэс будзе такім жа, як для распрацоўкі. Напрыклад, калі галіна адпраўляецца ў майстар, разгортванне будзе запускацца аўтаматычна. Асноўная розніца паміж такім падыходам і бягучым працоўным працэсам будзе ў тым, што усё будзе кіравацца ў git (само прыкладанне і спосаб яго разгортвання ў Kubernetes).
Пераваг некалькі:
Значна больш зразумела для распрацоўшчыка. Прасцей навучыцца прымяняць змены ў лакальным чарце.
Вызначэнне разгортвання службы можна ўказаць там жа, дзе код службы.
Кіраванне выдаленнем абагульненых чартаў. У сервісу будзе свой выпуск Helm. Гэта дазволіць кіраваць жыццёвым цыклам прыкладання (адкат, апгрэйд) на драбнюткім узроўні, каб не закранаць іншыя сэрвісы.
Перавагі git для кіравання чартамі: адмена змен, часопіс аўдыту і т. д. Калі трэба адмяніць змену чарта, гэта можна зрабіць з дапамогай git. Разгортванне запускаецца аўтаматычна.
Можна падумаць аб удасканаленні працоўнага працэсу распрацоўкі з дапамогай такіх прылад, як Скафот, з якім распрацоўшчыкі могуць тэсціраваць змены ў кантэксце, набліжаным да прадакшэну.
Двухэтапная міграцыя
Нашы распрацоўшчыкі выкарыстоўваюць гэты працоўны працэс ужо 2 гады, так што нам патрэбна максімальна бязбольная міграцыя. Таму мы вырашылі дадаць прамежкавы этап на шляху да мэты.
Першы этап просты:
Мы захоўваем падобную структуру для налады разгортвання прыкладанняў, але ў адным аб'екце з імем DailymotionRelease.
Мы пагаварылі з усімі распрацоўшчыкамі, так што працэс міграцыі ўжо пачаўся. Першы этап па-ранейшаму кантралюецца з выкарыстаннем платформы CI. Хутка я напішу яшчэ адзін пост аб другім этапе: як мы перайшлі на працоўны працэс GitOps з Паток. Я раскажу, як мы ўсе настроілі і з якімі цяжкасцямі сутыкнуліся (некалькі рэпазітараў, сакрэты і г. д.). Сачыце за навінамі.
Тут мы паспрабавалі апісаць наш прагрэс у працоўным працэсе разгортвання прыкладанняў за апошнія гады, які прывёў да думак аб падыходзе GitOps. Мы яшчэ не дасягнулі мэты і будзем паведамляць аб выніках, але зараз перакананыя, што правільна зрабілі, калі вырашылі ўсё спрасціць і наблізіць да звычак распрацоўшчыкаў.