База знаний LinxCloud Services

Архитектура сервиса kubernetes от Linx Cloud Services

Как устроен Kubernetes as a Service на платформе Linx Cloud

Работа с Kubernetes aaS в Linx Cloud — это:

  1. Удобная панель управления для выполнения операций над кластерами, включая их создание.
  2. Добавление или удаление нод (Cluster Autoscaler), иными словами возможность автоматического масштабирования узлов кластера.
  3. Возможность мониторинга сервисов и самого кластера на основе Prometheus Operator и Grafana.
  4. Хранение и управление образами благодаря сотрудничеству с Docker Registry.
  5. Развертывание федеративных кластеров Kubernetes на базе AWS и Linx Cloud автоматически.
  6. Возможность получения реальных IP пользователей внутри кластеров с помощью Cluster Policy: Local.
  7. Функции Start/Stop для кластера целиком, что поспособствует экономии для тестовых сред.
  8. Возможность строить геораспределенные кластеры и федерации, когда кластеры находятся в разных дата-центрах.
  9. Cозданиt Node Pools, пулов виртуальных машин разных размеров.
  10. Работа кластеров с VPN-соединением.
  11. Persistent Volumes интегрированы с системой хранения OpenStack.
  12. Создание и масштабирование кластеров Kubernetes с помощью UI или API Linx Cloud, управление сущностями через Kubernetes dashboard и kubectl.
  13. Простое и быстрое обновление (rolling update) для минорных мажорных версий.
  14. Свой Terraform-провайдер для Kubernetes.

 

 

Место Kubernetes в инфраструктуре облачной платформы

Нижний слой — типовые физические серверы (compute nodes), используемые для вычисления и хранение. Мы обеспечиваем файловыми и блочными хранилищами на базе Ceph и S3-совместимыми объектными хранилищами. Наши серверы распределены по дата-центрам, между которыми проложена сеть 40 Gbps.

Над уровнем серверов работает OpenStack, обеспечивающий виртуализацию для пользовательских окружений. А уже поверх виртуальных машин, сетей и балансировщиков работают PaaS-решения: Kubernetes, базы данных, DWH на базе ClickHouse, Hadoop, Spark и другие.

Аналогичную схему мы строим и в приватных инсталляциях Kubernetes как сервиса в дата-центрах наших заказчиков в формате частного облака.

 

Какие инструменты мы используем

  1. Операционная система. Сначала мы использовали CoreOS, которая работает на хостах, сейчас у нас Fedora Atomic (1.14-1.15) и CentOS (1.16).
  2. CRI. Мы два года используем Docker последней версии, но сейчас мигрируем, добавляем опциональную возможность виртуализации с повышенной изоляцией на базе Firecracker и Kata Container.
  3. Сеть — Calico. Сети Kubernetes зависят от облачной сети, которая обеспечивается SDN всего облака. В основе нашей SDN изначально был OpenStack Neutron. Но год назад мы начали разработку модуля Sprut — нашего собственного SDN-решения, которое поддерживает API Neutron, но работает по другим принципам. Подход Sprut решил наши проблемы масштабируемости, возникающие из-за десятков тысяч сетевых сущностей (портов) у нас в облаке, когда при падении сетевых нод в сети такого размера начинался процесс полной синхронизации (fullsync). Сейчас Sprut мы задействуем для тех клиентов, для которых в силу особенностей нагрузки на сеть использовать его целесообразнее, чем Calico, в перспективе мы его откроем для всех.
  4. Кластерный DNS на базе CoreDNS, со всеми его Service Discovery, метриками Prometheus и другими стандартными фичами.
  5. Ingress Controller. Сейчас это Nginx, но мы также добавляем Envoy, как дополнительный Ingress Controller. Наши тесты показывают, что Envoy часто быстрее. Ingress Controller интегрирован с облачным балансировщиком нагрузки на базе OpenStack Octavia и поддерживает Proxy Protocol.
  6. Мониторинг на базе Prometheus Operator. Раньше использовали просто Prometheus, но сейчас все хотят автоматизацию и сервис-мониторы, поэтому мы уже несколько месяцев предлагаем Prometheus Operator + Grafana, в рамках которой можно добавлять сервис-мониторы и выполнять мониторинг кластеров.
  7. Аддоны (опциональные расширения). В один клик можно установить Docker registry, интегрированный с нашим S3-хранилищем, ingress controller, различные системы мониторинга (Heapster, Prometheus).

 

Multi Master и сетевая топология

Kubernetes от Linx Cloud поддерживает деплой в формате Multi Master, при этом каждая пользовательская группа нод уже находится в конкретной зоне доступности. Геораспределение гарантируется созданием виртуальных машин по принципу Soft Anti Affinity, когда машины по возможности запускаются на разных гипервизорах.

Multi Master в облаке

В Multi Master etcd работает в кластерном режиме, так что если что-то случается с одним из мастеров, другие продолжают работать. Под каждый etcd выделен отдельный SSD-диск, что обеспечивает хороший latency и быструю работу API-сервера, т.к. в etcd находится служебная информация о всех ресурсах кластера Kubernetes.

