Наші висновки за рік міграції GitLab.com на Kubernetes

Прим. перев.: адаптацію Kubernetes у GitLab вважають одним із двох головних факторів, що сприяють зростанню компанії. Тим не менш, донедавна інфраструктура онлайн-сервісу GitLab.com була побудована на віртуальних машинах, і лише близько року тому почалася її міграція до K8s, яка досі не завершена. Раді подати переклад недавньої статті SRE-інженера GitLab про те, як це відбувається і які висновки роблять інженери, які беруть участь у проекті.

Наші висновки за рік міграції GitLab.com на Kubernetes

Ось вже близько року наш інфраструктурний підрозділ займається міграцією всіх сервісів, що працюють на GitLab.com, Kubernetes. За цей час ми зіткнулися з проблемами, пов'язаними не лише з переміщенням сервісів у Kubernetes, але й з керуванням гібридним deployment'ом під час переходу. Про цінні уроки, отримані нами, і йтиметься у цій статті.

З самого початку GitLab.com його сервери працювали у хмарі на віртуальних машинах. Цими віртуальними машинами управляє Chef, а їх установка відбувається за допомогою нашого офіційного Linux-пакету. Стратегія розгортання на випадок, якщо потрібно оновити програму, полягає у простому оновленні парку серверів скоординованим послідовним чином за допомогою CI-пайплайну. Цей метод - нехай повільний і трішки нудний — гарантує, що GitLab.com застосовує ті ж самі способи встановлення та конфігурування, що й користувачі автономних. (self-managed) інсталяцій GitLab, які використовують для цього наші Linux-пакети.

Ми використовуємо такий метод, оскільки надзвичайно важливо відчути на собі усі суми та радості, які відчувають пересічні представники спільноти, коли встановлюють та налаштовують свої копії GitLab. Цей підхід добре працював протягом деякого часу, однак коли кількість проектів на GitLab перевищила 10 млн, ми зрозуміли, що він більше не задовольняє нашим потребам у масштабуванні та розгортанні.

Перші кроки до Kubernetes та cloud-native GitLab

2017-го було створено проект GitLab Charts для підготовки GitLab до розгортання у хмарі, а також для того, щоб дати користувачам можливість встановлювати GitLab у кластери Kubernetes. Тоді ми знали, що перенесення GitLab у Kubernetes збільшить можливості масштабування SaaS-платформи, спростить розгортання та підвищить ефективність використання обчислювальних ресурсів. У той же час багато функцій нашої програми залежали від примонтованих NFS-розділів, що уповільнювало перехід із віртуальних машин.

Прагнення до cloud native і Kubernetes дозволило нашим інженерам планувати поступовий перехід, в ході якого ми відмовилися від деяких залежностей програми від мережевих сховищ, принагідно продовжуючи розробляти нові функції. З того часу, як ми почали планувати міграцію влітку 2019-го, багато з цих обмежень було усунуто, і процес перекладу GitLab.com на Kubernetes тепер триває повним ходом!

Особливості роботи GitLab.com у Kubernetes

Для GitLab.com ми використовуємо єдиний регіональний кластер GKE, який обробляє весь трафік програми. Щоб мінімізувати складність (без того хитромудрої) міграції, ми концентруємося на сервісах, які не залежать від локального сховища або NFS. GitLab.com використовує переважно монолітну кодову базу на Rails, і ми спрямовуємо трафік залежно від характеристик робочого навантаження на різні endpoint'и, ізольовані у власні пули вузлів.

У випадку фронтенду ці типи поділяються на запити до web, API, GIT SSH/HTTPS та Registry. У випадку бекенда ми розбиваємо job'и у черзі за різними характеристиками залежно від зумовлених меж ресурсівякі дозволяють нам встановлювати цільові показники рівня обслуговування (Service-Level Objectives, SLOs) для різних навантажень.

Всі ці сервіси GitLab.com налаштовані за допомогою немодифікованого Helm-GartLab. Конфігурація проводиться в субчартах, які можуть бути вибірково включені в міру того, як ми поступово переносимо послуги кластеру. Навіть з огляду на те, що було вирішено не включати в міграцію деякі з наших stateful-сервісів, такі як Redis, Postgres, GitLab Pages і Gitaly, використання Kubernetes дозволяє радикально скоротити число VM, якими керує Chef в даний час.

Прозорість та керування конфігурацією Kubernetes

Всі налаштування управляються самим GitLab'ом. Для цього використовуються три конфігураційні проекти на основі Terraform і Helm. Ми намагаємося всюди по можливості використовувати сам GitLab для запуску GitLab'у, але для експлуатаційних завдань у нас функціонує окрема інсталяція GitLab. Вона потрібна для того, щоб не залежати від доступності GitLab.com під час проведення розгортань та оновлень GitLab.com.

