Kubernetes в ДомКлик: как спать спокойно, управляя кластером на 1000 микросервисов +36




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



Команда Ops


В команде Ops на данный момент работает 15 человек. Трое из них отвечают за офис, двое работают в другом часовом поясе и доступны, в том числе, и ночью. Таким образом, всегда кто-то из Ops находится у монитора и готов среагировать на инцидент любой сложности. Ночных дежурств у нас нет, что сохраняет нашу психику и даёт возможность всем высыпаться и проводить досуг не только за компьютером.

image

Компетенции у всех разные: сетевики, 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-кластере, если измерять по количеству deployments. Количество подов колеблется между 1700 и 2000. Подов в prod-кластере сейчас около 2000.

Точные числа назвать не могу, так как мы следим за ненужными микросервисами и выпиливаем их в полуавтоматическом режиме. Следить за ненужными сущностями в k8s нам помогает useless-operator, что здорово экономит ресурсы и деньги.

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


Мониторинг


Краеугольным камнем в эксплуатации большого кластера становится грамотно выстроенный и информативный мониторинг. Мы пока не нашли универсального решения, которое покрыло бы 100 % всех «хотелок» по мониторингу, поэтому периодически клепаем разные кастомные решения в этой среде.

  • Zabbix. Старый добрый мониторинг, который предназначен, в первую очередь, для отслеживания общего состояния инфраструктуры. Он говорит нам, когда нода умирает по процу, памяти, дискам, сети и так далее. Ничего сверхъестественного, но также у нас есть отдельный DaemonSet из агентов, с помощью которых, например, мы мониторим состояние DNS в кластере: ищем тупящие поды coredns, проверяем доступность внешних хостов. Казалось бы, зачем ради этого заморачиваться, но на больших объемах трафика этот компонент является серьезной точкой отказа. Ранее я уже описывал, как боролся с производительностью DNS в кластере.
  • Prometheus Operator. Набор различных экспортеров даёт большой обзор всех компонентов кластера. Далее визуализируем всё это на больших дашбордах в Grafana, а для оповещений используем alertmanager.

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

Ресурсы команд в «Кубе»


Прежде чем приступить к примерам, стоит объяснить, как у нас работает выделение ресурсов для микросервисов.

Чтобы понимать, какие команды и в каких количествах используют свои ресурсы (процессор, память, локальный SSD), мы выделяем на каждую команду свой namespace в «Кубе» и ограничиваем его максимальные возможности по процессору, памяти и диску, предварительно обговорив нужды команд. Соответственно, одна команда, в общем случае, не заблокирует для деплоя весь кластер, выделив себе тысячи ядер и терабайты памяти. Доступы в namespace выдаются через AD (мы используем RBAC). Namespace'ы и их лимиты добавляются через пул-реквест в GIT-репозиторий, а далее через Ansible-пайплайн всё автоматически раскатывается.

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

namespaces:

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

Реквесты и лимиты


В «Кубе» Request — это количество гарантированно зарезервированных ресурсов под pod (один или более докер-контейнеров) в кластере. Limit — это негарантированный максимум. Часто можно увидеть на графиках, как какая-то команда выставила себе слишком много реквестов для всех своих приложений и не может задеплоить приложение в «Куб», так как под их namespace все request'ы уже «потрачены».

Правильный выход из такой ситуации: смотреть реальное потребление ресурсов и сравнивать с запрошенным количеством (Request).




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

Теперь подробно разберём какой-нибудь namespace (я выбрал namespace kube-system — системный namespace для компонентов самого «Куба») и посмотрим соотношение реально использованного процессорного времени и памяти к запрошенному:



Очевидно, что памяти и ЦПУ зарезервировано под системные службы намного больше, чем используется реально. В случае с kube-system это оправдано: бывало, что nginx ingress controller или nodelocaldns в пике упирались в CPU и отъедали очень много RAM, поэтому здесь такой запас оправдан. К тому же, мы не можем полагаться на графики за последние 3 часа: желательно видеть исторические метрики за большой период времени.

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



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



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

В итоге, у разработчиков есть инструменты для мониторинга своих namespaces в «Кубе», и они способны сами выбирать, где и в какое время у каких приложений можно «подрезать» ресурсы, а каким подам можно на всю ночь отдать весь CPU.

Методологии


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

Как Ops, мы предоставляем различные метрики и дашборды для разработчиков, связанные со скоростью ответа сервисов и их ошибками.