Для доступа извне используется балансировщик нагрузки API сервера Kubernetes, который имеет внешний IP-адрес. При этом все ноды — и мастера, и миньоны — находятся в приватной сети (фактически в виртуальном частном облаке) и не имеют публичных адресов.

 

Доступ к кластеру Kubernetes из публичной сети

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

NodePort открывает публичный порт на ноде. Однако есть ограничение: в целях безопасности по умолчанию публичные IP-адреса не установлены ни на мастера, ни на миньоны, кластеры создаются без белых IP-адресов. Пользователь может их сам установить.

Load Balancer. Наш Kubernetes интегрирован с облачной платформой Linx Cloud, так что платформа предоставляет Load Balancer как сервис и может сама создавать балансировщики. Для сравнения, если пользователь настраивает Kubernetes (например, в он премисе), нужно самостоятельно поднимать и настраивать софтверные балансеры. На платформе Linx Cloud балансировщики поднимаются сразу в отказоустойчивом режиме active-standby. Когда поднимается основной балансер (на HAProxy), у него всегда есть standby, спящий балансер. Между ними настроен VRRP. Если основной балансер отказывает, весь трафик мгновенно переключается на standby, при этом IP-адрес не меняется.

Отказоустойчивый Load Balancer как сервис на платформе Linx Cloud. Kubernetes создает nodeport на каждой ноде и балансировщик

В настройке балансировки для Kubernetes помогает наш Cloud Provider. Нужно создать манифест, в котором пользователь указывает тип манифеста “сервис” и тип сервиса “Load Balancer”. После деплоя этого манифеста Kubernetes (точнее, Cloud Provider, который работает в Kubernetes) обращается к OpenStack API, создает балансировщик и внешний IP-адрес, если это необходимо. Если внешний адрес не нужен, нужно поставить аннотацию, что требуется внутренний балансировщик, и можно пускать трафик на кластер, не открывая публичный IP-адрес на каждой ноде.

Сервисный манифест для создания балансировщика нагрузки с помощью Cloud Provider

Не всегда удобно создавать по балансеру на каждый сервис, 10 сервисов — есть 10 балансировщиков, 50 сервисов — 50 балансировщиков. Ими потом также приходится управлять, это тяжелые сущности. Эту проблему решает Ingress.

Ingress. Чтобы можно было не создавать много балансировщиков, мы добавили поддержку Ingress Controller. Ingress Controller интегрирован с балансировщиком OpenStack. То есть в декларации сервиса конкретного Ingress Controller указан тип Load Balancer. Для кластера создается один балансировщик, по которому Ingress Controller работает и дальше распределяет трафик по сервисам. Ingress Controller балансирует по DNS-именам.

Схема работы Ingress

Для некоторых клиентов важно, чтобы в подах было видно IP-адреса клиентов, получающих доступ в кластер. При балансировке теряются заголовки IP-пакетов: приложение не получает реальный IP-адрес клиента. Балансировщик OpenStack еще видит заголовок X-Forwarded-For, но Ingress Controller и под его уже не получают. Это не позволяет настроить доступ пользователей по White Lists, не работают сервисы типа GeoIP или anti-DDoS, которым нужно видеть реальные IP-адреса клиентов.

IP-адрес клиента не доходит до пода

И здесь у нас оказалось два решения :

Сделать режим proxy-протокола как в Amazon. Ради этой возможности мы перешли на балансировщик OpenStack Octavia, так как в стандартном балансировщике OpenStack нет такой опции. В итоге мы сделали новый балансировщик, который поддерживал как TCP-балансировку, так и HTTP(HTTP/2) с терминацией SSL.

При этом поддержку proxy-протокола нужно включать как на самом балансировщике (HAproxy), так и на Nginx Ingress Controller, который выступает таким приемником. Иначе схема пропускания трафика ломается. Также важно, что SSL-терминация, если у вас стандартный веб-трафик, должна проходить на Ingress:

Терминация SSL на балансировщике. Здесь на балансер приходит HTTPS , он расшифровывается, и в кластер идет HTTP. Если все это сделать и активировать в сервисе ExternalTrafficPolicy: Local, вы будете видеть заголовки IP-пакетов:

 

Storage и Kubernetes

Если разворачивать Kubernetes локально или в облаке просто на виртуальных машинах, то по умолчанию в нем нет нормальной работы с постоянными дисками. Можно использовать Host Path, Local volume (no-provisioner), либо прямо в кластере Kubernetes разворачивать экзотические программно-определяемые системы хранения типа Linstor или OpenEBS. Но что произойдет с данными или очередью данных, которая размещается в кластере, если умрет нода или под?

При самостоятельном подключении блочных устройств к кластеру есть проблемы: CSI драйверы не идеальны для многих типов стораджей, и автоматическое перемонтирование может не произойти. Мы сделали работу с блочными устройствами автоматизированной. Чтобы при отключении пода блочное устройство переподключалось к новому поду само.

