title background

Статьи / Запуск Camunda BPM в Kubernetes

05.08.2020 г., перевод статьи Alastair Firth, Lars Lange

Используете Kubernetes? Готовы переместить свои экземпляры Camunda BPM с виртуальных машин, а может просто попробовать запустить их на Kubernetes? Давайте рассмотрим некоторые распространенные конфигурации и отдельные элементы, которые можно адаптировать к вашим конкретным потребностям.

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

Авторы

  • Аластер Фёрт (Alastair Firth) — старший инженер по надежности сайта (Site Reliability Engineer) в команде Camunda Cloud;
  • Ларс Ланге (Lars Lange) — DevOps-инженер в Camunda.

Если коротко, то:

git clone https://github.com/camunda-cloud/camunda-examples.git cd camunda-examples/camunda-bpm-demo make skaffold

Ладно, скорее всего это не сработало, так как у вас не установлены skaffold и kustomize. Ну тогда читайте дальше!

Что такое Camunda BPM

Camunda BPM — это платформа с открытым исходным кодом для управления бизнес-процессами и автоматизации принятия решений, которая объединяет бизнес-пользователей и разработчиков программного обеспечения. Она идеально подходит для координации и объединения людей, (микро) сервисов или даже ботов! Прочитать больше о различных вариантах использования можно по ссылке.

Зачем использовать Kubernetes

Kubernetes стал стандартом де-факто для запуска современных приложений в Linux. Благодаря использованию системных вызовов вместо эмуляции аппаратного уровня и возможностям ядра управлять памятью и переключением задач, время загрузки и время запуска сводятся к минимуму. Однако наибольшее преимущество может дать стандартный API-интерфейс, который Kubernetes предоставляет для настройки инфраструктуры, необходимой всем приложениям: хранилище, сеть и мониторинг. В июне 2020 года ему исполнилось 6 лет, и это, пожалуй, второй по величине проект с открытым исходным кодом (после Linux). В последнее время он активно стабилизирует свой функционал после быстрой итерации последних нескольких лет, поскольку это становится критически важным для производственных нагрузок по всему миру.

Camunda BPM Engine может легко подключаться к другим приложениям, работающим в том же кластере, а Kubernetes обеспечивает отличную масштабируемость, позволяя увеличивать затраты на инфраструктуру только тогда, когда это действительно необходимо (и легко сокращать их по мере необходимости).

Качество мониторинга также значительно улучшается с помощью таких инструментов, как Prometheus, Grafana, Loki, Fluentd и Elasticsearch, позволяющих централизованно просматривать все рабочие нагрузки кластера. Сегодня мы рассмотрим, как внедрить экспортера Prometheus в виртуальную машину Java (JVM).

Цели

Давайте рассмотрим несколько областей, в которых мы можем настроить Docker-образ Camunda BPM (github), чтобы он хорошо взаимодействовал с Kubernetes.

  1. Журналы и метрики;
  2. Соединения с базой данных;
  3. Аутентификация;
  4. Управление сессиями.

Мы рассмотрим несколько способов реализации этих целей и наглядно покажем весь процесс.

Примечание: Используете версию Enterprise? Посмотрите здесь и обновите ссылки на образы при необходимости.

Разработка рабочего процесса

Запуск Camunda BPM в Kubernetes

В этой демонстрации мы будем использовать Skaffold для создания образов Docker с помощью Google Cloud Build. Он имеет хорошую поддержку различных инструментов (таких как Kustomize и Helm), CI и инструментов сборки, а также поставщиков инфраструктуры. Файл skaffold.yaml.tmpl включает настройки для Google Cloud Build и GKE, что обеспечивает очень простой способ запуска инфраструктуры промышленного уровня.

make skaffold загрузит контекст Dockerfile в Cloud Build, создаст образ и сохранит его в GCR, а затем применит манифесты к вашему кластеру. Это то, что делает make skaffold, но у Skaffold есть много других возможностей.

Для шаблонов yaml в Kubernetes мы используем kustomize для управления оверлеями yaml без разветвления всего манифеста, что позволяет вам использовать git pull --rebase для дальнейших улучшений. Сейчас он в kubectl и это неплохо работает для таких вещей.