Хоча наші пайплайни для кластера Kubernetes працюють на окремій інсталяції GitLab, є у репозиторіїв коду є дзеркала, публічно доступні за такими адресами:

  • k8s-workloads/gitlab-com конфігураційна обв'язка GitLab.com для Helm-чарта GitLab;
  • k8s-workloads/gitlab-helmfiles містить конфігурації для сервісів, які не пов'язані з додатком GitLab безпосередньо. До них входять конфігурації для ведення логів та моніторингу кластера, а також для інтегрованих інструментів на зразок PlantUML;
  • Gitlab-com-infrastructure - Конфігурація Terraform для Kubernetes та старої (legacy) VM-інфраструктури. Тут налаштовуються всі ресурси, необхідних запуску кластера, включаючи сам кластер, пули вузлів, облікові записи служб, резервування IP-адрес.

Наші висновки за рік міграції GitLab.com на Kubernetes
При внесенні змін з'являється загальнодоступне коротке резюме з посиланням на докладний diff, який SRE аналізує перед внесенням змін до кластера.

Для SRE посилання веде докладний diff в інсталяції GitLab, яка використовується для експлуатації та доступ до якої обмежений. Це дозволяє співробітникам та спільноті без доступу до експлуатаційного проекту (він відкритий лише для SRE) переглядати запропоновані зміни у конфігурації. Поєднуючи загальнодоступний екземпляр GitLab'а для коду із закритим екземпляром для CI-пайплайнів, ми зберігаємо єдиний робочий процес, водночас гарантуючи незалежність від GitLab.com під час оновлень конфігурації.

Що ми з'ясували під час міграції

У процесі переїзду був накопичений досвід, який ми застосовуємо до нових міграцій та deployment'ів у Kubernetes.

1. Зростання витрат через трафіку між зонами доступності

Наші висновки за рік міграції GitLab.com на Kubernetes
Щоденна egress-статистика (байт на добу) парком Git-сховищ на GitLab.com

Google поділяє свою мережу на регіони. Ті, своєю чергою, розбиваються на зони доступності (AZ). Git-хостинг пов'язаний з великими обсягами даних, тому нам важливо контролювати мережевий egress. У випадку внутрішнього трафіку egress безкоштовний тільки в тому випадку, якщо він залишається в межах однієї зони доступності. На момент написання цієї статті ми віддаємо приблизно 100 Тб даних у звичайний робочий день (і це лише для Git-репозиторіїв). Сервіси, які в нашій старій топології, заснованій на VM, знаходилися на тих самих віртуальних машинах, тепер працюють у різних pod'ах Kubernetes. Це означає, що частина трафіку, яка раніше була локальною для VM, може потенційно виходити за межі зон доступності.

Регіональні кластери GKE дозволяють охоплювати декілька зон доступності для резервування. Ми розглядаємо можливість розділити регіональний кластер GKE на однозонні кластери для сервісів, що генерують великі обсяги трафіку. Це дозволить скоротити витрати на egress за збереження резервування лише на рівні кластера.

2. Limit'и, request'и ресурсів та масштабування

Наші висновки за рік міграції GitLab.com на Kubernetes
Число реплік, що обробляють production-трафік на registry.gitlab.com. Трафік досягає свого піку о 15:00 UTC.

Наша історія з міграцією розпочалася у серпні 2019-го, коли ми перенесли перший сервіс – реєстр контейнерів GitLab (GitLab Container Registry) – у Kubernetes. Цей критично важливий сервіс з високим трафіком добре підійшов для першої міграції, оскільки є stateless-додаток з малим числом зовнішніх залежностей. Першою проблемою, з якою ми зіткнулися, стала велика кількість витіснених pod'ів через брак пам'яті на вузлах. Через це нам довелося змінювати request'и та limit'и.

Було виявлено, що у випадку додатка, у якого споживання пам'яті зростає з часом, низькі значення для request'ів (що резервують пам'ять для кожного pod'а) разом з «щедрим» жорстким limit'ом на використання приводили до насичення (saturation) вузлів та високого рівня витіснення. Щоб упоратися з цією проблемою, було вирішено збільшити request'и та знизити limit'и. Це зняло тиск із вузлів та забезпечило життєвий цикл pod'ів, який не чинив надто високого тиску на вузол. Тепер ми починаємо міграції зі щедрими (і майже однаковими) значеннями request'ів та limit'ів, коригуючи їх за потребою.

3. Метрики та логи

Наші висновки за рік міграції GitLab.com на Kubernetes
Інфраструктурний підрозділ фокусується на затримках, відсотку помилок та сатурації із встановленими цілями за рівнем обслуговування (SLO), прив'язаними до загальної доступності нашої системи.

