Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

Мене звуть Віктор Ягофаров, і я займаюся розвитком Kubernetes-платформи в компанії «ДомКлік» на посаді технічного керівника розробки в команді Ops (експлуатація). Я хотів би розповісти про влаштування наших процесів Dev <-> Ops, про особливості експлуатації одного з найбільших k8s-кластерів у Росії, а також про DevOps/SRE-практики, які застосовує наша команда.

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

Команда Ops

У команді Ops на даний момент працює 15 людей. Троє з них відповідають за офіс, двоє працюють в іншому часовому поясі та доступні, в тому числі й уночі. Таким чином, завжди хтось із Ops знаходиться біля монітора і готовий зреагувати на інцидент будь-якої складності. Нічних чергувань у нас немає, що зберігає нашу психіку і дає можливість усім висипатися та проводити дозвілля не лише за комп'ютером.

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

Компетенції у всіх різні: мережевики, DBA, спеціалісти з стеку ELK, Kubernetes-адміни/розробники, фахівці з моніторингу, віртуалізації, заліза тощо. Об'єднує всіх одне - кожен може замінити певною мірою будь-якого з нас: наприклад, ввести нові ноди в кластер k8s, оновити PostgreSQL, написати pipeline CI/CD + Ansible, автоматизувати що-небудь на Python/Bash/Go, підключити залізницю в ЦОД. Сильні компетенції в будь-якій області не заважають змінити напрямок діяльності і почати прокачуватися в будь-якій іншій галузі. Наприклад, я влаштовувався в компанію як фахівець із PostgreSQL, а зараз моя головна зона відповідальності – кластери Kubernetes. У команді будь-яке зростання тільки вітається і дуже розвинене почуття плеча.

До речі, ми хантимо. Вимоги до кандидатів є досить стандартними. Особисто для мене важливо, щоб людина вписувалася в колектив, була неконфліктною, але також вміла відстоювати свою точку зору, хотіла розвиватися і не боялася робити щось нове, пропонувала свої ідеї. Також, обов'язкові навички програмування скриптовими мовами, знання основ Linux та англійської мови. Англійська потрібна просто для того, щоб людина у разі факапа могла загуглити вирішення проблеми за 10 секунд, а не за 10 хвилин. Зі фахівцями з глибоким знанням Linux зараз дуже складно: смішно, але два кандидати з трьох не можуть відповісти на запитання «Що таке Load Average? З чого він складається?», а питання «Як зібрати core dump із сишної програми» вважають чимось зі світу надлюдей... чи динозаврів. Із цим доводиться миритися, оскільки зазвичай у людей сильно розвинені інші компетенції, а «лінуксу» ми навчимо. Відповідь на запитання «навіщо це все потрібно знати DevOps-інженеру в сучасному світі хмар» доведеться залишити за рамками статті, але якщо трьома словами: все це потрібно.

Команда Tools

Чималу роль автоматизації грає команда Tools. Їхнє основне завдання — створення зручних графічних та CLI-інструментів для розробників. Наприклад, наша внутрішня розробка Confer дозволяє буквально декількома кліками миші викотити додаток у Kubernetes, налаштувати йому ресурси, ключі з vault і т.д. Раніше був Jenkins + Helm 2, але довелося розробити власний інструмент, щоб унеможливити копі-пасту і внести однаковість у життєвий цикл ПЗ.

Команда Ops не пише пайплайни за розробників, але може проконсультувати з будь-яких питань у їх написанні (у декого ще залишився Helm 3).

DevOps

Що стосується DevOps, то ми бачимо його таким:

Команди Dev пишуть код, викочують через Confer в dev -> qa/stage -> prod. Відповідальність за те, щоб код не гальмував і не сипав помилками, лежить на командах Dev та Ops. У денний час реагувати на інцидент зі своїм додатком повинен насамперед черговий від команди Ops, а у вечірній та нічний час черговий адмін (Ops) повинен розбудити чергового розробника, якщо він точно знає, що проблема не в інфраструктурі. Усі метрики та алерти в моніторингу з'являються автоматично або напівавтоматично.

Зона відповідальності Ops починається з моменту викочування програми в прод, але й відповідальність Dev на цьому не закінчується - ми робимо одну справу і знаходимося в одному човні.

Розробники консультують адмінів, якщо потрібна допомога в написанні адмінського мікросервісу (наприклад, Go backend + HTML5), а адміни консультують розробників з будь-яких інфраструктурних питань або питань, пов'язаних з k8s.

До речі, у нас взагалі немає моноліту, лише мікросервіси. Їхня кількість поки що коливається між 900 і 1000 у prod k8s-кластері, якщо вимірювати за кількістю розгортання. Кількість подів коливається між 1700 та 2000. Подів у prod-кластері зараз близько 2000.

