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
В кластере при этом у нас развернулось несколько компонентов:
istio-operator + сам Istio;
kalm-operator + Kalm;
cert-manager.
Стоит обратить внимание, что непосредственно управлять кластером при помощи 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) и информацию по развернутым приложениям.
Дополнительные сведения
В Nodes выводится информация о ресурсах кластера и его узлах:
А в Disks — информация по созданным дискам для компонентов приложения:
Настройки
Другие вкладки позволяют настроить:
Domain & Certs — домены и SSL-сертификаты для них;
Routes — маршруты для созданного нами домена;
WebHooks — вубхуки. Есть интеграция с GitHub и CircleCI (можно настроить хук на обновление приложения при обновлении образа);
Pull Secrets — доступ к registry с авторизацией, чтобы образы для Pod’ов загружались из него;
SSO & Members — авторизацию (через Dex) и доступ к определенным ресурсам для определенного пользователя.
Запуск приложения
Выполним первый запуск приложения через WebUI на примере WordPress.
Для создания namespace во вкладке Kalm/Apps нажмем на уже упомянутую Create App:
Укажем имя приложения, образ, из которого оно будет запускаться, его тип и количество реплик. Тип компонента выбирается из значений Server (соответствует Deployment), DaemonSet, CronJob и StatefulSet.
Далее можно указать requests и limits для CPU и Memory, а также добавить Node Selector.
Если необходимо, используем дополнительные настройки, разнесенные по вкладкам:
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, по которому сможем подключиться к базе, и другие параметры.
После этого нажимаем на Deploy Component.
Аналогично добавляем Pod с самим WordPress:
И снова — Deploy Component (на скриншоте это Update Component, потому что я затем менял параметры).
Чтобы увидеть запущенное приложение в браузере, можно пробросить порт из SVC на localhost и зайти на этот порт:
kubectl -n wordpress port-forward service/wordpress 9001:9001
Переходим в браузере по адресу http://localhost:9001 — нас встречает стартовая страница настройки WordPress!
Запуск консоли и просмотр логов
После того, как мы запустили приложения, их можно увидеть во вкладке Apps/Component как Pod’ы.
Если перейти на вкладку Apps/Dashboard, там можно увидеть 3 вкладки:
Workload — информация по запущенным Pod’ам и количеству маршрутов;
Metrics — информация по трафику и ответам от приложения;
Warnings — предупреждения в событиях компонента.
Также можно полностью удалить namespace во вкладке Apps/Settings:
Вернемся на вкладку Apps/Components. В столбце Actions можно перейти к детальной информации о Pod’е и поменять настройки его контейнера. Нажимаем на детали и получаем 4 вкладки:
Basic — общая информация и настройки Pod’а;
Pods — список запущенных Pod’ов, общая информация по ним. Если провалиться в консоль, можно получить логи контейнера и удалить Pod;
Networking — список настроенных портов для Pod’а и адрес, по которому можно обратиться к нему;
Routes — список настроенных маршрутов.
Давайте посмотрим логи контейнера и консоль контейнера. Зайдем во вкладку Pods в Apps/Components/<name>.
Проваливаемся в логи, нажав на соответствующую иконку. В открывшейся странице можно выбрать несколько Pod’ов, затем выбрать контейнер, логи которого нужно посмотреть, и количество отображаемых строк логов. Можно выбирать несколько Pod’ов и переключаться между ними для просмотра логов.
Также для просмотра логов в Kalm можно установить PLG-стек (Promtail, Loki и Grafana). Подробно о настройке PLG рассказано в официальной документации.
Как запущенное приложение выглядит в кластере
Если после нажатия на Deploy Component зайти через консоль в кластер, можно увидеть, что добавленное приложение — это отдельный namespace, а компонент — отдельный Deployment:
> kubectl get ns
NAME STATUS AGE
cert-manager Active <age>
default Active <age>
istio-operator Active <age>
istio-system Active <age>
kalm-operator Active <age>
kalm-system Active <age>
kube-node-lease Active <age>
kube-public Active <age>
kube-system Active <age>
wordpress Active <age>
> kubectl -n wordpress get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
wordpress 1/1 1 1 <age>
> kubectl -n wordpress get pods
NAME READY STATUS RESTARTS AGE
mysql-0 2/2 Running 0 <age>
wordpress-64b8587cf9-drmgb 2/2 Running 0 <age>
> kubectl -n wordpress get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql ClusterIP 10.102.100.85 <none> 3306/TCP <age>
mysql-headless ClusterIP None <none> 3306/TCP <age>
wordpress ClusterIP 10.99.135.229 <none> 9001/TCP <age>
> kubectl -n wordpress get pvc
NAME |STATUS|VOLUME|CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-mysql | Bound |pvc | 1Gi RWO standard <age>
pvc-wordpress| Bound |pvc | 1Gi RWO standard <age>
Другие особенности
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.
Для обращения к kalm-api можно использовать токен доступа — это тоже CRD (Custom Resource Definition). Для этого токена можно ограничить доступ только к определенным ресурсам в кластере, которые предоставляются Kalm.
Также можно настраивать роли для определенного пользователя или группы и разграничивать доступ для всех предоставляемых Kalm ресурсов в кластере. Вот таблица со всеми возможными ролями.
На скриншоте ниже — новый пользователь test-user, для которого в WebUI настраивается кластерная роль, и отдельно — роль для каждого из приложений. Также можно проверить настроенные ограничения и выданные права.
Заключение
Kalm может быть полезен для локальной разработки, если у разработчика нет опыта работы с Kubernetes или знания о нем минимальны. Можно развернуть, например, инсталляцию minikube + Kalm и проверить работоспособность своего приложения в Kubernetes. При этом вместо консоли использовать удобную веб-панель с простым интерфейсом.
Если сравнивать решение с привычным kubectl
в контексте реального обслуживания кластера, на мой взгляд, возможности Kalm ограничены. Kalm предназначен для управления приложениями в кластере и трафиком. Ресурсы можно разворачивать только через собственный CRD.
Есть и мелкие недочеты — например, нет возможности просмотра всех namespace’ов в кластере, которые не созданы Kalm (хотя если посмотреть на использование ресурсов, там учитываются все Pod’ы, запущенные в кластере). Или — при локальном использовании нельзя прокинуть в хост-систему порт из панели Kalm, из-за чего приходится использовать port-forward… Вдобавок, поскольку Kalm пока еще в статусе Closed Beta, его использование в production не рекомендуется. Как вариант, можно поднять небольшой проект и посмотреть на его работу в тестовом режиме.
Видно, что разработчики уделяют внимание не только развитию самого проекта, но и постоянно улучшают документацию (впрочем, не везде её хватает). Можно надеяться, что Kalm будет расширять и функциональность, и аудиторию.
Напоследок, отдельного упоминания стоит недавний анонс другого решения от тех же авторов — Koncrete. Оно продвигается как готовый к работе (уже развернутый и настроенный в облаке) ArgoCD.
P.S.
Читайте также в нашем блоге: