Обзор Kalm — веб-интерфейса для деплоя приложений и управления ими в Kubernetes

image-loader.svg

Kalm — бесплатное приложение с открытым исходным кодом. Представляет собой стандартный контроллер Kubernetes, который можно установить в любой кластер (версии v1.15 и выше), включая Amazon EKS и Google GKE. Основная цель Kalm — предоставить разработчикам простой пользовательский интерфейс, чтобы упростить работу с K8s.

Приложение написано преимущественно на Go и TypeScript. Проект был анонсирован год назад, и на данный момент у него всего ~350 звезд на GitHub. Формальный статус — Closed Beta, однако публичной информации достаточно, чтобы все желающие уже могли поучаствовать в его тестировании.

Ключевые возможности Kalm

Kalm — это Kubernetes Application Manager, графический интерфейс, предназначенный для простого развертывания и управления приложениями в Kubernetes. Утилита работает «из коробки» с любым существующим кластером. Установка занимает около 5 минут.

Главные фичи, выделяемые разработчиками:

  • WebUI. Создание и обновление Deployment«ов, сетей, переменных окружения, ConfigMaps и Secrets. Отслеживание состояния приложений, чтение логов, управление контейнерами.

  • SSO и пользователи. Разграничение доступа к ресурсам кластера через внутреннюю аутентификацию, работающую по принципу single sign-on (SSO).

  • Выпуск LE-сертификатов. Настройка и автоматическое продление SSL-сертификатов для вашего приложения. Поддержка автоматического выпуска wildcard SSL.

  • Управление трафиком. Kalm умеет направлять трафик из нескольких доменов/поддоменов в один или множество Deployment«ов. Можно обслуживать внешний трафик или настроить более сложные схемы — например, blue-green и canary-развертывание.

  • Webhooks. С помощью вебхуков можно обновлять или откатывать Deployment«ы. Это полезно для быстрой интеграции с такими инструментами для CI/CD, как GitHub Actions или CircleCI.

Установка и первый запуск

Для начала нужно создать кластер Kubernetes. Чтобы сделать это локально, авторы предлагают воспользоваться minikube, K3s и Kind, а для облака — EKS или GKE. Для каждого типа инфраструктуры с K8s есть своя инструкция по установке Kalm.

К слову, также для облачных кластеров доступна платная услуга — Kalm Cloud. Это специальная онлайн-панель для управления приложениями в кластерах, предусматривающая минимальные действия по установке/конфигурации Kalm и техническую поддержку. Тарифы по работе с Kalm Cloud есть здесь: вкратце, они начинаются от 600 USD в месяц, но стартапы могут получить скидку в 90% на год.

Теперь к самой установке. Перед её началом убедитесь, что kubectl указывает на правильный кластер Kubernetes, так как установка производится в текущий контекст kubectl (через apply).

Я выбрал minikube. Установка выполняется в два шага. Сначала клонируем репозиторий:

# clone the repo
git clone https://github.com/kalmhq/kalm.git
cd kalm

Затем устанавливаем утилиту:

./scripts/install-local-mode.sh

В кластере при этом у нас развернулось несколько компонентов:

Стоит обратить внимание, что непосредственно управлять кластером при помощи Kalm нельзя, но можно заходить в контейнеры, выполнять команды, править ConfigMaps и т.д. По кластеру можно также видеть служебную информацию: общее количество потребляемых ресурсов, нагруженность каждого узла в кластере, потребление ресурсов отдельными приложениями.

Если в кластер уже установлены какие-то приложения, в Kalm они отображаться не будут. Утилита понимает только свой синтаксис и «видит» приложения, установленные только через kalm-operator.

После установки пробрасываем порт из кластера в localhost:

kubectl port-forward -n kalm-system $(kubectl get pod -n kalm-system -l app=kalm -ojsonpath="{.items[0].metadata.name}") 3010:3010

Если установка прошла успешно, дашборд Kalm будет доступен по адресу http://localhost:3010.

Если возникли проблемы с запуском, не лишним будет заглянуть в этот раздел документации.

Знакомство с интерфейсом

Интерфейс Kalm — простой и понятный. Первое, что мы видим — возможность создать новый namespace (здесь эта операция называется Create App) и информацию по развернутым приложениям.

image-loader.svg

Дополнительные сведения

В Nodes выводится информация о ресурсах кластера и его узлах:

image-loader.svg

А в Disks — информация по созданным дискам для компонентов приложения:

image-loader.svg

Настройки

Другие вкладки позволяют настроить:

  • Domain & Certs — домены и SSL-сертификаты для них;

  • Routes — маршруты для созданного нами домена;

  • WebHooks — вубхуки. Есть интеграция с GitHub и CircleCI (можно настроить хук на обновление приложения при обновлении образа);

  • Pull Secrets — доступ к registry с авторизацией, чтобы образы для Pod«ов загружались из него;

  • SSO & Members — авторизацию (через Dex) и доступ к определенным ресурсам для определенного пользователя.

