blob: 0ec417d8e38fb49fc2b26e0836dab48c30582aff [file] [log] [blame]
{"version":3,"sources":["webpack:///./src/pages/docs/installation/kubernetes.mdx"],"names":["_frontmatter","layoutProps","MDXLayout","DefaultLayout","MDXContent","components","props","mdxType","parentName","isMDXComponent"],"mappings":"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","file":"component---src-pages-docs-installation-kubernetes-mdx-51884d5d55fa52ea0b3a.js","sourcesContent":["import * as React from 'react'\n /* @jsx mdx */\nimport { mdx } from '@mdx-js/react';\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\n\nimport DefaultLayout from \"/home/runner/work/superset/superset/docs/node_modules/gatsby-theme-docz/src/base/Layout.js\";\nexport const _frontmatter = {};\nconst layoutProps = {\n _frontmatter\n};\nconst MDXLayout = DefaultLayout;\nexport default function MDXContent({\n components,\n ...props\n}) {\n return <MDXLayout {...layoutProps} {...props} components={components} mdxType=\"MDXLayout\">\n\n\n <h2 {...{\n \"id\": \"running-on-kubernetes\"\n }}>{`Running on Kubernetes`}</h2>\n <p>{`Running on Kubernetes is supported with the provided `}<a parentName=\"p\" {...{\n \"href\": \"https://helm.sh/\"\n }}>{`Helm`}</a>{` chart found in the official `}<a parentName=\"p\" {...{\n \"href\": \"https://apache.github.io/superset/index.yaml\"\n }}>{`Superset helm repository`}</a>{`.`}</p>\n <h3 {...{\n \"id\": \"prerequisites\"\n }}>{`Prerequisites`}</h3>\n <ul>\n <li parentName=\"ul\">{`A Kubernetes cluster`}</li>\n <li parentName=\"ul\">{`Helm installed`}</li>\n </ul>\n <h3 {...{\n \"id\": \"running\"\n }}>{`Running`}</h3>\n <ol>\n <li parentName=\"ol\">{`Add the Superset helm repository`}</li>\n </ol>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-sh\"\n }}>{`helm repo add superset https://apache.github.io/superset\n\"superset\" has been added to your repositories\n`}</code></pre>\n <ol>\n <li parentName=\"ol\">{`View charts in repo`}</li>\n </ol>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-sh\"\n }}>{`helm search repo superset\nNAME CHART VERSION APP VERSION DESCRIPTION\nsuperset/superset 0.1.1 1.0 Apache Superset is a modern, enterprise-ready b...\n`}</code></pre>\n <ol>\n <li parentName=\"ol\">{`Configure your setting overrides`}</li>\n </ol>\n <p>{`Just like any typical Helm chart, you'll need to craft a `}<inlineCode parentName=\"p\">{`values.yaml`}</inlineCode>{` file that would define/override any of the values exposed into the default `}<a parentName=\"p\" {...{\n \"href\": \"https://github.com/apache/superset/tree/master/helm/superset/values.yaml\"\n }}>{`values.yaml`}</a>{`, or from any of the dependent charts it depends on:`}</p>\n <ul>\n <li parentName=\"ul\"><a parentName=\"li\" {...{\n \"href\": \"https://artifacthub.io/packages/helm/bitnami/redis\"\n }}>{`bitnami/redis`}</a></li>\n <li parentName=\"ul\"><a parentName=\"li\" {...{\n \"href\": \"https://artifacthub.io/packages/helm/bitnami/postgresql\"\n }}>{`bitnami/postgresql`}</a></li>\n </ul>\n <p>{`More info down below on some important overrides you might need.`}</p>\n <ol>\n <li parentName=\"ol\">{`Install and run`}</li>\n </ol>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-sh\"\n }}>{`helm upgrade --install --values my-values.yaml superset superset/superset\n`}</code></pre>\n <p>{`You should see various pods popping up, such as:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-sh\"\n }}>{`kubectl get pods\nNAME READY STATUS RESTARTS AGE\nsuperset-celerybeat-7cdcc9575f-k6xmc 1/1 Running 0 119s\nsuperset-f5c9c667-dw9lp 1/1 Running 0 4m7s\nsuperset-f5c9c667-fk8bk 1/1 Running 0 4m11s\nsuperset-init-db-zlm9z 0/1 Completed 0 111s\nsuperset-postgresql-0 1/1 Running 0 6d20h\nsuperset-redis-master-0 1/1 Running 0 6d20h\nsuperset-worker-75b48bbcc-jmmjr 1/1 Running 0 4m8s\nsuperset-worker-75b48bbcc-qrq49 1/1 Running 0 4m12s\n`}</code></pre>\n <p>{`The exact list will depend on some of your specific configuration overrides but you should generally expect:`}</p>\n <ul>\n <li parentName=\"ul\">{`N `}<inlineCode parentName=\"li\">{`superset-xxxx-yyyy`}</inlineCode>{` and `}<inlineCode parentName=\"li\">{`superset-worker-xxxx-yyyy`}</inlineCode>{` pods (depending on your `}<inlineCode parentName=\"li\">{`replicaCount`}</inlineCode>{` value)`}</li>\n <li parentName=\"ul\">{`1 `}<inlineCode parentName=\"li\">{`superset-postgresql-0`}</inlineCode>{` depending on your postgres settings`}</li>\n <li parentName=\"ul\">{`1 `}<inlineCode parentName=\"li\">{`superset-redis-master-0`}</inlineCode>{` depending on your redis settings`}</li>\n <li parentName=\"ul\">{`1 `}<inlineCode parentName=\"li\">{`superset-celerybeat-xxxx-yyyy`}</inlineCode>{` pod if you have `}<inlineCode parentName=\"li\">{`supersetCeleryBeat.enabled = true`}</inlineCode>{` in your values overrides`}</li>\n </ul>\n <ol>\n <li parentName=\"ol\">{`Access it`}</li>\n </ol>\n <p>{`The chart will publish appropriate services to expose the Superset UI internally within your k8s cluster. To access it externally you will have to either:`}</p>\n <ul>\n <li parentName=\"ul\">{`Configure the Service as a `}<inlineCode parentName=\"li\">{`LoadBalancer`}</inlineCode>{` or `}<inlineCode parentName=\"li\">{`NodePort`}</inlineCode></li>\n <li parentName=\"ul\">{`Set up an `}<inlineCode parentName=\"li\">{`Ingress`}</inlineCode>{` for it - the chart includes a definition, but will need to be tuned to your needs (hostname, tls, annotations etc...)`}</li>\n <li parentName=\"ul\">{`Run `}<inlineCode parentName=\"li\">{`kubectl port-forward superset-xxxx-yyyy :8088`}</inlineCode>{` to directly tunnel one pod's port into your localhost`}</li>\n </ul>\n <p>{`Depending how you configured external access, the URL will vary. Once you've identified the appropriate URL you can log in with:`}</p>\n <ul>\n <li parentName=\"ul\">{`user: `}<inlineCode parentName=\"li\">{`admin`}</inlineCode></li>\n <li parentName=\"ul\">{`password: `}<inlineCode parentName=\"li\">{`admin`}</inlineCode></li>\n </ul>\n <h3 {...{\n \"id\": \"important-settings\"\n }}>{`Important settings`}</h3>\n <h4 {...{\n \"id\": \"security-settings\"\n }}>{`Security settings`}</h4>\n <p>{`Default security settings and passwords are included but you `}<strong parentName=\"p\">{`SHOULD`}</strong>{` override those with your own, in particular:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`postgresql:\n postgresqlPassword: superset\n`}</code></pre>\n <h4 {...{\n \"id\": \"dependencies\"\n }}>{`Dependencies`}</h4>\n <p>{`You can specify pip packages to be installed before startup, e.g. to install extra database drivers:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`additionalRequirements:\n - psycopg2\n - redis\n - elasticsearch-dbapi\n - pymssql\n - gsheetsdb\n # Force verstion to work around https://github.com/betodealmeida/gsheets-db-api/issues/15\n - moz-sql-parser==4.9.21002\n # For OAuth\n - Authlib\n # For webdriver / reports\n - gevent\n`}</code></pre>\n <p><strong parentName=\"p\">{`WARNING`}</strong>{`: The list will replace the default one from the default `}<inlineCode parentName=\"p\">{`values.yaml`}</inlineCode>{` entirely, not `}<em parentName=\"p\">{`add`}</em>{` to it...`}</p>\n <h4 {...{\n \"id\": \"superset_configpy\"\n }}>{`superset_config.py`}</h4>\n <p>{`The default `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{` is fairly minimal and you will very likely need to extend it. This is done by specifying one or more key/value entries in `}<inlineCode parentName=\"p\">{`configOverrides`}</inlineCode>{`, e.g.:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`configOverrides:\n my_override: |\n # This will make sure the redirect_uri is properly computed, even with SSL offloading\n ENABLE_PROXY_FIX = True\n FEATURE_FLAGS = {\n \"DYNAMIC_PLUGINS\": True\n }\n`}</code></pre>\n <p>{`Those will be evaluated as Helm templates and therefore will be able to reference other `}<inlineCode parentName=\"p\">{`values.yaml`}</inlineCode>{` variables e.g. `}<inlineCode parentName=\"p\">{`{{ .Values.ingress.hosts[0] }}`}</inlineCode>{` will resolve to your ingress external domain.`}</p>\n <p>{`The entire `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{` will be installed as a secret, so it is safe to pass sensitive parameters directly... however it might be more readable to use secret env variables for that.`}</p>\n <p>{`Full python files can be provided by running `}<inlineCode parentName=\"p\">{`helm upgrade --install --values my-values.yaml --set-file configOverrides.oauth=set_oauth.py`}</inlineCode></p>\n <h4 {...{\n \"id\": \"environment-variables\"\n }}>{`Environment Variables`}</h4>\n <p>{`Those can be passed as key/values either with `}<inlineCode parentName=\"p\">{`extraEnv`}</inlineCode>{` or `}<inlineCode parentName=\"p\">{`extraSecretEnv`}</inlineCode>{` if they're sensitive. They can then be referenced from `}<inlineCode parentName=\"p\">{`superset_config.py`}</inlineCode>{` using e.g. `}<inlineCode parentName=\"p\">{`os.environ.get(\"VAR\")`}</inlineCode>{`.`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`extraEnv:\n SMTP_HOST: smtp.gmail.com\n SMTP_USER: user@gmail.com\n SMTP_PORT: \"587\"\n SMTP_MAIL_FROM: user@gmail.com\n\nextraSecretEnv:\n SMTP_PASSWORD: xxxx\n\nconfigOverrides:\n smtp: |\n import ast\n SMTP_HOST = os.getenv(\"SMTP_HOST\",\"localhost\")\n SMTP_STARTTLS = ast.literal_eval(os.getenv(\"SMTP_STARTTLS\", \"True\"))\n SMTP_SSL = ast.literal_eval(os.getenv(\"SMTP_SSL\", \"False\"))\n SMTP_USER = os.getenv(\"SMTP_USER\",\"superset\")\n SMTP_PORT = os.getenv(\"SMTP_PORT\",25)\n SMTP_PASSWORD = os.getenv(\"SMTP_PASSWORD\",\"superset\")\n`}</code></pre>\n <h4 {...{\n \"id\": \"system-packages\"\n }}>{`System packages`}</h4>\n <p>{`If new system packages are required, they can be installed before application startup by overriding the container's `}<inlineCode parentName=\"p\">{`command`}</inlineCode>{`, e.g.:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`supersetWorker:\n command:\n - /bin/sh\n - -c\n - |\n apt update\n apt install -y somepackage\n apt autoremove -yqq --purge\n apt clean\n\n # Run celery worker\n . {{ .Values.configMountPath }}/superset_bootstrap.sh; celery --app=superset.tasks.celery_app:app worker\n`}</code></pre>\n <h4 {...{\n \"id\": \"data-sources\"\n }}>{`Data sources`}</h4>\n <p>{`Data source definitions can be automatically declared by providing key/value yaml definitions in `}<inlineCode parentName=\"p\">{`extraConfigs`}</inlineCode>{`:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`extraConfigs:\n datasources-init.yaml: |\n databases:\n - allow_csv_upload: true\n allow_ctas: true\n allow_cvas: true\n database_name: example-db\n extra: \"{\\\\r\\\\n \\\\\"metadata_params\\\\\": {},\\\\r\\\\n \\\\\"engine_params\\\\\": {},\\\\r\\\\n \\\\\"\\\\\n metadata_cache_timeout\\\\\": {},\\\\r\\\\n \\\\\"schemas_allowed_for_csv_upload\\\\\": []\\\\r\\\\n\\\\\n }\"\n sqlalchemy_uri: example://example-db.local\n tables: []\n`}</code></pre>\n <p>{`Those will also be mounted as secrets and can include sensitive parameters.`}</p>\n <h3 {...{\n \"id\": \"configuration-examples\"\n }}>{`Configuration Examples`}</h3>\n <h4 {...{\n \"id\": \"setting-up-oauth\"\n }}>{`Setting up OAuth`}</h4>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`extraEnv:\n AUTH_DOMAIN: example.com\n\nextraSecretEnv:\n GOOGLE_KEY: xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n GOOGLE_SECRET: xxxxxxxxxxxxxxxxxxxxxxxx\n\nconfigOverrides:\n enable_oauth: |\n # This will make sure the redirect_uri is properly computed, even with SSL offloading\n ENABLE_PROXY_FIX = True\n\n from flask_appbuilder.security.manager import (AUTH_OAUTH, AUTH_DB)\n AUTH_TYPE = AUTH_OAUTH\n OAUTH_PROVIDERS = [\n {\n \"name\": \"google\",\n \"icon\": \"fa-google\",\n \"token_key\": \"access_token\",\n \"remote_app\": {\n \"client_id\": os.getenv(\"GOOGLE_KEY\"),\n \"client_secret\": os.getenv(\"GOOGLE_SECRET\"),\n \"api_base_url\": \"https://www.googleapis.com/oauth2/v2/\",\n \"client_kwargs\": {\"scope\": \"email profile\"},\n \"request_token_url\": None,\n \"access_token_url\": \"https://accounts.google.com/o/oauth2/token\",\n \"authorize_url\": \"https://accounts.google.com/o/oauth2/auth\",\n \"authorize_params\": {\"hd\": os.getenv(\"AUTH_DOMAIN\", \"\")}\n },\n }\n ]\n\n # Map Authlib roles to superset roles\n AUTH_ROLE_ADMIN = 'Admin'\n AUTH_ROLE_PUBLIC = 'Public'\n\n # Will allow user self registration, allowing to create Flask users from Authorized User\n AUTH_USER_REGISTRATION = True\n\n # The default user self registration role\n AUTH_USER_REGISTRATION_ROLE = \"Admin\"\n`}</code></pre>\n <h4 {...{\n \"id\": \"enable-alerts-and-reports\"\n }}>{`Enable Alerts and Reports`}</h4>\n <p>{`For this, as per the `}<a parentName=\"p\" {...{\n \"href\": \"/docs/installation/email-reports\"\n }}>{`Alerts and Reports doc`}</a>{`, you will need to:`}</p>\n <h5 {...{\n \"id\": \"install-a-supported-webdriver-in-the-celery-worker\"\n }}>{`Install a supported webdriver in the Celery worker`}</h5>\n <p>{`This is done either by using a custom image that has the webdriver pre-installed, or installing at startup time by overriding the `}<inlineCode parentName=\"p\">{`command`}</inlineCode>{`. Here's a working example for `}<inlineCode parentName=\"p\">{`chromedriver`}</inlineCode>{`:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`supersetWorker:\n command:\n - /bin/sh\n - -c\n - |\n # Install chrome webdriver\n # See https://github.com/apache/superset/blob/4fa3b6c7185629b87c27fc2c0e5435d458f7b73d/docs/src/pages/docs/installation/email_reports.mdx\n apt update\n wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb\n apt install -y --no-install-recommends ./google-chrome-stable_current_amd64.deb\n wget https://chromedriver.storage.googleapis.com/88.0.4324.96/chromedriver_linux64.zip\n unzip chromedriver_linux64.zip\n chmod +x chromedriver\n mv chromedriver /usr/bin\n apt autoremove -yqq --purge\n apt clean\n rm -f google-chrome-stable_current_amd64.deb chromedriver_linux64.zip\n\n # Run\n . {{ .Values.configMountPath }}/superset_bootstrap.sh; celery --app=superset.tasks.celery_app:app worker\n`}</code></pre>\n <h5 {...{\n \"id\": \"run-the-celery-beat\"\n }}>{`Run the Celery beat`}</h5>\n <p>{`This pod will trigger the scheduled tasks configured in the alerts and reports UI section:`}</p>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`supersetCeleryBeat:\n enabled: true\n`}</code></pre>\n <h5 {...{\n \"id\": \"configure-the-appropriate-celery-jobs-and-smtpslack-settings\"\n }}>{`Configure the appropriate Celery jobs and SMTP/Slack settings`}</h5>\n <pre><code parentName=\"pre\" {...{\n \"className\": \"language-yaml\"\n }}>{`extraEnv:\n SMTP_HOST: smtp.gmail.com\n SMTP_USER: user@gmail.com\n SMTP_PORT: \"587\"\n SMTP_MAIL_FROM: user@gmail.com\n\nextraSecretEnv:\n SLACK_API_TOKEN: xoxb-xxxx-yyyy\n SMTP_PASSWORD: xxxx-yyyy\n\nconfigOverrides:\n feature_flags: |\n import ast\n\n FEATURE_FLAGS = {\n \"ALERT_REPORTS\": True\n }\n\n SMTP_HOST = os.getenv(\"SMTP_HOST\",\"localhost\")\n SMTP_STARTTLS = ast.literal_eval(os.getenv(\"SMTP_STARTTLS\", \"True\"))\n SMTP_SSL = ast.literal_eval(os.getenv(\"SMTP_SSL\", \"False\"))\n SMTP_USER = os.getenv(\"SMTP_USER\",\"superset\")\n SMTP_PORT = os.getenv(\"SMTP_PORT\",25)\n SMTP_PASSWORD = os.getenv(\"SMTP_PASSWORD\",\"superset\")\n SMTP_MAIL_FROM = os.getenv(\"SMTP_MAIL_FROM\",\"superset@superset.com\")\n\n SLACK_API_TOKEN = os.getenv(\"SLACK_API_TOKEN\",None)\n celery_conf: |\n from celery.schedules import crontab\n\n class CeleryConfig(object):\n BROKER_URL = f\"redis://{env('REDIS_HOST')}:{env('REDIS_PORT')}/0\"\n CELERY_IMPORTS = ('superset.sql_lab', )\n CELERY_RESULT_BACKEND = f\"redis://{env('REDIS_HOST')}:{env('REDIS_PORT')}/0\"\n CELERY_ANNOTATIONS = {'tasks.add': {'rate_limit': '10/s'}}\n CELERY_IMPORTS = ('superset.sql_lab', \"superset.tasks\", \"superset.tasks.thumbnails\", )\n CELERY_ANNOTATIONS = {\n 'sql_lab.get_sql_results': {\n 'rate_limit': '100/s',\n },\n 'email_reports.send': {\n 'rate_limit': '1/s',\n 'time_limit': 600,\n 'soft_time_limit': 600,\n 'ignore_result': True,\n },\n }\n CELERYBEAT_SCHEDULE = {\n 'reports.scheduler': {\n 'task': 'reports.scheduler',\n 'schedule': crontab(minute='*', hour='*'),\n },\n 'reports.prune_log': {\n 'task': 'reports.prune_log',\n 'schedule': crontab(minute=0, hour=0),\n },\n 'cache-warmup-hourly': {\n 'task': 'cache-warmup',\n 'schedule': crontab(minute='*/30', hour='*'),\n 'kwargs': {\n 'strategy_name': 'top_n_dashboards',\n 'top_n': 10,\n 'since': '7 days ago',\n },\n }\n }\n\n CELERY_CONFIG = CeleryConfig\n reports: |\n EMAIL_PAGE_RENDER_WAIT = 60\n WEBDRIVER_BASEURL = \"http://{{ template \"superset.fullname\" . }}:{{ .Values.service.port }}/\"\n WEBDRIVER_BASEURL_USER_FRIENDLY = \"https://www.example.com/\"\n WEBDRIVER_TYPE= \"chrome\"\n WEBDRIVER_OPTION_ARGS = [\n \"--force-device-scale-factor=2.0\",\n \"--high-dpi-support=2.0\",\n \"--headless\",\n \"--disable-gpu\",\n \"--disable-dev-shm-usage\",\n # This is required because our process runs as root (in order to install pip packages)\n \"--no-sandbox\",\n \"--disable-setuid-sandbox\",\n \"--disable-extensions\",\n ]\n`}</code></pre>\n\n </MDXLayout>;\n}\n;\nMDXContent.isMDXComponent = true;\n "],"sourceRoot":""}