Также мы используем envsubst для заполнения имени хоста и идентификатора проекта GCP в файлах * .yaml.tmpl. Вы можете посмотреть, как это работает в makefile или просто продолжить дальше.

Необходимые условия

  • Рабочий кластер Kubernetes
    • GKE или Minikube — хорошо подойдут для первого раза;
  • Kustomize
  • Skaffold — для создания собственных образов docker и легкого развертывания в GKE
    • скачайте последнюю версию
    • curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && chmod + x skaffold && sudo mv skaffold/usr/local/bin
    • если вы используете Google Cloud build, то:
      • gcloud auth application-default login
      • в противном случае настройте skaffold.yaml.tmpl для своих провайдеров
  • Копия этого кода
    • git clone https://github.com/camunda-cloud/camunda-examples.git
  • Envsubst
    • Установка для OSX
    • Для Linux установить gettext с помощью пакетного менеджера
    • используется в демонстрации, чтобы избежать жесткого кодирования имен хостов и идентификаторов облачных проектов

Рабочий процесс с помощью манифестов

Если вы не хотите использовать kustomize или skaffold, вы можете обратиться к манифестам в generated-manifest.yaml и адаптировать их к рабочему процессу по вашему выбору.

Журналы и метрики

Prometheus стал стандартом для сбора метрик в Kubernetes. Он занимает ту же нишу, что и AWS Cloudwatch Metrics, Cloudwatch Alerts, Stackdriver Metrics, StatsD, Datadog, Nagios, vSphere Metrics и другие. У него открытый исходный код и мощный язык запросов. Визуализацию возложим на Grafana — оно поставляется с большим количество панелей мониторинга, доступных из коробки. Они связаны друг с другом и относительно просты в установке с prometheus-operator.

По умолчанию Prometheus использует модель извлечения <service>/metrics, и добавление sidecar-контейнеров для этого является обычным явлением. К сожалению, метрики JMX лучше всего регистрируются внутри JVM, поэтому sidecar-контейнеры не так эффективны. Давайте подключим jmx_exporter с открытым исходным кодом от Prometheus к JVM, добавив его в образ контейнера, который предоставит путь /metrics на другом порту.

Добавьте Prometheus jmx_exporter в контейнер

-- images/camunda-bpm/Dockerfile FROM camunda/camunda-bpm-platform:tomcat-7.11.0 ## Add prometheus exporter RUN wget https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.11.0/jmx_prometheus_javaagent-0.11.0.jar -P lib/ #9404 is the reserved prometheus-jmx port ENV CATALINA_OPTS -javaagent:lib/jmx_prometheus_javaagent-0.11.0.jar=9404:/etc/config/prometheus-jmx.yaml

Ну, это было легко. Экспортер будет мониторить tomcat и отображать его метрики в формате Prometheus по адресу <svc>:9404/metrics

Настройка экспортера

Внимательный читатель может задаться вопросом, а откуда взялся prometheus-jmx.yaml? Существует много разных вещей, которые могут работать в JVM, и tomcat — это только одна из них, поэтому экспортер нуждается в некоторой дополнительной настройке. Стандартные конфигурации для tomcat, wildfly, kafka и так далее доступны здесь. Мы добавим tomcat как ConfigMap в Kubernetes, а затем смонтируем его как том.

Во-первых, мы добавляем файл конфигурации экспортера в нашу директорию platform/config/

platform/config └── prometheus-jmx.yaml

Затем мы добавляем ConfigMapGenerator в kustomization.yaml.tmpl:

-- platform/kustomization.yaml.tmpl apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization [...] configMapGenerator: - name: config files: - config/prometheus-jmx.yaml

Это добавит каждый элемент files[] в качестве элемента конфигурации ConfigMap. ConfigMapGenerators хороши тем, что они хэшируют данные в конфигурации и инициируют перезапуск пода, если он изменяется. Они также уменьшают объем конфигурации в Deployment, поскольку вы можете смонтировать всю «папку» файлов конфигурации в одной VolumeMount.

Наконец, нам нужно смонтировать ConfigMap как том к поду:

-- platform/deployment.yaml apiVersion: apps/v1 kind: Deployment [...] spec: template: spec: [...] volumes: - name: config configMap: name: config defaultMode: 0744 containers: - name: camunda-bpm volumeMounts: - mountPath: /etc/config/ name: config [...]

Прекрасно. Если Prometheus не настроен для полной очистки, вам, возможно, придется сказать ему, чтобы он очистил поды. Пользователи Prometheus Operator могут использовать service-monitor.yaml для начала работы. Изучите Service-monitor.yaml, operator design и ServiceMonitorSpec перед тем как приступить.

Распространение этого шаблона на другие варианты использования

Все файлы, которые мы добавляем в ConfigMapGenerator, будут доступны в новом каталоге /etc/config. Вы можете расширить этот шаблон для монтирования любых других необходимых вам конфигурационных файлов. Вы даже можете смонтировать новый сценарий запуска. Можете использовать subPath для монтирования отдельных файлов. Для обновления xml-файлов рассмотрите возможность использования xmlstarlet вместо sed. Он уже включен в образ.

Журналы

Отличные новости! Журналы приложений уже доступны на stdout, например, с помощью kubectl logs. Fluentd (он установлен по умолчанию в GKE) перенаправит ваши журналы в Elasticsearch, Loki или на вашу корпоративную платформу журналов. Если вы хотите использовать jsonify для журналов, то можете следовать приведенному выше шаблону для установки logback.

База данных

По умолчанию образ будет иметь базу данных H2. Нам это не подходит, и мы будем использовать Google Cloud SQL с Cloud SQL Proxy — это понадобится потом для решения внутренних задач. Это простой и надежный вариант, если у вас нет собственных предпочтений в настройке базы данных. AWS RDS предоставляет аналогичную услугу.

Независимо от выбранной вами базы данных, если только это не H2, вам нужно будет установить соответствующие переменные среды в platform/deploy.yaml. Это выглядит примерно так:

-- platform/deployment.yaml apiVersion: apps/v1 kind: Deployment [...] spec: template: spec: [...] containers: - name: camunda-bpm env: - name: DB_DRIVER value: org.postgresql.Driver - name: DB_URL value: jdbc:postgresql://postgres-proxy.db:5432/process-engine - name: DB_USERNAME valueFrom: secretKeyRef: name: cambpm-db-credentials key: db_username - name: DB_PASSWORD valueFrom: secretKeyRef: name: cambpm-db-credentials key: db_password [...]

Примечание: Можете использовать Kustomize для развертывания в различных средах с использованием оверлея: пример.

Примечание: использование valueFrom: secretKeyRef. Пожалуйста, используйте эту функцию Kubernetes даже во время разработки, чтобы сохранить свои секреты в безопасности.

Вполне вероятно, что у вас уже есть предпочтительная система управления секретами Kubernetes. Если нет, то вот некоторые варианты: шифрование их с помощью KMS вашего облачного провайдера, а затем внедрение их в K8S в качестве секретов через CD-конвейер — MozillaSOPS — будет очень хорошо работать в сочетании с секретами Kustomize. Есть и другие инструменты, такие как dotGPG — они выполняют аналогичные функции: HashiCorp Vault, Kustomize Secret Value Plugins.

Ingress

Если только вы не решите использовать переадресацию локального порта, вам понадобится настроенный Ingress Controller. Если вы не используете ingress-nginx (Helm chart) то, скорее всего, уже знаете, что вам нужно установить необходимые аннотации в ingress-patch.yaml.tmpl или platform/ingress.yaml. Если вы используете ingress-nginx и видите nginx ingress class с балансировщиком нагрузки, указывающим на него и внешний DNS или запись подстановочного DNS, — все готово. В противном случае настройте Ingress Controller и DNS или пропустите эти шаги и оставьте прямое подключение к поду.

TLS

Если вы используете cert-manager или kube-lego и letsencrypt — сертификаты для нового входа будут получены автоматически. В противном случае, откройте ingress-patch.yaml.tmpl и настройте его под свои нужды.

Запуск!

Если вы придерживались всего написанного выше, то команда make skaffold HOSTNAME=<you.example.com> должна запустить доступный экземпляр в <hostname>/camunda

