В поиске оптимального, бесплатного, простого дашбордного решения? Superset. Вот руководство по его установке для Kubernetes.

Я работаю архитектором ПО в разных компаниях. Один клиент сейчас делает на Power BI диаграммы бизнес-аналитики и раздает их коллегам в компании.

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

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

Superset с более чем 59 000 звезд на GitHub

Вот требования клиента:

  • ПО с открытым кодом;
  • добавление новых пользовательских коннекторов для пользовательских служб;
  • SQL для запрашивания данных с поддержкой объединения;
  • обмен дашбордами, их встраивание в проекты различных групп пользователей;
  • параметризация дашбордов для разных вариантов применения;
  • большой список типов диаграмм.

Вооружившись этими требованиями, я наткнулся на Superset и захотел попробовать его.

Superset очень легко расширяется системой плагинов и различных коннекторов данных.

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

Легко создаются сложные дашборды

Доступны всевозможные супергибкие диаграммы:

Авторское право: документация Superset

Благодаря интерфейсу без кода сложные диаграммы легко создаются из уже созданных наборов данных:

Авторское право: документация Superset

Очень мощный конструктор запросов

Конструктором запросов создаются сложные наборы данных, из которые затем делают диаграммы:

Авторское право: документация Superset

Superset применяется многими крупными компаниями

В репозитории GitHub также перечислены компании, которыми задействуется Superset:

Руководство по установке Superset в Kubernetes

Superset устанавливается всего двумя командами, вторая команда зависит от superset.yaml  —  основного конфигурационного файла развертывания:

helm repo add superset https://apache.github.io/superset
helm upgrade --install --values superset.yaml superset superset/superset

superset.yaml сохраняется локально в файле на диске

В какие строки вносятся изменения, указано после этого блока кода:

# Значения по умолчанию для Superset.
# Это файл в формате YAML.
# Объявляем переменные, передаваемые в шаблоны.
# Из этого файла для его документирования автоматически генерируется README, см. https://github.com/norwoodj/helm-docs
# Чтобы обновить его, устанавливаем helm-docs и запускаем из корневого каталога этой диаграммы
# -- Указывая название, переопределяем название диаграммы
nameOverride: ~
# -- Указывая название, переопределяем полные названия ресурсов
fullnameOverride: ~
# -- Директива идентификатора пользователя. У этого пользователя должно быть достаточно прав для запуска сценария начальной загрузки
# # В производственной среде не рекомендуется запускать контейнеры от имени администратора. Для большей надежности меняем это значение на другой «UID», например 1000
runAsUser: 0
# -- Указываем используемое название учетной записи службы
serviceAccountName: ~
serviceAccount:
# -- Создаем для Superset пользовательскую учетную запись службы. Если в «create» задано «true» и «serviceAccountName» не указано, используется «superset.fullname».
create: false
annotations: {}
# -- В этом скрипте устанавливаем дополнительные пакеты и выполняем любые другие настройки начальной загрузки
# Для кластеров продакшена рекомендуется создать собственный образ, этот этап выполняется при непрерывной интеграции
# @default -- см. «values.yaml»
bootstrapScript: |
#!/bin/bash
pip3 install chipmunkdb-python-client
if [ ! -f ~/bootstrap ]; then echo "Running Superset with uid {{ .Values.runAsUser }}" > ~/bootstrap; fi
# -- Название секрета для генерирования файла «superset_config.py»
# Внимание: внутри этого секрета обязательно должен быть ключ «superset_config.py» и дополнительно другие файлы
configFromSecret: '{{ template "superset.fullname" . }}-config'
# -- Название секрета для заполнения переменных среды в развернутых подах
# Пригодится для секретных ключей и т. д.
envFromSecret: '{{ template "superset.fullname" . }}-env'
# -- Это может быть список шаблонных строк
envFromSecrets: []
# -- Дополнительные переменные среды́, передаваемые в поды
extraEnv: {}
# Различные настройки gunicorn, см. документацию gunicorn
# https://docs.gunicorn.org/en/stable/settings.html#
# При запуске gunicorn эти переменные используются как флаги
# https://github.com/apache/superset/blob/master/docker/run-server.sh#L22
# Для длительно выполняемых запросов увеличиваем время ожидания.
# GUNICORN_TIMEOUT: 300
# Увеличиваем количество воркеров gunicorn, резко повышаем этим производительность
# См. https://docs.gunicorn.org/en/stable/design.html#how-many-workers
# SERVER_WORKER_AMOUNT: 4
# WORKER_MAX_REQUESTS: 0
# WORKER_MAX_REQUESTS_JITTER: 0
# SERVER_THREADS_AMOUNT: 20
# GUNICORN_KEEPALIVE: 2
# SERVER_LIMIT_REQUEST_LINE: 0
# SERVER_LIMIT_REQUEST_FIELD_SIZE: 0
# OAUTH_HOME_DOMAIN: ..
# # Если белый список не задан, вход выполняется по любому адресу, которым задействуется конечная точка OAuth2.
# # сюда относится любой случайный адрес Gmail, если для веб-приложения OAuth2 задан «External».
# OAUTH_WHITELIST_REGEX: ...
# -- Дополнительные переменные среды́ в формате «RAW», передаваемые в поды
extraEnvRaw: []
# Загружаем пароль БД из другого секрета, например для оператора zalando
# - название: DB_PASS
# valueFrom:
# secretKeyRef:
# название: superset.superset-postgres.credentials.postgresql.acid.zalan.do
# ключ: пароль
# -- Дополнительные переменные среды́, передаваемые как секреты
extraSecretEnv: {}
# MAPBOX_API_KEY: ...
# # API-ключи Google: https://console.cloud.google.com/apis/credentials
# GOOGLE_KEY: ...
# GOOGLE_SECRET: ...
# # С помощью «openssl rand -base64 42» генерируем собственный секретный ключ для шифрования.
# SUPERSET_SECRET_KEY: 'CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET'
# -- Дополнительные файлы для подключения в «/app/pythonpath»
extraConfigs: {}
# import_datasources.yaml: |
# базы данных:
# - allow_file_upload: true
# allow_ctas: true
# allow_cvas: true
# database_name: example-db
# дополнительно: "{\r\n \"metadata_params\": {},\r\n \"engine_params\": {},\r\n \"\
# metadata_cache_timeout\": {},\r\n \"schemas_allowed_for_file_upload\": []\r\n\
# }"
# sqlalchemy_uri: example://example-db.local
# таблицы: []
# -- Дополнительные файлы для подключения в «/app/pythonpath» как секреты
extraSecrets: {}
extraVolumes: []
# - название: customConfig
# configMap:
# название: '{{ template "superset.fullname" . }}-custom-config'
# - название: additionalSecret
# секрет:
# secretName: my-secret
# defaultMode: 0600
extraVolumeMounts: []
# - название: customConfig
# mountPath: /mnt/config
# readOnly: true
# - название: additionalSecret:
# mountPath: /mnt/secret
# -- Словарь переопределений для добавления в конце «superset_config.py», название не важно
# Внимание: очередность не гарантируется
# Файлы передаются в виде helm «--set-file configOverrides.my-override=my-file.py»
configOverrides:
secret: |
SECRET_KEY = 'YOUR_SECRET'
# extend_timeout: |
# # Для длительно выполняемых запросов увеличиваем время ожидания.
# SUPERSET_WEBSERVER_TIMEOUT = ...
# enable_oauth: |
# из «flask_appbuilder.security.manager import (AUTH_DB, AUTH_OAUTH)»
# AUTH_TYPE = AUTH_OAUTH
# OAUTH_PROVIDERS = [
# {
# "name": "google",
# "whitelist": [ os.getenv("OAUTH_WHITELIST_REGEX", "") ],
# "icon": "fa-google",
# "token_key": "access_token",
# "remote_app": {
# "client_id": os.environ.get("GOOGLE_KEY"),
# "client_secret": os.environ.get("GOOGLE_SECRET"),
# "api_base_url": "https://www.googleapis.com/oauth2/v2/",
# "client_kwargs": {"scope": "email profile"},
# "request_token_url": None,
# "access_token_url": "https://accounts.google.com/o/oauth2/token",
# "authorize_url": "https://accounts.google.com/o/oauth2/auth",
# "authorize_params": {"hd": os.getenv("OAUTH_HOME_DOMAIN", "")}
# }
# }
# ]
# # Сопоставляем роли Authlib с ролями Superset
# AUTH_ROLE_ADMIN = 'Admin'
# AUTH_ROLE_PUBLIC = 'Public'
# # Разрешается саморегистрация с созданием из авторизованного пользователя пользователей Flask
# AUTH_USER_REGISTRATION = True
# # Роль саморегистрации пользователя по умолчанию
# AUTH_USER_REGISTRATION_ROLE = "Admin"
# секрет: |
# # С помощью «openssl rand -base64 42» генерируем собственный секретный ключ для шифрования.
# SECRET_KEY = 'CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET'
# -- То же, но с файлами в качестве значений
configOverridesFiles: {}
# extend_timeout: extend_timeout.py
# enable_oauth: enable_oauth.py
configMountPath: "/app/pythonpath"
extraConfigMountPath: "/app/configs"
image:
repository: apachesuperset.docker.scarf.sh/apache/superset
tag: ~
pullPolicy: IfNotPresent
imagePullSecrets: []
initImage:
repository: apache/superset
tag: dockerize
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 8088
annotations: {}
# cloud.google.com/load-balancer-type: "Internal"
loadBalancerIP: ~
nodePort:
# -- (int)
http: nil
ingress:
enabled: false
ingressClassName: ~
annotations: {}
# kubernetes.io/tls-acme: "true"
## Для длительно выполняемых запросов увеличиваем время ожидания.
# nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
# nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
# nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
path: /
pathType: ImplementationSpecific
hosts:
- chart-example.local
tls: []
extraHostsRaw: []
# - secretName: chart-example-tls
# хосты:
# - chart-example.local
resources: {}
# Обычно мы рекомендуем не указывать ресурсы по умолчанию и оставлять
# пользователям выбор. Так увеличивается вероятность запуска диаграмм в средах с небольшими
# ресурсами, например Minikube. Если указать ресурсы, придется раскомментировать следующие
# подкорректировать их при необходимости и убрать фигурные скобки после «resources:».
# Ограничения ниже применятся ко всем компонентам Superset. Индивидуальные ограничения ресурсов задаются согласно приведенным ниже значениям для подов.
# Этими значениями перезапишется все, что здесь задано.
# ограничения:
# процессор: 100m
# память: 128Mi
# запросы:
# процессор: 100m
# память: 128Mi
# -- Пользовательские «hostAliases» для всех подов Superset
## https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/
hostAliases: []
# - имена хостов:
# - nodns.my.lan
# ip: 18.27.36.45
# Конфигурация узлов Superset
supersetNode:
replicaCount: 1
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
# -- Задается [бюджет перебойной работы подов] для подов «supersetNode», см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
# -- Следует ли создавать бюджет перебойной работы подов
enabled: false
# -- Если задано, «maxUnavailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
minAvailable: 1
# -- Если задано, «minAvailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
maxUnavailable: 1
# -- Команда запуска
# @default -- см. «values.yaml»
command:
- "/bin/sh"
- "-c"
- ". {{ .Values.configMountPath }}/superset_bootstrap.sh; /usr/bin/run-server.sh"
connections:
# -- Меняем в случае применения собственного Redis, затем также задаем «redis.enabled:false»
redis_host: '{{ .Release.Name }}-redis-headless'
redis_port: "6379"
redis_user: ""
# redis_password: superset
redis_cache_db: "1"
redis_celery_db: "0"
# Или SSL-порт, обычно это 6380
# Для применения Redis с SSL обновляем следующее:
redis_ssl:
enabled: false
ssl_cert_reqs: CERT_NONE
# Меняем конфигурацию ниже в случае применения собственного экземпляра PostgresSQL и также задаем «postgresql.enabled:false»
db_host: '{{ .Release.Name }}-postgresql'
db_port: "5432"
db_user: superset
db_pass: superset
db_name: superset
env: {}
# -- Если же значение «true», при каждом обновлении развертывание принудительно перезагружается
forceReload: false
# -- Контейнеры инициализации
# @default -- контейнер в ожидании Postgres
initContainers:
- name: wait-for-postgres
image: "{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}"
imagePullPolicy: "{{ .Values.initImage.pullPolicy }}"
envFrom:
- secretRef:
name: "{{ tpl .Values.envFromSecret . }}"
command:
- /bin/sh
- -c
- dockerize -wait "tcp://$DB_HOST:$DB_PORT" -timeout 120s
# -- Запускаем дополнительные контейнеры в поде «supersetNode»
extraContainers: []
# -- Аннотации добавляемые к развертыванию «supersetNode»
deploymentAnnotations: {}
# -- Метки, добавляемые к развертыванию «supersetNode»
deploymentLabels: {}
# -- Привязка, добавляемая к развертыванию «supersetNode»
affinity: {}
# -- «TopologySpreadConstrains», добавляемые к развертываниям «supersetNode»
topologySpreadConstraints: []
# -- Аннотации, добавляемые к подам «supersetNode»
podAnnotations: {}
# -- Метки, добавляемые к подам «supersetNode»
podLabels: {}
startupProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 15
timeoutSeconds: 1
failureThreshold: 60
periodSeconds: 5
successThreshold: 1
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 15
timeoutSeconds: 1
failureThreshold: 3
periodSeconds: 15
successThreshold: 1
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 15
timeoutSeconds: 1
failureThreshold: 3
periodSeconds: 15
successThreshold: 1
# -- Этими настройками ресурсов для подов «supersetNode» перезаписываются имеющиеся значения из глобального объекта «resources», определенного выше.
resources: {}
# ограничения:
# процессор: 100m
# память: 128Mi
# запросы:
# процессор: 100m
# память: 128Mi
podSecurityContext: {}
containerSecurityContext: {}
strategy: {}
# тип: RollingUpdate
# rollingUpdate:
# maxSurge: 25 %
# maxUnavailable: 25 %
# Конфигурация воркера Celery в Superset
supersetWorker:
replicaCount: 1
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
# -- Задается [бюджет перебойной работы подов] для подов «supersetWorker», см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
# -- Следует ли создавать бюджет перебойной работы подов
enabled: false
# -- Если задано, «maxUnavailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
minAvailable: 1
# -- Если задано, «minAvailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
maxUnavailable: 1
# -- Команда запуска воркера
# @default -- команда «celery worker»
command:
- "/bin/sh"
- "-c"
- ". {{ .Values.configMountPath }}/superset_bootstrap.sh; celery --app=superset.tasks.celery_app:app worker"
# -- Если же значение «true», при каждом обновлении развертывание принудительно перезагружается
forceReload: false
# -- Контейнер инициализации
# @default -- контейнер в ожидании Postgres и Redis
initContainers:
- name: wait-for-postgres-redis
image: "{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}"
imagePullPolicy: "{{ .Values.initImage.pullPolicy }}"
envFrom:
- secretRef:
name: "{{ tpl .Values.envFromSecret . }}"
command:
- /bin/sh
- -c
- dockerize -wait "tcp://$DB_HOST:$DB_PORT" -wait "tcp://$REDIS_HOST:$REDIS_PORT" -timeout 120s
# -- Запускаем дополнительные контейнеры в поде «supersetWorker»
extraContainers: []
# -- Аннотации, добавляемые к развертыванию «supersetWorker»
deploymentAnnotations: {}
# -- Метки, добавляемые к развертыванию «supersetWorker»
deploymentLabels: {}
# -- Привязка, добавляемая к развертыванию «supersetWorker»
affinity: {}
# -- «TopologySpreadConstrains», добавляемые к развертываниям «supersetWorker»
topologySpreadConstraints: []
# -- Аннотации, добавляемые к подам «supersetWorker»
podAnnotations: {}
# -- Метки, добавляемые к подам «supersetWorker»
podLabels: {}
# -- Этими настройками ресурсов для подов «supersetWorker» перезаписываются имеющиеся значения из глобального объекта «resources», определенного выше.
resources: {}
# ограничения:
# процессор: 100m
# память: 128Mi
# запросы:
# процессор: 100m
# память: 128Mi
podSecurityContext: {}
containerSecurityContext: {}
strategy: {}
# тип: RollingUpdate
# rollingUpdate:
# maxSurge: 25 %
# maxUnavailable: 25 %
livenessProbe:
exec:
# -- Команда пробы работоспособности
# @default -- команда «celery inspect ping»
command:
- sh
- -c
- celery -A superset.tasks.celery_app:app inspect ping -d celery@$HOSTNAME
initialDelaySeconds: 120
timeoutSeconds: 60
failureThreshold: 3
periodSeconds: 60
successThreshold: 1
# -- Проб запуска/готовности нет по умолчанию, нам нет дела до времени запуска, ведь трафик им не обслуживается
startupProbe: {}
# -- Проб запуска/готовности нет по умолчанию, нам нет дела до времени запуска, ведь трафик им не обслуживается
readinessProbe: {}
# Надстройка ритмичности Superset для запуска запланированных заданий, таких как отчеты
supersetCeleryBeat:
# -- Это потребуется только для использования оповещений и отчетов
enabled: false
# -- Задается [бюджет перебойной работы подов] для подов «supersetCeleryBeat», см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
# -- Следует ли создавать бюджет перебойной работы подов
enabled: false
# -- Если задано, «maxUnavailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
minAvailable: 1
# -- Если задано, «minAvailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
maxUnavailable: 1
# -- Команда
# @default -- команда «celery beat»
command:
- "/bin/sh"
- "-c"
- ". {{ .Values.configMountPath }}/superset_bootstrap.sh; celery --app=superset.tasks.celery_app:app beat --pidfile /tmp/celerybeat.pid --schedule /tmp/celerybeat-schedule"
# -- Если же значение «true», при каждом обновлении развертывание принудительно перезагружается
forceReload: false
# -- Список контейнеров инициализации
# @default -- контейнер в ожидании Postgres
initContainers:
- name: wait-for-postgres-redis
image: "{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}"
imagePullPolicy: "{{ .Values.initImage.pullPolicy }}"
envFrom:
- secretRef:
name: "{{ tpl .Values.envFromSecret . }}"
command:
- /bin/sh
- -c
- dockerize -wait "tcp://$DB_HOST:$DB_PORT" -wait "tcp://$REDIS_HOST:$REDIS_PORT" -timeout 120s
# -- Запускаем дополнительные контейнеры в подах «supersetCeleryBeat»
extraContainers: []
# -- Аннотации, добавляемые к развертыванию «supersetCeleryBeat»
deploymentAnnotations: {}
# -- Привязка, добавляемая к развертыванию «supersetCeleryBeat»
affinity: {}
# -- «TopologySpreadConstrains», добавляемые к развертываниям «supersetCeleryBeat»
topologySpreadConstraints: []
# -- Аннотации, добавляемые к подам «supersetCeleryBeat»
podAnnotations: {}
# -- Метки, добавляемые к подам «supersetCeleryBeat»
podLabels: {}
# -- Этими настройками ресурсов для подов «CeleryBeat» перезаписываются имеющиеся значения из глобального объекта «resources», определенного выше.
resources: {}
# ограничения:
# процессор: 100m
# память: 128Mi
# запросы:
# процессор: 100m
# память: 128Mi
podSecurityContext: {}
containerSecurityContext: {}
supersetCeleryFlower:
# -- Включается развертывание в Celery flower, пользовательском интерфейсе управления для мониторинга заданий Celery
# Внимание: в Superset 1.x для этого требуется образ Superset с установленным flower<1.0.0, которого нет в образах по умолчанию.
# Версиям flower>=1.0.0 требуется Celery 5+, не поддерживаемые в Superset 1.5
enabled: false
replicaCount: 1
# -- Задается [бюджет перебойной работы подов] для подов «supersetCeleryFlower», см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
# -- Следует ли создавать бюджет перебойной работы подов
enabled: false
# -- Если задано, «maxUnavailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
minAvailable: 1
# -- Если задано, «minAvailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
maxUnavailable: 1
# -- Команда
# @default -- команда «celery flower»
command:
- "/bin/sh"
- "-c"
- "celery --app=superset.tasks.celery_app:app flower"
service:
type: ClusterIP
annotations: {}
loadBalancerIP: ~
port: 5555
nodePort:
# -- (int)
http: nil
startupProbe:
httpGet:
path: /api/workers
port: flower
initialDelaySeconds: 5
timeoutSeconds: 1
failureThreshold: 60
periodSeconds: 5
successThreshold: 1
livenessProbe:
httpGet:
path: /api/workers
port: flower
initialDelaySeconds: 5
timeoutSeconds: 1
failureThreshold: 3
periodSeconds: 5
successThreshold: 1
readinessProbe:
httpGet:
path: /api/workers
port: flower
initialDelaySeconds: 5
timeoutSeconds: 1
failureThreshold: 3
periodSeconds: 5
successThreshold: 1
# -- Список контейнеров инициализации
# @default -- контейнер в ожидании Postgres и Redis
initContainers:
- name: wait-for-postgres-redis
image: "{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}"
imagePullPolicy: "{{ .Values.initImage.pullPolicy }}"
envFrom:
- secretRef:
name: "{{ tpl .Values.envFromSecret . }}"
command:
- /bin/sh
- -c
- dockerize -wait "tcp://$DB_HOST:$DB_PORT" -wait "tcp://$REDIS_HOST:$REDIS_PORT" -timeout 120s
# -- Запускаем дополнительные контейнеры в подах «supersetCeleryFlower»
extraContainers: []
# -- Аннотации, добавляемые к развертыванию «supersetCeleryFlower»
deploymentAnnotations: {}
# -- Привязка, добавляемая к развертыванию «supersetCeleryFlower»
affinity: {}
# -- «TopologySpreadConstrains», добавляемые к развертываниям «supersetCeleryFlower»
topologySpreadConstraints: []
# -- Аннотации, добавляемые к подам «supersetCeleryFlower»
podAnnotations: {}
# -- Метки, добавляемые к подам «supersetCeleryFlower»
podLabels: {}
# -- Этими настройками ресурсов для подов «CeleryBeat» перезаписываются имеющиеся значения из глобального объекта «resources», определенного выше.
resources: {}
# ограничения:
# процессор: 100m
# память: 128Mi
# запросы:
# процессор: 100m
# память: 128Mi
podSecurityContext: {}
containerSecurityContext: {}
supersetWebsockets:
# -- Это потребуется только для использования «GLOBAL_ASYNC_QUERIES» в режиме «ws»
# см. https://github.com/apache/superset/blob/master/CONTRIBUTING.md#async-chart-queries
enabled: false
replicaCount: 1
# -- Задается [бюджет перебойной работы подов] для подов «supersetWebsockets», см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/
podDisruptionBudget:
# -- Следует ли создавать бюджет перебойной работы подов
enabled: false
# -- Если задано, «maxUnavailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
minAvailable: 1
# -- Если задано, «minAvailable» не задается, см. https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget
maxUnavailable: 1
ingress:
path: /ws
pathType: Prefix
image:
# -- Официального образа пока нет, а этот поддерживается сообществом
repository: oneacrefund/superset-websocket
tag: latest
pullPolicy: IfNotPresent
# -- Файл «config.json» передается на сервер, см. https://github.com/apache/superset/tree/master/superset-websocket
# Внимание: конфигурация считывается и из переменных среды́, и у них приоритет, список поддерживаемых переменных см. в https://github.com/apache/superset/blob/master/superset-websocket/src/config.ts
# @default -- см. «values.yaml»
config:
{
"port": 8080,
"logLevel": "debug",
"logToFile": false,
"logFilename": "app.log",
"statsd": { "host": "127.0.0.1", "port": 8125, "globalTags": [] },
"redis":
{
"port": 6379,
"host": "127.0.0.1",
"password": "",
"db": 0,
"ssl": false,
},
"redisStreamPrefix": "async-events-",
"jwtSecret": "CHANGE-ME",
"jwtCookieName": "async-token",
}
service:
type: ClusterIP
annotations: {}
loadBalancerIP: ~
port: 8080
nodePort:
# -- (int)
http: nil
command: []
resources: {}
# -- Запускаем дополнительные контейнеры в подах «supersetWebsockets»
extraContainers: []
deploymentAnnotations: {}
# -- Привязка, добавляемая к развертыванию «supersetWebsockets»
affinity: {}
# -- «TopologySpreadConstrains», добавляемые к развертываниям «supersetWebsockets»
topologySpreadConstraints: []
podAnnotations: {}
podLabels: {}
strategy: {}
podSecurityContext: {}
containerSecurityContext: {}
startupProbe:
httpGet:
path: /health
port: ws
initialDelaySeconds: 5
timeoutSeconds: 1
failureThreshold: 60
periodSeconds: 5
successThreshold: 1
livenessProbe:
httpGet:
path: /health
port: ws
initialDelaySeconds: 5
timeoutSeconds: 1
failureThreshold: 3
periodSeconds: 5
successThreshold: 1
readinessProbe:
httpGet:
path: /health
port: ws
initialDelaySeconds: 5
timeoutSeconds: 1
failureThreshold: 3
periodSeconds: 5
successThreshold: 1
init:
# Настраиваем ресурсы
# Внимание: командой «fab» расходуется много оперативной памяти,
# это чревато завершением процесса из-за нехватки памяти, если превышено ограничение
# Для создания пользователя-администратора вводится надежный пароль или меняется после настройки.
# Почта администратора тоже меняется на пользовательскую.
resources: {}
# ограничения:
# процессор:
# память:
# запросы:
# процессор:
# память:
# -- Команда
# @default -- команда «superset_init.sh»
command:
- "/bin/sh"
- "-c"
- ". {{ .Values.configMountPath }}/superset_bootstrap.sh; . {{ .Values.configMountPath }}/superset_init.sh"
enabled: true
jobAnnotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-delete-policy": "before-hook-creation"
loadExamples: false
createAdmin: true
adminUser:
username: admin
firstname: Superset
lastname: Admin
email: [email protected]
password: admin
# -- Список «initContainers»
# @default -- контейнер в ожидании Postgres
initContainers:
- name: wait-for-postgres
image: "{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}"
imagePullPolicy: "{{ .Values.initImage.pullPolicy }}"
envFrom:
- secretRef:
name: "{{ tpl .Values.envFromSecret . }}"
command:
- /bin/sh
- -c
- dockerize -wait "tcp://$DB_HOST:$DB_PORT" -timeout 120s
# -- Скрипт инициализации Superset
# @default -- скрипт для создания пользователя-администратора и инициализации ролей
initscript: |-
#!/bin/sh
set -eu
echo "Upgrading DB schema..."
superset db upgrade
echo "Initializing roles..."
superset init
{{ if .Values.init.createAdmin }}
echo "Creating admin user..."
superset fab create-admin \
--username {{ .Values.init.adminUser.username }} \
--firstname {{ .Values.init.adminUser.firstname }} \
--lastname {{ .Values.init.adminUser.lastname }} \
--email {{ .Values.init.adminUser.email }} \
--password {{ .Values.init.adminUser.password }} \
|| true
{{- end }}
{{ if .Values.init.loadExamples }}
echo "Loading examples..."
superset load_examples
{{- end }}
if [ -f "{{ .Values.extraConfigMountPath }}/import_datasources.yaml" ]; then
echo "Importing database connections.... "
superset import_datasources -p {{ .Values.extraConfigMountPath }}/import_datasources.yaml
fi
# -- Запуск дополнительных контейнеров в поде задания инициализации
extraContainers: []
## Аннотации, добавляемые к подам задания инициализации
podAnnotations: {}
podSecurityContext: {}
containerSecurityContext: {}
## Допуски, добавляемые к подам задания инициализации
tolerations: []
## Привязка, добавляемая к подам задания инициализации
affinity: {}
# -- «TopologySpreadConstrains», добавляемые к заданию инициализации
topologySpreadConstraints: []
# -- Значения конфигурации для зависимости Postgresql.
# см. https://github.com/bitnami/charts/tree/main/bitnami/postgresql
# @default -- см. «values.yaml»
postgresql:
##
## Используем зависимость диаграмм PostgreSQL.
## В случае применения собственного PostgreSQL задаем «false».
enabled: true
## Параметры аутентификации
auth:
## Название имеющегося секрета с паролем Postgres внутри.
existingSecret:
## Название PostgreSQL для создания своего пользователя
username: superset
## Пароль PostgreSQL для создания своего пользователя. Игнорируется, если указан «auth.existingSecret» с ключом «password»
password: superset
## Название PostgreSQL для создания пользовательской базы данных
database: superset
image:
tag: "14.6.0-debian-11-r13"
## Основные параметры PostgreSQL
primary:
##
## Настройка хранилища постоянных томов.
## см. https://kubernetes.io/docs/user-guide/persistent-volumes
persistence:
##
## «persistence» активируется в PostgreSQL запросами на выделение постоянных томов.
enabled: true
##
## Класс постоянного хранения
# storageClass: classname
##
## Режимы доступа:
accessModes:
- ReadWriteOnce
## Порт PostgreSQL
service:
ports:
postgresql: "5432"
# -- Значения конфигурации для зависимости Redis.
# см. https://github.com/bitnami/charts/blob/master/bitnami/redis
# Еще документация: https://artifacthub.io/packages/helm/bitnami/redis
# @default -- см. «values.yaml»
redis:
##
## Используем зависимость диаграмм Redis.
##
## В случае применения собственного Redis хост задается в «supersetNode.connections.redis_host»
##
## В случае применения собственного Redis задаем «false».
enabled: true
##
## Архитектуру задаем как автономную «standalone»/репликация
architecture: standalone
##
## Настройка аутентификации:
##
auth:
## Включаем аутентификацию по паролю
enabled: false
## Название имеющегося секрета с паролем Redis внутри.
existingSecret: ""
## Название ключа с секретом внутри.
existingSecretKey: ""
## Пароль Redis
password: superset
##
## Настройка мастера
##
master:
##
## Настройка образа
# образ:
##
## Названия секретов реестра Docker, список
# pullSecrets: nil
##
## Настраиваем «persistence»
persistence:
##
## Для постоянного хранения данных применяем PVC — запрос на выделение постоянного тома.
enabled: false
##
## Класс постоянного хранения
# storageClass: classname
##
## Режим доступа:
accessModes:
- ReadWriteOnce
nodeSelector: {}
tolerations: []
affinity: {}
# -- «TopologySpreadConstrains», добавляемые во все развертывания
topologySpreadConstraints: []