Точні числа назвати не можу, тому що ми стежимо за непотрібними мікросервісами та випилюємо їх у напівавтоматичному режимі. Слідкувати за непотрібними сутностями у k8s нам допомагає useless-operatorщо здорово економить ресурси та гроші.

Управління ресурсами

моніторинг

Наріжним каменем в експлуатації великого кластера стає грамотно збудований та інформативний моніторинг. Ми поки що не знайшли універсального рішення, яке б покрило 100 % усіх «хотелок» з моніторингу, тому періодично клепаємо різні кастомні рішення в цьому середовищі.

  • Zabbix. Старий добрий моніторинг, який призначений насамперед для відстеження загального стану інфраструктури. Він говорить нам, коли нода помирає по роботі, пам'яті, дисках, мережі тощо. Нічого надприродного, але також у нас є окремий DaemonSet з агентів, за допомогою яких, наприклад, ми моніторимо стан DNS у кластері: шукаємо тупи піде coredns, перевіряємо доступність зовнішніх хостів. Здавалося б, навіщо задля цього морочитись, але на великих обсягах трафіку цей компонент є серйозною точкою відмови. Раніше я вже описувавяк боровся з продуктивністю DNS в кластері
  • Оператор Прометей. Набір різних експортерів дає великий огляд всіх компонентів кластеру. Далі візуалізуємо все це на великих дашбордах у Grafana, а для сповіщень використовуємо alertmanager.

Ще одним корисним інструментом для нас став list-ingress. Ми написали його після того, як кілька разів зіштовхнулися із ситуацією, коли одна команда перекриває своїми шляхами Ingress іншої команди, через що виникали помилки 50x. Зараз перед деплоєм на прод розробники перевіряють, що нікого не зачеплять, а для моєї команди це добрий інструмент для первинної діагностики проблем з Ingress'ами. Смішно, що спочатку його написали для адмінів і виглядав він досить «незграбно», але після того, як інструмент сподобався dev-командам, він сильно перетворився і став виглядати не як «адмін зробив веб-морду для адмінів». Незабаром ми відмовимося від цього інструменту і подібні ситуації валідуватимуться ще до викочування пайплайну.

Ресурси команд у «Кубі»

Перш ніж приступити до прикладів, варто пояснити, як у нас працює виділення ресурсів мікросервісів.

Щоб розуміти, які команди та в яких кількостях використовують свої ресурси (процесор, пам'ять, локальний SSD), ми виділяємо на кожну команду свій простору імен у «Кубі» та обмежуємо його максимальні можливості по процесору, пам'яті та диску, попередньо обговоривши потреби команд. Відповідно, одна команда, загалом, не заблокує для деплою весь кластер, виділивши собі тисячі ядер та терабайти пам'яті. Доступи в namespace видаються через AD (ми використовуємо RBAC). Namespace'и та їх ліміти додаються через пул-реквест у GIT-репозиторій, а далі через Ansible-пайплайн все автоматично розкочується.

Приклад виділення ресурсів на команду:

namespaces:

  chat-team:
    pods: 23
    limits:
      cpu: 11
      memory: 20Gi
    requests:
      cpu: 11
      memory: 20Gi

Реквести та ліміти

У «Кубі» Запит - це кількість гарантовано зарезервованих ресурсів під стручок (один або більше докер-контейнерів) у кластері. Limit – це негарантований максимум. Часто можна побачити на графіках, як якась команда виставила собі занадто багато реквестів для всіх своїх додатків і не може задеплоїти додаток у «Куб», тому що під їх namespace всі request'и вже «витрачені».

Правильний вихід із такої ситуації: дивитися реальне споживання ресурсів та порівнювати із запрошеною кількістю (Request).

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів
Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

На скріншотах вище видно, що «запитані» (Requested) CPU підбираються до реальної кількості потоків, а Limits можуть перевищувати реальну кількість потоків центральних процесорів =)

Тепер докладно розберемо якийсь namespace (я вибрав namespace kube-system - системний namespace для компонентів самого "Куба") і подивимося співвідношення реально використаного процесорного часу та пам'яті до запитаного:

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

Очевидно, що пам'яті та ЦПУ зарезервовано під системні служби набагато більше, ніж реально. У випадку з kube-system це виправдано: бувало, що nginx ingress controller або nodelocaldns в піку впиралися в CPU і від'їдали дуже багато RAM, тому тут такий запас виправданий. До того ж ми не можемо покладатися на графіки за останні 3 години: бажано бачити історичні метрики за великий період часу.

Було розроблено систему «рекомендацій». Наприклад, тут можна побачити, яким ресурсам краще б підняти «ліміти» (верхня дозволена планка), щоб не відбувалося «тротлінга» (throttling): моменту, коли під уже витратив CPU або пам'ять за відведений йому квант часу і перебуває в очікуванні, поки його «розморозять»:

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

А ось поди, яким варто було б стримати апетити:

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