Если вы не выставили вход через публичный URL-адрес, то можете переадресовать его с localhost: kubectl port-forward -n camunda-bpm-demo svc/camunda-bpm 8080:8080 на localhost:8080/camunda

Подождите несколько минут, пока tomcat полностью будет готов. Cert-manager понадобится некоторое время для проверки доменного имени. После этого вы можете следить за журналами с помощью доступных средств — например, такого инструмента, как kubetail, или же просто с помощью kubectl:

kubectl logs -n camunda-bpm-demo $(kubectl get pods -o=name -n camunda-bpm-demo) -f

Следующие шаги

Авторизация

Это больше относится к настройке Camunda BPM, чем к Kubernetes, но важно отметить, что по умолчанию в REST API аутентификация отключена. Можете включить базовую аутентификацию или использовать другой метод, например JWT. Вы можете использовать configmaps и тома для загрузки xml, или xmlstarlet (см. выше) для редактирования существующих файлов в образе, а также либо использовать wget, либо загружать их с помощью контейнера init и общего тома.

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

Как и многие другие приложения, Camunda BPM обрабатывает сессии в JVM, поэтому, если вы хотите запустить несколько реплик, вы можете включить sticky sessions (например, для ingress-nginx), которые будут существовать до тех пор, пока реплика не исчезнет, или задать атрибут Max-Age для файлов cookie. В качестве более надежного решения можно развернуть Session Manager в Tomcat. У Ларса есть отдельный пост на эту тему, но что-то вроде:

wget http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/2.3.2/memcached-session-manager-2.3.2.jar -P lib/ && \ wget http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager-tc9/2.3.2/memcached-session-manager-tc9-2.3.2.jar -P lib/ && \ sed -i '/^<\/Context>/i \ <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" \ memcachedNodes="redis://redis-proxy.db:22121" \ sticky="false" \ sessionBackupAsync="false" \ storageKeyPrefix="context" \ lockingMode="auto" \ />' conf/context.xml

Примечание: можно использовать xmlstarlet вместо sed

Мы использовали twemproxy перед Google Cloud Memorystore, с memcached-session-manager (поддерживает Redis) для его запуска.

Масштабирование

Если вы уже разобрались с сессиями, то первым (и часто последним) ограничением для масштабирования Camunda BPM может стать подключение к базе данных. Частичная настройка доступна уже «из коробки». Также отключим intialSize в файле settings.xml. Добавьте HorizontalPodAutoscaler (HPA) и вы сможете легко автоматически масштабировать количество подов.

Запросы и ограничения

В platform/deployment.yaml вы увидите, что мы жестко закодировали поле ресурсов. Это хорошо работает с HPA, но может понадобиться дополнительная настройка. Для этого подойдет патч kustomize. См. ingress-patch.yaml.tmpl и ./kustomization.yaml.tmpl

Вывод

Вот мы и установили Camunda BPM на Kubernetes с метриками Prometheus, журналами, базой данных H2, TLS и Ingress. Мы добавили файлы jar и файлы конфигурации, используя ConfigMaps и Dockerfile. Мы поговорили об обмене данными с томами и непосредственно в переменные среды из секретов. Кроме этого, предоставили обзор настройки Camunda для нескольких реплик и аутентифицированного API.

Ссылки

github.com/camunda-cloud/camunda-examples/camunda-bpm-kubernetes │ ├── generated-manifest.yaml <- manifest for use without kustomize ├── images │ └── camunda-bpm │ └── Dockerfile <- overlay docker image ├── ingress-patch.yaml.tmpl <- site-specific ingress configuration ├── kustomization.yaml.tmpl <- main Kustomization ├── Makefile <- make targets ├── namespace.yaml ├── platform │ ├── config │ │ └── prometheus-jmx.yaml <- prometheus exporter config file │ ├── deployment.yaml <- main deployment │ ├── ingress.yaml │ ├── kustomization.yaml <- "base" kustomization │ ├── service-monitor.yaml <- example prometheus-operator config │ └── service.yaml └── skaffold.yaml.tmpl <- skaffold directives