Мы используем Ceph. Главное, что они работают через OpenStack, который предоставляет специальные модули, абстрагирующие Kubernetes (или любые виртуальные машины, работающие в облаке), на конкретных драйверах — OpenStack Cinder.

У нас несколько разных storage-классов, которые работают в Kubernetes: SSD Ceph, HDD Ceph, геораспределенные Ceph между нашими ЦОДами. Есть storage-класс, отвечающий за блочные диски: фактически это дисковые шкафы с SSD, они подключаются к хост-машинам по iSCSI.

Несколько Storage-классов в Linx Cloud

При необходимости мы используем NFS, когда клиенты не могут переписать приложения в микросервисную архитектуру. У нас есть аналог сервиса EFS от Amazon — файловое хранилище с NFS-протоколом, доступное как сервис. Оно подходит, если у вас legacy-приложение, которое вы переводите в Kubernetes.

Кроме того, у нас есть локальные SSD, но здесь сложно гарантировать их доступность и переезд данных, поскольку они доступны только с физических серверов, к которым подключены.

Наиболее отказоустойчивым решением является использование Kubernetes PersistenVolume’s на основе OpenStack Cinder. PersistenVolume подключаются через единый модуль OpenStack — OpenStack Cinder, к каждой ноде Kubernetes и обеспечивают возможность переезда постоянных томов в случае падения ноды на рабочую. А также когда повышается нагрузка чтения/записи и Kubernetes решает перевозить неважные поды на другие ноды — тогда он автоматически переводит монтирование этого диска к другим Kubernetes-нодам.

Так происходит автоматическое перемонтирование

Можно использовать storage class, написав декларации PersistentVolumeClaim. На примере, который изображен ниже, Cloud Provider выделит в заданной зоне доступности новый Persistent Volume, размером 30 ГБ с типом диска SSD, подключит его к ноде и примонтирует к подам. Также он будет следить, чтобы этот диск переезжал между нодами в случае переезда подов:

 

Автоматическое масштабирование

В Linx Cloud есть Cluster Autoscaler. Это не просто автоскейлинг подов внутри кластера, а автоскейлинг самого кластера по необходимости: новые ноды добавляются, когда нагрузка выросла, и удаляются, если нагрузка упала. Масштабирование происходит автоматически — до 100 узлов и обратно за несколько минут.

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

Cluster Autoscaler лучше настраивать совместно с Horizontal Pod Autoscaler. Различие использования двух вариантов Autoscaler:

  • Cluster Autoscaler позволяет расширять сами выделенные для кластера ресурсы. По сути он может автоматически арендовать дополнительные ресурсы или сократить их использование через Cloud Provider.
  • Horizontal Pod Autoscaler позволяет расширять ресурсы подов в рамках существующих выделенных ресурсов кластера, чтобы оптимально их использовать.

 

Функциональность

Интеграция со стандартными инструментами Kubernetes

  • Хранение и обработка serverless-функций в контейнерах: OpenFaaS, OpenWhisk, Kubeless
  • Инструменты Service Mesh: Istio, Consul, Linkerd
  • Мониторинг, аналитика, логирование: Prometheus, Fluentd, Jaeger, OpenTracing
  • CI/CD: Gitlab, CircleCI, Travis CI
  • IaC (описание приложений): Terraform, Helm

Безопасность

  • Kubernetes использует аутентификацию по сертификатам.
  • Систему безопасности кластеров можно интегрировать с LDAP/Active Directory для аутентификации пользователей. При этом ролевую модель безопасности в Kubernetes можно настроить на проверку прав доступа на основе принадлежности пользователя к группам в LDAP-каталоге.
  • Для сетевой безопасности можно применять Calico Network Policy.
  • В наш Kubernetes aaS интегрирован Docker Registry, защищенный SSL.

Резервное копирование и миграция

  • Мы поддерживаем интеграцию с Velero. Velero выполняет резервное копирование, которое позволяет бэкапить манифесты etcd и Persistent Volumes.
  • Также с помощью Velero можно мигрировать кластеры on-premises и других провайдеров на наш Kubernetes.

Работа с большими данными

Kubernetes по сути можно использовать для любых микросервисных приложений, работающих с данными. Чем Kubernetes на платформе Linx Cloud интересен для data scientist’ов:

  • Автомасштабирование позволяет выдерживать большие вычислительные нагрузки.
  • Можно создавать событийные (event-triggered) обработчики данных.
  • Приложения на Kubernetes легко интегрировать с другими нашими PaaS для Big Data, машинного обучения, в рамках одной сети.
  • Если хочется поэкспериментировать, то для ускорения обучения к очереди событий или событийному обработчику на базе Kubernetes можно напрямую подключить GPU.
Что вас интересует?
Получить демо-доступ

Спасибо за ваш запрос, мы свяжемся с вами в ближайшее время!