Мы используем такие методологии, как: RED, USE и Golden Signals, комбинируя их вместе. Стараемся минимизировать количество дашбордов так, чтобы с одного взгляда было понятно, какой сервис сейчас деградирует (например, коды ответов в секунду, время ответа по 99-перцентилю), и так далее. Как только становятся нужны какие-то новые метрики для общих дашбордов, мы тут же их рисуем и добавляем.

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





Получившийся результат ценен тем, что теперь разрабы довольно редко ходят к админам с вопросами «где посмотреть какую-то метрику».

Внедрение Service Mesh не за горами и должно сильно облегчить всем жизнь, коллеги из Tools уже близки к внедрению абстрактного «Istio здорового человека»: жизненный цикл каждого HTTP(s)-запроса будет виден в мониторинге, и всегда можно будет понять «на каком этапе всё сломалось» при межсервисном (и не только) взаимодействии. Подписывайтесь на новости хаба компании ДомКлик. =)

Поддержка инфраструктуры Kubernetes


Исторически сложилось так, что мы используем патченную версию Kubespray — Ansible-роль для разворачивания, расширения и обновления Kubernetes. В какой-то момент из основной ветки была выпилена поддержка non-kubeadm инсталляций, а процесс перехода на kubeadm предложен не был. В итоге, компания Southbridge сделала свой форк (с поддержкой kubeadm и быстрым фиксом критических проблем).

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

  • Берем Kubespray от Southbridge, сверяем с нашей веткой, мерджим.
  • Выкатываем обновление в Stress-«Куб».
  • Выкатываем обновление по одной ноде (в Ansible это «serial: 1») в Dev-«Куб».
  • Обновляем Prod в субботу вечером по одной ноде.

В будущем есть планы заменить Kubespray на что-нибудь более быстрое и перейти на kubeadm.

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

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

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

Заключение




Вот так, в общих чертах, в компании ДомКлик выглядит процесс DevOps со стороны инженера эксплуатации. Статья получилась менее технической, чем я ожидал: поэтому, следите за новостями ДомКлик на Хабре: будут более «хардкорные» статьи о Kubernetes и не только.

Теги:




Комментарии (37):

  1. Nastradamus
    /#21932686

    Ответ на вопрос моей мамы «чем я занимаюсь на работе» =)

  2. sse
    /#21932908

    А сколько у вас разработчиков, которые пишут серверные приложения и микросервисы?

    • Nastradamus
      /#21932936 / +1

      350 — буквально все разрабы имеют что-то своё в кубе: включая мобильную разработку и фронтенд. Даже у меня там несколько pet projects, хоть я и админ =)

  3. ShuraorSasha
    /#21932974 / +1

    классная статья, спасибо!

  4. abogushov
    /#21933516

    Спасибо за статью! Ops команда выполняет ревью Helm чарта? Кто готовит дашборт для white box мониторинга сервиса? Есть ли какие-то требования к документации сервиса у ops-команды или вопрос сразу уходит к дежурному разработчику?

    • Nastradamus
      /#21933524

      Мы ревьювим чарты, да. Дашборд готовят разработчики. Документация — на воли совести создателя сервиса. Не страшно если ее вообще нет: infrastructure as a code.

  5. vickivanov
    /#21933652

    Не сочтите за критику, но — каждый раз, когда я вижу такие цифры применительно даже не к Сберу, а к Домклику, у меня шок. 350 разработчиков — это маленькая армия, с которой можно дать рынку недвижимости такие сервисы, аналогов которым не было и нет. А по факту эта армия запилила линейку продуктов, самый сложный из которых — это по сути просто доска объявлений по недвижимости. Как же так?
    Без обид, правда удивлен)

    • Nastradamus
      /#21933654

      ДомКлик сделали сервис выдачи ипотеки онлайн. До этого был мрак. 49% доли рынка недвижимости — это не только клиенты Сбера.

    • Nastradamus
      /#21933658 / +3

      Но это скорее к бизнесу вопрос. Мне нравится облака делать, которые меня не будят по ночам.

    • barloc
      /#21938954

      А потом говорят, что людей не хватает в ит :)

  6. darkAlert
    /#21933838

    Это всё круто, автоматизировано… особенно удобно для мошенников. Говорю так, потомучто:
    1) полгода назад у моей жены мошенники похитили со сбера 800к рублей
    2) месяц назад я продал квартиру через ДомКлик, завел счет в сбере. И через 20 минут после сделки мне сразу позвонили эти же мошенники. И я не верю что данные просто слили вручную, так оперативно можно сделать если всё это мошенничество также автоматизировано.

    • oller
      /#21934228

      Ну для прокрутки таких офер незачем иметь прокладки вида продажи данных, достаточно только одному компетентному человеку получать данные и сливать своей группе. Там же сотни миллионов
      С точки зрения безопасности в кубере все очень сложно. Не удивлюсь если подсосаться к системе этой могут и без явных следов.
      Если даже apple жил с 10к лет с дырой, которую использовали для удаленного управления устройством, то кубер даже смешно
      пруф про apple ниже
      safe.cnews.ru/news/top/2020-04-27_hakery_atakuyut_vippolzovatelej

      PS за ошибки в тексте извините

  7. Loggus66
    /#21934976

    То есть для визуализации всего-всего используется Grafana. GUI вроде Rancher2 не стал использоваться по причине его сырости в момент проектировки системы, не было нужды, или не хотелось иметь лишнюю прослойку?
    Оффтопик: как спать спокойно после оформления сделки через Домклик, зная, что злоумышленники могут выпустить ЭЦП на твоё имя и провернуть операции с недвижимостью?

    • Nastradamus
      /#21936364

      Про визуализацию мониторинга через Ранчер ничего не скажу. Сам Ранчер нам не интересен — его фичи либо уже у нас есть, либо не интересны. Графана — стандарт индустрии, хорошая документация и все ее умеют. Она была до Кубера и наверное будет когда его не станет :) Хотелось бы чтобы она просто не тормозила хотя бы на топовых компах на той же community Kubernetes Dashboard.

  8. Savochkin
    /#21935010

    Подскажите, пожалуйста, как часто вы выкатываете релизы на прод?
    Используете ли вы кросфункциональнвн продуктовые / фича команды? Если да, то какого размера?
    Какое у вас среднее время производства фичи? ( ну типа от момента когда взяли в работу и до выпуска на прод?)

    • Nastradamus
      /#21943038

      Попросил коллег ответить на ваш вопрос =) Скорее всего ответ где-то кроется в первых постах нашей компании на Хабре.

  9. softadmin
    /#21935854

    Спасибо за статью! Подскажите, хорошо ли чувствует себя сам сервер Docker под нагрузкой? У вас нет в планах переводить рантайм с Docker на что-то другое? Какое у вас в среднем количество подов на ноду ?

    • Nastradamus
      /#21936354

      С самим Docker проблем нет. Есть вопросы к скорости развития самого Docker: он просто не развивается и долгожданных нужных фич вроде лимитирования по IOPS, cgroups v2 — мы до сих пор не получили. В среднем сейчас 40-70 подов на ноду (до 100 иногда доходит).

  10. shachneff
    /#21936136

    1000 микросервисов… а почему так много? Что делает каждый микросервис, можете привести примеры? Даже не каждый, а по группам побить.

    • Nastradamus
      /#21944750

      Увы, это уже не ко мне. Передал вопрос разрабам =)

  11. vrutkovs
    /#21941556

    Была разработана система «рекомендаций»

    А чем полезна эта система? Системные поды
    а) подпадают в обе категории,
    б) судя по скроллбару там много подов которым неплохо бы урезать аппетиты.
    Эти "рекомендации" не применяются и сделаны исключительно для отчетности?

    • Nastradamus
      /#21941564

      Если там выбрать namespace, отличный от kube-system — то там будет все нормально.
      Просто чтобы живые имена подов не показывать, я выбрал такой ns.

  12. 0x450x6c
    /#21941570

    Обновляем Prod в субботу вечером по одной ноде.

    А что будет в случае проблем после обновления, но если его заметили в следующий день, т.е. в воскресенье?


    Jenkins

    Деплой и настройка дженкинса автоматизировано?


    Ansible

    ИМХО, у ansible недостатков много:


    • медленная.
    • императивная, как следствие оставляет мусора в системе, к примеру, недостаточно удалить лишные настройки, нужно ещё правильно написать сценарии для удаления.
    • странный DSL, по сути отдельный язык программирования.

    Хотя для кубовых инфраструктур — может не так уж плохо.




    Как с безопасностью?


    • может ли один микросервис доставить неприятности соседям?
    • сколько людей имеет доступ к prod серверу, и мониторите ли их действия на сервере?

    • pepemon
      /#21942858

      Императивным Ansible может быть только потому что вы его сами используете как Bash на стероидах. У меня на проекте используются ислючительно идемпотентные роли, никаких сайд-эффектов (то что вы называете "мусором") никогда не имелось. Ну и медленность давно уже лечится хоть тем же Mitogen.

      • 0x450x6c
        /#21943556

        Императивным Ansible может быть только потому что вы его сами используете как Bash на стероидах.

        Так можно сказать про что угодно.


        У меня на проекте используются ислючительно идемпотентные роли, никаких сайд-эффектов (то что вы называете "мусором") никогда не имелось.

        Допустим вам больше не нужен определенный роль, чтобы откатить все настройки этого роля, вам придется написать дополнительную логику для отката, что требует дополнительных усилий на разработку + тестирование.


        Если вы сразу пишите и тестируете логику отката — здорово.


        Для меня является недостатком то, что необходимо писать такую логику.

        • Nastradamus
          /#21944644

          Для меня является недостатком то, что необходимо писать такую логику.

          Чтобы откатить настройки роли, нужно смерджить в гит или нажать специальную кнопку в CI-системе, которая откатит состояние на предыдущий коммит.
          Или самое тупое: подготовить заранее PR для отката.

          Мы каким-то разным ансиблом пользуемся )

          • 0x450x6c
            /#21944686 / +1

            Чтобы откатить настройки роли, нужно смерджить в гит или нажать специальную кнопку в CI-системе, которая откатит состояние на предыдущий коммит.

            Но это не откатить состояние сервера.

    • Nastradamus
      /#21943164

      А что будет в случае проблем после обновления, но если его заметили в следующий день, т.е. в воскресенье?


      Обычно если что-то не заметили сразу, то это не является чем-то сильно критичным.
      У нас есть дашборды, показывающие «где что болит» и детальные дашборды по разным компонентам куба. Пропустить «большой косяк» довольно сложно, а мелкие косяки могут починить и ночные админы, либо утром сами починим, если не критично.

      Деплой и настройка дженкинса автоматизировано?


      Я не большой спец по Дженкинсу, недавно стало писать под него. Может я неправильно понял вопрос.
      Дженкинс у нас только для Ops-проектов и руками завести пайплайн раз в 2 недели не проблема

      ИМХО, у ansible недостатков много

      Почти полностью согласен. Производительность Kubespray довольно ужасна, хотим слезть с него.

      Как с безопасностью?


      Довольно много работаем над этим. Не всё идеально, но лучше чем обычно (что я вижу в других компаниях). Подробности раскрыть не могу.

  13. pepemon
    /#21942888

    перешли довольно болезненно с Helm 2, но очень рады опции atomic

    А что не так с atomic в самом Helm 2? Данная опция в нём делает тоже самое, что и в Helm 3.

    • Nastradamus
      /#21943180

      Atomic в Helm 2 появился чуть ли не после выхода Helm 3, ЕМНИП. Не проверяли — проще было сразу перейти на Helm 3 и выпилить все tiller'ы из всех нэймспейсов.

  14. podhornyi
    /#21943170

    Спасибо за статью!


    Подскажите пожалуйста на какой системе(версия имеджа, ядра и и.д.) у вас крутится куб в проде?
    И тюнили ли вы систему перед тем как поставить куб?

    • Nastradamus
      /#21943194

      CentOS 7, 4.4.2xx ядра (периодически обновляем на последнее ядро LT-ветки).

      Систему тюним при заливке при помощи Ansible: там штук 50 sysctl меняем.

      kubelet'ы тоже тюним — их опции выстраданы годами.

      • pepemon
        /#21943284

        А чем красношапочное ядро не устроило? А если билдить и мэйнтэйнить ядра самим, то почему не longterm посвежее? Один eBPF чего стоит.

        • Nastradamus
          /#21944748

          Ну обычное LT ядро от CentOS. На момент обновления ядер — было последним. Несколько месяцев им. Ставим то, что не глючит. У поздних 3x были проблемы с XFS (тормозило спонтанно на k8s нодах) и тоже самое было на 5.x ядрах последних от CentOS + еще были какие-то глюки. Оставили то, что позволяло спать спокойно.

          • pepemon
            /#21944940

            А, видимо тянете с ELRepo, понял. Я с их конфигов собираю, но только 4.19.xxx.

            • Nastradamus
              /#21946840

              ELRepo, так и есть. Я бы еще от XFS в польщу ext4 отказался.