Запуск приложения

Выполним первый запуск приложения через WebUI на примере WordPress.

Для создания namespace во вкладке Kalm/Apps нажмем на уже упомянутую Create App:

image-loader.svg

  1. Укажем имя приложения, образ, из которого оно будет запускаться, его тип и количество реплик. Тип компонента выбирается из значений Server (соответствует Deployment), DaemonSet, CronJob и StatefulSet.

  2. Далее можно указать requests и limits для CPU и Memory, а также добавить Node Selector.

  3. Если необходимо, используем дополнительные настройки, разнесенные по вкладкам:

image-loader.svg

  • Config — команда для запуска компонента, переменные окружения, файлы конфигурации для компонента.

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

  • Disk — диски для компонентов. На выбор предоставляются постоянные диски в виде PVC и временные (emptyDir). Также можно добавить уже используемый диск и расшарить данные между компонентами. Если у вас есть несколько storage classes, можно выбрать нужный.

  • Health — readiness- и liveness-пробы для проверки работоспособности приложения. Пробы могут быть трех типов: HTTP, Command и TCP.

  • Deployment Strategy — стратегию обновления компонентов. По умолчанию это Rolling Update, но можно поменять на Recreate. Предусмотрена возможность отложить принудительную остановку Pod«а указанием graceful termination period.

Перед запуском самого WordPress добавляем сначала его Pod с БД MySQL. Указываем название Pod«а, переменные окружения, порт MySQL, по которому сможем подключиться к базе, и другие параметры.

image-loader.svgimage-loader.svgimage-loader.svgimage-loader.svg

После этого нажимаем на Deploy Component.

Аналогично добавляем Pod с самим WordPress:

image-loader.svgimage-loader.svgimage-loader.svgimage-loader.svg

И снова — Deploy Component (на скриншоте это Update Component, потому что я затем менял параметры).

Чтобы увидеть запущенное приложение в браузере, можно пробросить порт из SVC на localhost и зайти на этот порт:

kubectl -n wordpress port-forward service/wordpress 9001:9001

Переходим в браузере по адресу http://localhost:9001 — нас встречает стартовая страница настройки WordPress!

image-loader.svg

Запуск консоли и просмотр логов

После того, как мы запустили приложения, их можно увидеть во вкладке Apps/Component как Pod«ы.

image-loader.svg

Если перейти на вкладкуApps/Dashboard, там можно увидеть 3 вкладки:

  • Workload — информация по запущенным Pod«ам и количеству маршрутов;

  • Metrics — информация по трафику и ответам от приложения;

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

Также можно полностью удалить namespace во вкладке Apps/Settings:

image-loader.svg

Вернемся на вкладку Apps/Components. В столбце Actions можно перейти к детальной информации о Pod«е и поменять настройки его контейнера. Нажимаем на детали и получаем 4 вкладки:

  • Basic — общая информация и настройки Pod«а;

  • Pods — список запущенных Pod«ов, общая информация по ним. Если провалиться в консоль, можно получить логи контейнера и удалить Pod;

  • Networking — список настроенных портов для Pod«а и адрес, по которому можно обратиться к нему;

  • Routes — список настроенных маршрутов.

Давайте посмотрим логи контейнера и консоль контейнера. Зайдем во вкладку Podsв Apps/Components/.

image-loader.svg

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

Также для просмотра логов в Kalmможно установить PLG-стек (Promtail, Loki и Grafana). Подробно о настройке PLG рассказано в официальной документации.

Как запущенное приложение выглядит в кластере

Если после нажатия на Deploy Component зайти через консоль в кластер, можно увидеть, что добавленное приложение — это отдельный namespace, а компонент — отдельный Deployment:

> kubectl get ns 
NAME                 STATUS   AGE
cert-manager        Active   
default                  Active   
istio-operator        Active   
istio-system          Active   
kalm-operator       Active   
kalm-system         Active   
kube-node-lease  Active   
kube-public          Active   
kube-system        Active   
wordpress            Active   

> kubectl -n wordpress get deployment
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
wordpress   1/1         1                       1                    

> kubectl -n wordpress get pods
NAME                                    READY   STATUS    RESTARTS   AGE
mysql-0                                      2/2        Running        0              
wordpress-64b8587cf9-drmgb   2/2        Running       0               

> kubectl -n wordpress get svc
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
mysql                   ClusterIP   10.102.100.85                  3306/TCP   
mysql-headless   ClusterIP    None                                3306/TCP   
wordpress            ClusterIP   10.99.135.229                  9001/TCP   

> kubectl -n wordpress get pvc
NAME             |STATUS|VOLUME|CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-mysql       | Bound   |pvc         |   1Gi             RWO                     standard              
pvc-wordpress| Bound  |pvc          |   1Gi             RWO                     standard              