За минулий рік однією з ключових подій в інфраструктурному підрозділі стали покращення в моніторингу та роботі зі SLO. SLO дозволили нам встановлювати цілі щодо окремих сервісів, за якими ми уважно стежили під час міграції. Але навіть з такою покращеною спостерігальністю не завжди можна відразу побачити проблеми, використовуючи метрики та алерти. Наприклад, зосередившись на затримках і відсотку помилок, ми повністю охоплюємо всі сценарії використання сервісу, що проходить міграцію.

Ця проблема була виявлена ​​майже відразу після перенесення частини робочих навантажень у кластер. Особливо гостро вона заявила про себе, коли довелося перевіряти функції, кількість запитів до яких невелика, але які мають дуже специфічні конфігураційні залежності. Одним із ключових уроків за підсумками міграції стала необхідність враховувати при моніторингу не лише метрики, але також логи та «довгий хвіст» (мова йде про такому їх розподілі на графіці - прим. перев.) помилок. Тепер для кожної міграції ми включаємо детальний перелік запитів до логів. (log queries) та плануємо чіткі процедури відкату, які у разі виникнення проблем можна передавати від однієї зміни до іншої.

Паралельне обслуговування одних і тих же запитів на старій VM-інфраструктурі та новій, заснованій на Kubernetes, було унікальним завданням. На відміну від міграції типу lift-and-shift (швидке перенесення додатків «як є» в нову інфраструктуру; докладніше можна прочитати, наприклад, тут - прим. перев.), паралельна робота на «старих» VM та Kubernetes вимагає, щоб інструменти для моніторингу були сумісні з обома середовищами та вміли об'єднувати метрики в один вид. Важливо, що ми використовуємо одні й ті ж dashboard'и та запити до логів, щоб досягти узгодженої спостерігальності під час перехідного періоду.

4. Перемикання трафіку на новий кластер

Для GitLab.com частина серверів виділяється під канаркову (canary) стадію. Канарковий парк обслуговує наші внутрішні проекти, а також може включатися користувачами. Але в першу чергу він призначений для перевірки змін, що вносяться в інфраструктуру та додаток. Перший перенесений сервіс почав з прийому обмеженого обсягу внутрішнього трафіку, і ми продовжуємо використовувати цей метод, щоб переконатися у дотриманні SLO перед тим, як направити весь трафік кластеру.

У разі міграції це означає, що спочатку в Kubernetes надсилаються запити до внутрішніх проектів, а потім ми поступово переключаємо на кластер решту трафіку шляхом зміни ваги для бекенду через HAProxy. У процесі переходу з VM на Kubernetes стало зрозуміло, що дуже вигідно мати в запасі простий спосіб перенаправлення трафіку між старою та новою інфраструктурою і, відповідно, тримати стару інфраструктуру напоготові для відкату в перші кілька днів після міграції.

5. Резервні потужності pod'ів та їх використання

Майже відразу було виявлено наступну проблему: pod'и для сервісу Registry стартували швидко, проте запуск pod'ів для Sidekiq займав до двох хвилин. Тривалий запуск pod'ів для Sidekiq став проблемою, коли ми розпочали міграцію в Kubernetes робочих навантажень для worker'ів, яким потрібно швидко обробляти job'и та швидко масштабуватися.

У даному випадку урок полягав у тому, що хоча Horizontal Pod Autoscaler (HPA) у Kubernetes добре справляється зі зростанням трафіку, важливо брати до уваги характеристики робочих навантажень і виділяти резервні потужності pod'ів (особливо в умовах нерівномірного розподілу попиту). У нашому випадку спостерігався раптовий сплеск job'ів, що спричиняє стрімке масштабування, що призводило до насичення ресурсів CPU до того, як ми встигали масштабувати пул вузлів.

Завжди є спокуса якомога більше «вичавити» з кластера, проте ми, спочатку зіткнувшись із проблемами з продуктивністю, тепер починаємо з щедрого pod budget'а і зменшуємо його згодом, уважно стежачи за SLO. Запуск pod'ів для сервісу Sidekiq значно прискорився і тепер загалом займає близько 40 секунд. Від скорочення часу запуску pod'ів виграв як GitLab.com, так і наші користувачі інсталяцій self-managed, які працюють з офіційним Helm-чартом GitLab.

Висновок

Після перенесення кожного сервісу ми раділи перевагам використання Kubernetes у production: більш швидкому та безпечному деплою програми, масштабуванню та ефективнішому розподілу ресурсів. Причому плюси міграції виходять за межі сервісу GitLab.com. Від кожного покращення офіційного Helm-Чарта виграють і його користувачі.

Сподіваюся, вам сподобалася історія про наші пригоди з міграцією у Kubernetes. Ми продовжуємо переносити нові сервіси в кластер. Додаткову інформацію можна отримати з наступних публікацій:

PS від перекладача

Читайте також у нашому блозі:

Джерело: habr.com

Додати коментар або відгук