Обновим секретный ключ

В строке configOverrides определяется секретный ключ SECRET_KEY, создаем его:

openssl rand -base64 42

Затем копируем и заменяем вывод в yaml-файле:

configOverrides: 
secret: |
SECRET_KEY = 'YOUR_SECRET'
# запуская «openssl rand -base64 42», генерируем «YOUR_SECRET»
# и заменяем им красный «YOUR_SECRET»

Дополнительно установим отдельные коннекторы баз данных

Исходя из имеющихся источников данных, в Superset добавляются отдельные коннекторы баз данных, например, chipmunkdb  —  в часть yaml-файла с bootstrapScript:

bootstrapScript: |
#!/bin/bash
pip3 install chipmunkdb-python-client
# в качестве коннекторов баз данных добавляются и другие библиотеки
if [ ! -f ~/bootstrap ]; then echo "Running Superset with uid {{ .Values.runAsUser }}" > ~/bootstrap; fi

Проверив superset.yaml, устанавливаем Superset:

helm repo add superset https://apache.github.io/superset
helm upgrade --install --values superset.yaml superset superset/superset

После установки в выходных данных показано, как получить доступ к пользовательскому интерфейсу Superset.

Вводим учетные данные, по умолчанию имя пользователя: admin, пароль: admin, и видим экран дашборда:

Apache Superset установлен. Опробуйте его, поделитесь своими впечатлениями и рекомендациями по выбору бесплатного дашбордного решения.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Thoren Lederer: This Open Source Dashboard Solution With 59k Stars on GitHub astonished me — Apache Superset

Предыдущая статьяSQL в браузере  —  веб-оболочка DuckDB для анализа локальных данных