Другие особенности

Custom Resources Definitions

Помимо запуска через WebUI есть также возможность запуска сущностей через Custom Resources. Вот что на данный момент может предложить Kalm:

  • Component— запуск компонента в указанном namespace;

  • ProtectedEndpoint— запуск EndPoint, которому необходима авторизация;

  • SingleSignOnConfig— настройка SSO для доступа к Kalm dashboard через Dex provider (GitLab, GitHub и т.п.);

  • HTTPRoute— настройка маршрута к SVC в кластере;

  • Httpscert— настройка сертификата X.509;

  • HttpsCertIssuer— настройка выпуск сертификата под определенным провайдером;

  • AccessToken — выпуск токена для вебхуков и настройка прав доступа для данного токена;

  • RoleBinding— настройка ролей для пользователей или групп;

  • ACMEServer— определение ACMEDNS-сервера в кластере.

Пример использования Custom Resources при создании компонента с помощью обычного файла-манифеста:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
  namespace: default
  labels:
    app: hello-world
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - image: kalmqh/echosever
        name: hello-world
---
apiVersion: v1
kind: Service
metadata:
  name: hello-world
  namespace: default
spec:
  selector:
    app: hello-world
  ports:
    - port: 80
      targetPort: 8001

И тот же кейс —, но с использованием Custom Resources от Kalm:

apiVersion: core.kalm.dev/v1alpha1
kind: Component
metadata:
  name: hello-world
  namespace: test
spec:
  replicas: 1
  workloadType: server
  image: kalmhq/echoserver
  ports:
    - containerPort: 8001
      protocol: http
      servicePort: 8001

Важно: при создании в namespace: default вы не увидите его в панели Kalm, так как этот namespace не отображается в WebUI на вкладке Apps.

Управление трафиком

Для реализации одной из главных фич решения — управления трафиком ­— в Kalm интегрирован известный service mesh: Istio. Его конфигурация в рамках тех же Custom Resources на данный момент не реализована, хотя в документации упоминаются ресурсы HttpRoute и HttpsCert как нечто, что должно стать вскоре доступным (TODO) для решения наиболее типовых задач. На данный момент возможен только прямой доступ к настройке Istio, если такие навыки и потребности есть.

Про сам Istio мы неоднократно рассказывали в блоге, поэтому заострять внимание на его возможностях в этом обзоре я не буду.

Аутентификация и авторизация

Kalm предоставляет доступ к WebUI при помощи единой точки входа. Стандартная схема по умолчанию — SSO.

image-loader.svg

Для обращения к kalm-api можно использовать токен доступа — это тоже CRD (Custom Resource Definition). Для этого токена можно ограничить доступ только к определенным ресурсам в кластере, которые предоставляются Kalm.

Также можно настраивать роли для определенного пользователя или группы и разграничивать доступ для всех предоставляемых Kalm ресурсов в кластере. Вот таблица со всеми возможными ролями.

На скриншоте ниже — новый пользователь test-user, для которого в WebUI настраивается кластерная роль, и отдельно — роль для каждого из приложений. Также можно проверить настроенные ограничения и выданные права.

image-loader.svg

Заключение

Kalm может быть полезен для локальной разработки, если у разработчика нет опыта работы с Kubernetes или знания о нем минимальны. Можно развернуть, например, инсталляцию minikube + Kalm и проверить работоспособность своего приложения в Kubernetes. При этом вместо консоли использовать удобную веб-панель с простым интерфейсом.

Если сравнивать решение с привычным kubectl в контексте реального обслуживания кластера, на мой взгляд, возможности Kalm ограничены. Kalm предназначен для управления приложениями в кластере и трафиком. Ресурсы можно разворачивать только через собственный CRD.

Есть и мелкие недочеты — например, нет возможности просмотра всех namespace«ов в кластере, которые не созданы Kalm (хотя если посмотреть на использование ресурсов, там учитываются все Pod«ы, запущенные в кластере). Или — при локальном использовании нельзя прокинуть в хост-систему порт из панели Kalm, из-за чего приходится использовать port-forward… Вдобавок, поскольку Kalm пока еще в статусе Closed Beta, его использование в production не рекомендуется. Как вариант, можно поднять небольшой проект и посмотреть на его работу в тестовом режиме.

Видно, что разработчики уделяют внимание не только развитию самого проекта, но и постоянно улучшают документацию (впрочем, не везде её хватает). Можно надеяться, что Kalm будет расширять и функциональность, и аудиторию.

Напоследок, отдельного упоминания стоит недавний анонс другого решения от тех же авторов — Koncrete. Оно продвигается как готовый к работе (уже развернутый и настроенный в облаке) ArgoCD.

P.S.

Читайте также в нашем блоге:

© Habrahabr.ru