Про тротлінг + моніторинг ресурсів можна написати не одну статтю, тож ставте запитання у коментарях. У кількох словах можу сказати, що завдання автоматизації подібних метрик дуже непросте і вимагає багато часу та еквілібристики з «віконними» функціями та «CTE» Prometheus/VictoriaMetrics (ці терміни взяті в лапки, тому що в PromQL майже немає нічого подібного, і доводиться городити страшні запити на кілька екранів тексту і оптимізувати їх).

У результаті, у розробників є інструменти для моніторингу своїх namespaces в "Кубі", і вони здатні самі вибирати, де і в який час у яких додатків можна "підрізати" ресурси, а яким подам можна на всю ніч віддати весь CPU.

Методології

У компанії, як зараз модно, ми дотримуємося DevOps- та SRE-практик. Коли в компанії 1000 мікросервісів, близько 350 розробників і 15 адмінів на всю інфраструктуру, доводиться «бути модним»: за всіма цими «базордами» ховається гостра необхідність автоматизації всього і вся, а адміни не повинні бути пляшковим шийкою в процесах.

Як Ops, ми надаємо різні метрики та дашборди для розробників, пов'язані зі швидкістю відповіді сервісів та їх помилками.

Ми використовуємо такі методології, як: RED, ВИКОРИСТАННЯ и Golden Signalsкомбінуючи їх разом. Намагаємося мінімізувати кількість дашбордів так, щоб з одного погляду було зрозуміло, який сервіс зараз деградує (наприклад, коди відповідей за секунду, час відповіді по 99-перцентилю) тощо. Як тільки стають потрібні якісь нові метрики для загальних дашбордів, ми їх малюємо і додаємо.

Я не малював графіки вже місяць. Напевно, це добрий знак: значить більшість «хотілок» уже реалізовано. Бувало, що за тиждень я хоча б щодня малював якийсь новий графік.

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів

Результат, що вийшов, цінний тим, що тепер розробники досить рідко ходять до адмінів з питаннями «де подивитися якусь метрику».

впровадження Сервісна сітка не за горами і повинне сильно полегшити всім життя, колеги з Tools вже близькі до впровадження абстрактної «Istio здорової людини»: життєвий цикл кожного HTTP(s)-запиту буде видно в моніторингу, і завжди можна буде зрозуміти «на якому етапі все зламалося» при міжсервісній (і не тільки) взаємодії. Підписуйтесь на новини хаба компанії ДомКлік. =)

Підтримка інфраструктури Kubernetes

Історично склалося так, що ми використовуємо патчену версію Кубеспрей - Ansible-роль для розгортання, розширення та оновлення Kubernetes. У якийсь момент з основної гілки була випиляна підтримка non-kubeadm інсталяцій, а процес переходу на kubeadm запропонований не був. У підсумку, компанія Southbridge зробила свій форк (з підтримкою kubeadm та швидким фіксом критичних проблем).

Процес оновлення всіх кластерів k8s виглядає так:

  • беремо Кубеспрей від Southbridge, звіряємо з нашою гілкою, мерджимо.
  • Викочуємо оновлення в стрес-«Куб».
  • Викочуємо оновлення по одній ноді (в Ansible це "serial: 1") в DEV-«Куб».
  • Оновлюємо Тикати у суботу ввечері по одній ноді.

У майбутньому є плани замінити Кубеспрей на щось швидше і перейти на kubeadm.

Усього у нас три «Куби»: Stress, Dev та Prod. Плануємо запустити ще один (hot standby) Prod-«Куб» у другому ЦОДі. стрес и DEV живуть у «віртуалках» (oVirt для Stress та VMWare cloud для Dev). Тикати- «Куб» живе на «голому залізі» (bare metal): це однакові ноди з 32 CPU threads, 64-128 Гб пам'яті та 300 Гб SSD RAID 10 – всього їх 50 штук. Три «тонкі» ноди виділені під «майстри» Тикати-«Куба»: 16 Гб пам'яті, 12 CPU threads.

Для прода воліємо використовувати «голе залізо» і уникаємо зайвих прошарків на кшталт OpenStack: нам не потрібні «шумні сусіди» та CPU steal time. Та й складність адміністрування зростає приблизно вдвічі у разі in-house OpenStack.

Для CI/CD «Кубових» та інших інфраструктурних компонентів використовуємо окремий GIT-сервер, Helm 3 (перейшли досить болісно з Helm 2, але дуже раді опції атомний), Jenkins, Ansible та Docker. Любимо feature-бранчі та деплой у різні середовища з одного репозиторію.

Висновок

Kubernetes в ДомКлік: як спати спокійно, керуючи кластером на 1000 мікросервісів
Ось так, загалом, у компанії ДомКлік виглядає процес DevOps з боку інженера експлуатації. Стаття вийшла менш технічною, ніж я очікував: тому, слідкуйте за новинами ДомКлік на Хабрі: будуть «хардкорніші» статті про Kubernetes і не тільки.

Джерело: habr.com

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