├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── publish-charts.yml │ ├── test-dask-chart.yml │ ├── test-daskhub-chart.yml │ └── watch-dependencies.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CONTRIBUTING.md ├── README.md ├── ci ├── common └── release.sh ├── dask ├── .frigate ├── .helmignore ├── Chart.yaml ├── README.md ├── dev-values.yaml ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── additional-worker-deployment.yaml │ ├── dask-jupyter-config.yaml │ ├── dask-jupyter-deployment.yaml │ ├── dask-jupyter-ingress.yaml │ ├── dask-jupyter-service.yaml │ ├── dask-jupyter-serviceaccount.yaml │ ├── dask-scheduler-deployment.yaml │ ├── dask-scheduler-ingress.yaml │ ├── dask-scheduler-service.yaml │ ├── dask-scheduler-servicemonitor.yaml │ ├── dask-worker-deployment.yaml │ └── dask-worker-podmonitor.yaml └── values.yaml └── daskhub ├── .frigate ├── .helmignore ├── CHANGELOG.md ├── Chart.yaml ├── README.md ├── templates ├── NOTES.txt └── dask-kubernetes-rbac.yaml └── values.yaml /.gitattributes: -------------------------------------------------------------------------------- 1 | *.yaml linguist-language=YAML linguist-detectable 2 | ci/* -linguist-detectable 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # dependabot.yml reference: https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates 2 | # 3 | # Notes: 4 | # - Status and logs from dependabot are provided at 5 | # https://github.com/dask/helm-chart/network/updates. 6 | # - YAML anchors are not supported here or in GitHub Workflows. 7 | # 8 | version: 2 9 | updates: 10 | # Maintain dependencies in our GitHub Workflows 11 | - package-ecosystem: "github-actions" 12 | directory: "/" 13 | schedule: 14 | interval: monthly 15 | time: "05:00" 16 | timezone: "Etc/UTC" 17 | labels: 18 | - ci 19 | -------------------------------------------------------------------------------- /.github/workflows/publish-charts.yml: -------------------------------------------------------------------------------- 1 | # This is a GitHub workflow defining a set of jobs with a set of steps. ref: 2 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 3 | # 4 | # This workflow package and publishes the Helm charts to Helm repository living 5 | # inside the gh-pages branch of this git repository. 6 | # 7 | name: Publish charts 8 | 9 | on: 10 | push: 11 | tags: ["*"] 12 | workflow_dispatch: 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-22.04 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - uses: actions/setup-python@v5 22 | with: 23 | python-version: "3.10" 24 | 25 | - name: Install frigate 26 | run: pip install frigate 27 | 28 | - name: Generate charts' README.md files from .frigate files 29 | run: frigate hook 30 | 31 | - name: Get the version 32 | id: get_version 33 | run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} 34 | 35 | - name: Publish Helm charts 36 | uses: stefanprodan/helm-gh-pages@master 37 | with: 38 | token: ${{ secrets.GITHUB_TOKEN }} 39 | charts_dir: "." 40 | charts_url: https://helm.dask.org/ 41 | linting: "off" 42 | chart_version: ${{ steps.get_version.outputs.VERSION }} 43 | -------------------------------------------------------------------------------- /.github/workflows/test-dask-chart.yml: -------------------------------------------------------------------------------- 1 | # This is a GitHub workflow defining a set of jobs with a set of steps. ref: 2 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 3 | # 4 | # NOTE: Changes to this name must be followed by updates to the README.me 5 | # badges. 6 | name: Test dask chart 7 | 8 | on: 9 | pull_request: 10 | paths: 11 | - "dask/**" 12 | - "chartpress.yaml" 13 | - "**/test-dask-chart.yml" 14 | - "ci/common" 15 | push: 16 | paths: 17 | - "dask/**" 18 | - "chartpress.yaml" 19 | - "**/test-dask-chart.yml" 20 | - "ci/common" 21 | branches-ignore: 22 | - "upgrade-**" 23 | - "dependabot/**" 24 | - "pre-commit-ci-update-config" 25 | tags: 26 | - "**" 27 | workflow_dispatch: 28 | 29 | jobs: 30 | test-install-chart: 31 | runs-on: ubuntu-22.04 32 | 33 | strategy: 34 | # Keep running even if one variation of the job fail 35 | fail-fast: false 36 | matrix: 37 | # We run this job multiple times with different parameterization 38 | # specified below, these parameters have no meaning on their own and 39 | # gain meaning on how job steps use them. 40 | # 41 | # k3s-version: https://github.com/rancher/k3s/tags 42 | # k3s-channel: https://update.k3s.io/v1-release/channels 43 | # 44 | include: 45 | - k3s-channel: v1.25 46 | - k3s-channel: latest 47 | 48 | steps: 49 | - uses: actions/checkout@v4 50 | 51 | - name: Lint chart's templates 52 | run: helm lint ./dask --strict --values dask/dev-values.yaml 53 | 54 | - name: Validate chart's templates can render 55 | run: helm template ./dask --values dask/dev-values.yaml 1>/dev/null 56 | 57 | # Starts a k8s cluster with NetworkPolicy enforcement and installs kubectl 58 | # 59 | # ref: https://github.com/jupyterhub/action-k3s-helm/ 60 | - uses: jupyterhub/action-k3s-helm@v4 61 | with: 62 | k3s-channel: ${{ matrix.k3s-channel }} 63 | metrics-enabled: false 64 | traefik-enabled: false 65 | docker-enabled: false 66 | 67 | - name: Validate charts' rendered templates are valid k8s resources 68 | run: helm template ./dask --validate --values dask/dev-values.yaml 1>/dev/null 69 | 70 | - name: Install chart and await readiness 71 | run: | 72 | helm install dask ./dask --values dask/dev-values.yaml 73 | 74 | . ci/common 75 | full_namespace_await 76 | 77 | # GitHub Action reference: https://github.com/jupyterhub/action-k8s-namespace-report 78 | - name: Kubernetes namespace report 79 | uses: jupyterhub/action-k8s-namespace-report@v1 80 | if: always() 81 | -------------------------------------------------------------------------------- /.github/workflows/test-daskhub-chart.yml: -------------------------------------------------------------------------------- 1 | # This is a GitHub workflow defining a set of jobs with a set of steps. ref: 2 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 3 | # 4 | # NOTE: Changes to this name must be followed by updates to the README.me 5 | # badges. 6 | name: Test daskhub chart 7 | 8 | on: 9 | pull_request: 10 | paths: 11 | - "daskhub/**" 12 | - "chartpress.yaml" 13 | - "**/test-daskhub-chart.yml" 14 | - "ci/common" 15 | push: 16 | paths: 17 | - "daskhub/**" 18 | - "chartpress.yaml" 19 | - "**/test-daskhub-chart.yml" 20 | - "ci/common" 21 | branches-ignore: 22 | - "upgrade-**" 23 | - "dependabot/**" 24 | - "pre-commit-ci-update-config" 25 | workflow_dispatch: 26 | 27 | jobs: 28 | test-install-chart: 29 | runs-on: ubuntu-22.04 30 | 31 | strategy: 32 | # Keep running even if one variation of the job fail 33 | fail-fast: false 34 | matrix: 35 | # We run this job multiple times with different parameterization 36 | # specified below, these parameters have no meaning on their own and 37 | # gain meaning on how job steps use them. 38 | # 39 | # k3s-version: https://github.com/rancher/k3s/tags 40 | # k3s-channel: https://update.k3s.io/v1-release/channels 41 | include: 42 | - k3s-channel: v1.25 43 | - k3s-channel: latest 44 | 45 | steps: 46 | - uses: actions/checkout@v4 47 | 48 | - name: Update chart dependencies 49 | run: helm dependencies update ./daskhub 50 | 51 | - name: Lint chart's templates 52 | run: helm lint ./daskhub --strict 53 | 54 | - name: Validate chart's templates can render 55 | run: helm template ./daskhub 1>/dev/null 56 | 57 | # Starts a k8s cluster with NetworkPolicy enforcement and installs kubectl 58 | # 59 | # ref: https://github.com/jupyterhub/action-k3s-helm/ 60 | - uses: jupyterhub/action-k3s-helm@v4 61 | with: 62 | k3s-channel: ${{ matrix.k3s-channel }} 63 | metrics-enabled: false 64 | traefik-enabled: false 65 | docker-enabled: false 66 | 67 | # NOTE: We cannot perform helm template --validate as a quick step before 68 | # installing the daskhub chart because it contains resources of CRD 69 | # kind and the CRDs. This is because we validate against the k8s 70 | # api-server and helm template doesn't install the charts crds just 71 | # because we want to validate the rendered templates. 72 | # 73 | # - name: Validate charts' rendered templates are valid k8s resources 74 | # run: | 75 | # helm template ./daskhub --validate 1>/dev/null 76 | 77 | - name: Install chart and await readiness 78 | run: | 79 | helm install daskhub ./daskhub 80 | 81 | . ci/common 82 | full_namespace_await 83 | 84 | # GitHub Action reference: https://github.com/jupyterhub/action-k8s-namespace-report 85 | - name: Kubernetes namespace report 86 | uses: jupyterhub/action-k8s-namespace-report@v1 87 | if: always() 88 | -------------------------------------------------------------------------------- /.github/workflows/watch-dependencies.yml: -------------------------------------------------------------------------------- 1 | # This is a GitHub workflow defining a set of jobs with a set of steps. 2 | # ref: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 3 | # 4 | # - Watch the latest ghcr.io/dask/dask image tag and update its reference in 5 | # dask/values.yaml and dask/Chart.yaml (appVersion) if needed. 6 | # 7 | # - Watch the latest pangeo/base-notebook image tag and update its reference 8 | # daskhub/values.yaml under jupyterhub.singleuser.image.tag if needed. 9 | # 10 | # - Watch the pinned chart dependencies (jupyterhub, dask-gateway) in 11 | # daskhub/Chart.yaml to match the latest stable version available. 12 | # 13 | name: Watch dependencies 14 | 15 | on: 16 | schedule: 17 | # Run every hour sharp, ref: https://crontab.guru/#0_*_*_*_* 18 | - cron: "0 * * * *" 19 | workflow_dispatch: 20 | 21 | jobs: 22 | check-dask-image: 23 | if: github.repository == 'dask/helm-chart' 24 | runs-on: ubuntu-22.04 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - name: Get latest tag of ghcr.io/dask/dask 29 | id: latest 30 | env: 31 | REGISTRY: ghcr.io 32 | REPOSITORY: dask/dask 33 | # The skopeo image helps us list tags consistently from different docker 34 | # registries. We use jq to filter out tags of the x.y.z format with the 35 | # optional v prefix, and then sort based on the numerical x, y, and z 36 | # values. Finally, we pick the last value in the list. 37 | # 38 | # NOTE: This script is used twice in this file, always update both if 39 | # you update it at once place. 40 | # 41 | run: | 42 | latest_tag=$( 43 | docker run --rm quay.io/skopeo/stable list-tags docker://$REGISTRY/$REPOSITORY \ 44 | | jq -r '[.Tags[] | select(. | test("^v?\\d+\\.\\d+\\.\\d+$"))] | sort_by(split(".") | map(tonumber? // (.[1:] | tonumber))) | last' 45 | ) 46 | echo "::set-output name=tag::$latest_tag" 47 | 48 | - name: Get dask/Chart.yaml's tag of ghcr.io/dask/dask (in appVersion) 49 | id: local 50 | run: | 51 | local_tag=$(cat dask/Chart.yaml | yq e '.appVersion' -) 52 | echo "::set-output name=tag::$local_tag" 53 | 54 | - name: Update dask/Chart.yaml and dask/values.yaml pinned tag 55 | run: sed --in-place 's/"${{ steps.local.outputs.tag }}"/"${{ steps.latest.outputs.tag }}"/g' dask/Chart.yaml dask/values.yaml 56 | 57 | - name: git diff 58 | run: git --no-pager diff --color=always 59 | 60 | # ref: https://github.com/peter-evans/create-pull-request 61 | - name: Create a PR 62 | uses: peter-evans/create-pull-request@v7 63 | with: 64 | token: "${{ secrets.DASK_BOT_TOKEN }}" 65 | branch: update-dask-version 66 | reviewers: jacobtomlinson,consideratio 67 | commit-message: Update Dask version to ${{ steps.latest.outputs.tag }} 68 | title: Update Dask version to ${{ steps.latest.outputs.tag }} 69 | body: >- 70 | A new ghcr.io/dask/dask image version has been detected, version 71 | `${{ steps.latest.outputs.tag }}`. 72 | 73 | Updates dask the helm chart to use this version by default for 74 | workers, schedulers, and the optional jupyter server. 75 | 76 | update-singleuser-image: 77 | if: github.repository == 'dask/helm-chart' 78 | runs-on: ubuntu-22.04 79 | steps: 80 | - uses: actions/checkout@v4 81 | 82 | - name: Get daskhub/values.yaml pinned tag of pangeo/base-notebook 83 | id: local 84 | run: | 85 | local_tag=$(cat daskhub/values.yaml | yq e '.jupyterhub.singleuser.image.tag' -) 86 | echo "::set-output name=tag::$local_tag" 87 | 88 | - name: Get latest tag of pangeo/base-notebook 89 | id: latest 90 | env: 91 | REGISTRY: registry.hub.docker.com 92 | REPOSITORY: pangeo/base-notebook 93 | # The skopeo image helps us list tags consistently from different docker 94 | # registries. We use jq to filter out tags of the x.y.z format with the 95 | # optional v prefix, and then sort based on the numerical x, y, and z 96 | # values. Finally, we pick the last value in the list. 97 | # 98 | # NOTE: This script is used twice in this file, always update both if 99 | # you update it at once place. 100 | # 101 | run: | 102 | latest_tag=$( 103 | docker run --rm quay.io/skopeo/stable list-tags docker://$REGISTRY/$REPOSITORY \ 104 | | jq -r '[.Tags[] | select(. | test("^v?\\d+\\.\\d+\\.\\d+$"))] | sort_by(split(".") | map(tonumber? // (.[1:] | tonumber))) | last' 105 | ) 106 | echo "::set-output name=tag::$latest_tag" 107 | 108 | # FIXME: Apparently for some reason, sometimes we end up with a blank 109 | # output from the previous step to acquire the latest tag of 110 | # relevance from a container registry. 111 | # 112 | # In this step, we make the job fail if that is the case instead of 113 | # opening a PR, and we emit some debugging information along with 114 | # it. 115 | # 116 | if [ -z "$latest_tag" ]; then 117 | echo "For some reason latest_tag was found to be a blank string." 118 | echo "--- Debugging info: output of docker run ---" 119 | docker run --rm quay.io/skopeo/stable list-tags docker://$REGISTRY/$REPOSITORY 120 | echo "--- Now failing the job instead of opening a PR with a faulty version update." 121 | exit 1 122 | fi 123 | 124 | - name: Update daskhub/values.yaml pinned tag 125 | run: sed --in-place 's/${{ steps.local.outputs.tag }}/${{ steps.latest.outputs.tag }}/g' daskhub/values.yaml 126 | 127 | - name: git diff 128 | run: git --no-pager diff --color=always 129 | 130 | # ref: https://github.com/peter-evans/create-pull-request 131 | - name: Create a PR 132 | uses: peter-evans/create-pull-request@v7 133 | with: 134 | token: "${{ secrets.DASK_BOT_TOKEN }}" 135 | branch: update-singleuser-image 136 | labels: chart/daskhub 137 | reviewers: jacobtomlinson,consideratio 138 | commit-message: Update daskhub's pangeo/base-notebook version to ${{ steps.latest.outputs.tag }} 139 | title: Update daskhub's pangeo/base-notebook version to ${{ steps.latest.outputs.tag }} 140 | body: >- 141 | A new pangeo/base-notebook image version has been detected, version 142 | `${{ steps.latest.outputs.tag }}`. 143 | 144 | 145 | Updates daskhub to use this version by default for jupyterhub's user 146 | environment. 147 | 148 | update-chart-dep: 149 | if: github.repository == 'dask/helm-chart' 150 | runs-on: ubuntu-22.04 151 | 152 | strategy: 153 | fail-fast: false 154 | matrix: 155 | include: 156 | # Updates daskhub/Chart.yaml declared chart dependencies versions by 157 | # creating a PRs when a new stable version is available in the Helm 158 | # chart repository. 159 | # 160 | - chart_dep_index: "0" 161 | chart_dep_name: jupyterhub 162 | chart_dep_changelog_url: https://github.com/jupyterhub/zero-to-jupyterhub-k8s/blob/master/CHANGELOG.md 163 | 164 | - chart_dep_index: "1" 165 | chart_dep_name: dask-gateway 166 | chart_dep_changelog_url: https://gateway.dask.org/changelog.html 167 | 168 | steps: 169 | - uses: actions/checkout@v4 170 | 171 | - name: Get Chart.yaml pinned version of ${{ matrix.chart_dep_name }} chart 172 | id: local 173 | run: | 174 | local_version=$(cat daskhub/Chart.yaml | yq e '.dependencies.${{ matrix.chart_dep_index }}.version' -) 175 | echo "::set-output name=version::$local_version" 176 | 177 | - name: Get latest version of ${{ matrix.chart_dep_name }} chart 178 | id: latest 179 | run: | 180 | chart_dep_repo=$(cat daskhub/Chart.yaml | yq e '.dependencies.${{ matrix.chart_dep_index }}.repository' -) 181 | latest_version=$(helm show chart --repo=$chart_dep_repo ${{ matrix.chart_dep_name }} | yq e '.version' -) 182 | echo "::set-output name=version::$latest_version" 183 | 184 | - name: Update Chart.yaml pinned version 185 | run: sed --in-place 's/${{ steps.local.outputs.version }}/${{ steps.latest.outputs.version }}/g' daskhub/Chart.yaml 186 | 187 | - name: git diff 188 | run: git --no-pager diff --color=always 189 | 190 | # ref: https://github.com/peter-evans/create-pull-request 191 | - name: Create a PR 192 | uses: peter-evans/create-pull-request@v7 193 | with: 194 | token: "${{ secrets.DASK_BOT_TOKEN }}" 195 | branch: update-chart-dep-${{ matrix.chart_dep_name }} 196 | labels: chart/daskhub 197 | reviewers: jacobtomlinson,consideratio 198 | commit-message: Updates ${{ matrix.chart_dep_name }} chart to ${{ steps.latest.outputs.version }} 199 | title: Updates ${{ matrix.chart_dep_name }} chart to ${{ steps.latest.outputs.version }} 200 | body: >- 201 | Updates daskhub to depend on ${{ matrix.chart_dep_name }} version 202 | `${{ steps.latest.outputs.version }}`. 203 | 204 | 205 | See [${{ matrix.chart_dep_name }}'s changelog](${{ matrix.chart_dep_changelog_url }}) 206 | for more information. 207 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.lock 2 | charts 3 | ci/id_rsa 4 | ci/id_rsa.pub 5 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # pre-commit is a tool to perform a predefined set of tasks manually and/or 2 | # automatically before git commits are made. 3 | # 4 | # Config reference: https://pre-commit.com/#pre-commit-configyaml---top-level 5 | # 6 | # Common tasks 7 | # 8 | # - Run on all files: pre-commit run --all-files 9 | # - Register git hooks: pre-commit install --install-hooks 10 | # 11 | # About pre-commit.ci 12 | # 13 | # pre-commit.ci is a service that is enabled for this repo via 14 | # https://github.com/organizations/dask/settings/installations to do the 15 | # following: 16 | # 17 | # 1. Automatically keep the pinned versions in this file updated via PRs. 18 | # 2. Automatically run a pre-commit tests. 19 | # 3. Automatically add a commit with autoformatting changes to PRs if the 20 | # author have forgot to run configured autoformatters. 21 | # 22 | repos: [] 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Dask is a community maintained project. We welcome contributions in the form of bug reports, documentation, code, design proposals, and more. 2 | 3 | For general information on how to contribute see https://docs.dask.org/en/latest/develop.html. 4 | 5 | ## Project specific notes 6 | 7 | ### Pre-commit 8 | 9 | To ensure consistency between contributions we provide a [pre-commit](https://pre-commit.com/) config which automatically runs and fixes all linting steps when you make a commit. 10 | 11 | To get make use of this you need to install and initialize pre-commit in your local repo. 12 | 13 | ```console 14 | $ pip install pre-commit 15 | $ pre-commit install 16 | ``` 17 | 18 | Then when you commit changes checks will be run automatically. 19 | 20 | ```console 21 | $ git commit -m "My foo commit" 22 | frigate..................................................................Passed 23 | helmlint.................................................................Passed 24 | [foo be22e15] My foo commit 25 | 8 files changed, 75 insertions(+), 78 deletions(-) 26 | ... 27 | ``` 28 | 29 | The linting steps may reject your commit or make formatting changes to files which need to be staged and commited. 30 | 31 | Linting steps: 32 | 33 | #### Helm Lint 34 | 35 | This project uses the `helm lint` command from [Helm](https://helm.sh/docs/using_helm/) to ensure the helm chart is valid and can be installed. 36 | 37 | You can lint your changes yourself by running `pre-commit run --all-files` from the root of this repository. 38 | 39 | #### Frigate 40 | 41 | [Frigate](https://github.com/rapidsai/frigate) is a tool for automatically generating documentation for Helm charts. We use it to generate the `README.md` 42 | files in the Chart repos from a `.frigate` jinja template file. The jinja template make use of `values.yaml` and `Chart.yaml` content, so we monitor for changes to 43 | those as well as the generated output. 44 | 45 | You can generate these files yourself with `pre-commit run --all-files`. 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub workflow status - Dask](https://img.shields.io/github/workflow/status/dask/helm-chart/Test%20dask%20chart?logo=github&label=dask)](https://github.com/dask/helm-chart/actions) 2 | [![Dask chart version](https://img.shields.io/badge/dynamic/yaml?url=https://helm.dask.org/index.yaml&label=dask&query=$.entries.dask[:1].version&color=277A9F&logo=helm)](https://helm.dask.org/) 3 | [![Dask version](https://img.shields.io/badge/dynamic/yaml?url=https://helm.dask.org/index.yaml&label=dask&query=$.entries.dask[:1].appVersion&color=D67548&logo=python&logoColor=white)](https://dask.org/) 4 | 5 | [![GitHub workflow status - DaskHub](https://img.shields.io/github/workflow/status/dask/helm-chart/Test%20daskhub%20chart?logo=github&label=daskhub)](https://github.com/dask/helm-chart/actions) 6 | [![DaskHub chart version](https://img.shields.io/badge/dynamic/yaml?url=https://helm.dask.org/index.yaml&label=daskhub&query=$.entries.daskhub[:1].version&color=277A9F&logo=helm)](https://helm.dask.org/) 7 | [![Dask version](https://img.shields.io/badge/dynamic/yaml?url=https://helm.dask.org/index.yaml&label=daskhub&query=$.entries.daskhub[:1].appVersion&color=D67548&logo=python&logoColor=white)](https://dask.org/) 8 | 9 | # Dask Helm Charts 10 | 11 | This repository contains Dask's two helm charts. 12 | 13 | - [dask](./dask/README.md): Install Dask on Kubernetes for a single user with Jupyter and [dask-kubernetes](https://github.com/dask/dask-kubernetes). 14 | - [daskhub](./daskhub/README.md): Install Dask on Kubernetes for multiple users with JupyterHub and [dask-gateway](https://github.com/dask/dask-gateway). 15 | 16 | ## Single-user Quickstart 17 | 18 | Users deploying Dask for a single user should use the `dask/dask` helm chart. 19 | 20 | ``` 21 | helm repo add dask https://helm.dask.org/ 22 | helm repo update 23 | helm install my-release dask/dask 24 | ``` 25 | 26 | See [dask](./dask/README.md) for more. 27 | 28 | ## Multi-user Quickstart 29 | 30 | Users deploying Dask for multiple users should use the `dask/daskhub` helm chart. 31 | 32 | ``` 33 | helm repo add dask https://helm.dask.org/ 34 | helm repo update 35 | helm install --name my-release dask/daskhub 36 | ``` 37 | 38 | See [daskhub](./daskhub/README.md) for more. 39 | -------------------------------------------------------------------------------- /ci/common: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Use https://www.shellcheck.net/ to reduce mistakes if you make changes to this file. 3 | 4 | # Awaits deployments, statefulsets, and daemonsets becoming ready. 5 | full_namespace_await() { 6 | kubectl get deploy,sts,ds -o name \ 7 | | xargs --max-args 1 --no-run-if-empty \ 8 | kubectl rollout status --timeout=3m 9 | } 10 | -------------------------------------------------------------------------------- /ci/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | VERSION=$1 6 | 7 | # Commit Chart.yaml 8 | git commit --allow-empty -m "Version $VERSION" 9 | 10 | # Git tag new version 11 | git tag -a $VERSION -m "Version $VERSION" 12 | 13 | # Push upstream 14 | git push upstream main --tags 15 | -------------------------------------------------------------------------------- /dask/.frigate: -------------------------------------------------------------------------------- 1 | {% extends "markdown.jinja2" %} 2 | 3 | {% block description -%} 4 | [![GitHub workflow status - Dask](https://img.shields.io/github/workflow/status/dask/helm-chart/Test%20dask%20chart?logo=github&label=dask)](https://github.com/dask/helm-chart/actions) 5 | [![Dask chart version](https://img.shields.io/badge/dynamic/yaml?url=https://helm.dask.org/index.yaml&label=dask&query=$.entries.dask[:1].version&color=277A9F&logo=helm)](https://helm.dask.org/) 6 | [![Dask version](https://img.shields.io/badge/dynamic/yaml?url=https://helm.dask.org/index.yaml&label=dask&query=$.entries.dask[:1].appVersion&color=D67548&logo=python&logoColor=white)](https://dask.org/) 7 | 8 | - 9 | - 10 | 11 | ## Chart Details 12 | 13 | This chart will deploy the following: 14 | 15 | - 1 x Dask scheduler with port 8786 (scheduler) and 80 (Web UI) exposed on an external LoadBalancer (default) 16 | - 3 x Dask workers that connect to the scheduler 17 | - 1 x Jupyter notebook (optional) with port 80 exposed on an external LoadBalancer (default) 18 | - All using Kubernetes Deployments 19 | 20 | > **Tip**: See the [Kubernetes Service Type Docs](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) 21 | > for the differences between ClusterIP, NodePort, and LoadBalancer. 22 | 23 | ## Installing the Chart 24 | 25 | First we need to add the Dask helm repo to our local helm config. 26 | 27 | ```bash 28 | helm repo add dask https://helm.dask.org/ 29 | helm repo update 30 | ``` 31 | 32 | To install the chart with the release name `my-release`: 33 | 34 | ```bash 35 | helm install --name my-release dask/dask 36 | ``` 37 | 38 | Depending on how your cluster was setup, you may also need to specify 39 | a namespace with the following flag: `--namespace my-namespace`. 40 | 41 | ### Upgrading an existing installation that used stable/dask 42 | 43 | This chart is fully compatible with the previous chart, it is just a change of location. 44 | If you have an existing deployment of Dask which used the now-deprecated `stable/dask` chart 45 | you can upgrade it by changing the repo name in your upgrade command. 46 | 47 | ```bash 48 | # Add the Dask repo if you haven't already 49 | helm repo add dask https://helm.dask.org/ 50 | helm repo update 51 | 52 | # Upgrade your deployment that was previous created with stable/dask 53 | helm upgrade my-release dask/dask 54 | ``` 55 | {%- endblock %} 56 | 57 | {% block footnotes -%} 58 | #### Jupyter Password 59 | 60 | When launching the Jupyter server, you will be prompted for a password. The 61 | default password set in [values.yaml](/dask/values.yaml) is `dask`. 62 | 63 | ```yaml 64 | jupyter: 65 | ... 66 | password: 'sha1:aae8550c0a44:9507d45e087d5ee481a5ce9f4f16f37a0867318c' # 'dask' 67 | ``` 68 | 69 | To change this password, run `jupyter notebook password` in the command-line, 70 | example below: 71 | 72 | ```bash 73 | $ jupyter notebook password 74 | Enter password: dask 75 | Verify password: dask 76 | [NotebookPasswordApp] Wrote hashed password to /home/dask/.jupyter/jupyter_notebook_config.json 77 | 78 | $ cat /home/dask/.jupyter/jupyter_notebook_config.json 79 | { 80 | "NotebookApp": { 81 | "password": "sha1:aae8550c0a44:9507d45e087d5ee481a5ce9f4f16f37a0867318c" 82 | } 83 | } 84 | ``` 85 | 86 | Replace the `jupyter.password` field in [values.yaml](/dask/values.yaml) with the 87 | hash generated for your new password. 88 | 89 | ## Custom Configuration 90 | 91 | If you want to change the default parameters, you can do this in two ways. 92 | 93 | ### YAML Config Files 94 | 95 | You can change the default parameters in `values.yaml`, or create your own 96 | custom YAML config file, and specify this file when installing your chart with 97 | the `-f` flag. Example: 98 | 99 | ```bash 100 | helm install --name my-release -f values.yaml dask/dask 101 | ``` 102 | 103 | > **Tip**: You can use the default [values.yaml](/dask/values.yaml) for reference 104 | 105 | ### Command-Line Arguments 106 | 107 | If you want to change parameters for a specific install without changing 108 | `values.yaml`, you can use the `--set key=value[,key=value]` flag when running 109 | `helm install`, and it will override any default values. Example: 110 | 111 | ```bash 112 | helm install --name my-release --set jupyter.enabled=false dask/dask 113 | ``` 114 | 115 | ### Customizing Python Environment 116 | 117 | The default `ghcr.io/dask/dask` images have a standard Miniconda installation along 118 | with some common packages like NumPy and Pandas. You can install custom packages 119 | with either Conda or Pip using optional environment variables. This happens 120 | when your container starts up. 121 | 122 | > **Note**: The `IP:PORT` of this chart's services will not be accessible until 123 | > extra packages finish installing. Expect to wait at least a minute for the 124 | > Jupyter Server to be accessible if adding packages below, like `numba`. This 125 | > time will vary depending on which extra packages you choose to install. 126 | 127 | Consider the following YAML config as an example: 128 | 129 | ```yaml 130 | jupyter: 131 | env: 132 | - name: EXTRA_CONDA_PACKAGES 133 | value: numba xarray -c conda-forge 134 | - name: EXTRA_PIP_PACKAGES 135 | value: s3fs dask-ml --upgrade 136 | 137 | worker: 138 | env: 139 | - name: EXTRA_CONDA_PACKAGES 140 | value: numba xarray -c conda-forge 141 | - name: EXTRA_PIP_PACKAGES 142 | value: s3fs dask-ml --upgrade 143 | ``` 144 | 145 | > **Note**: The Jupyter and Dask-worker environments should have matching 146 | > software environments, at least where a user is likely to distribute that 147 | > functionality. 148 | 149 | ### RBAC 150 | 151 | By default the Jupyter pod will be given an RBAC role via a service account which allows you to scale 152 | deployments and access pod logs from the Jupyter pod. 153 | 154 | For example to scale the workers you can run the following command from the Jupyter terminal. 155 | 156 | ```bash 157 | kubectl scale deployment dask-worker --replicas=10 158 | ``` 159 | 160 | You can also get pod logs using kubectl. 161 | 162 | ```bash 163 | # List pods 164 | kubectl get pods 165 | 166 | # Watch pod logs 167 | kubectl logs -f {podname} 168 | ``` 169 | 170 | The RBAC role will give the Jupyter pod access to view all pods and update all deployments in the namespace you 171 | install the Helm Chart in. If you wish to disable this you must disable the Jupyter RBAC and unset the service account. 172 | 173 | ```yaml 174 | jupyter: 175 | rbac: false 176 | serviceAccountName: null 177 | ``` 178 | 179 | Also see the [dask-kubernetes documentation](https://kubernetes.dask.org/en/latest/api.html#dask_kubernetes.HelmCluster) 180 | for the `HelmCluster` cluster manager for managing workers from within your Python session. 181 | 182 | ## Maintaining 183 | 184 | ### Generating the README 185 | 186 | This repo uses [Frigate](https://frigate.readthedocs.io/en/master/index.html) to autogenerate the README. This makes it quick to keep the table 187 | of config options up to date. 188 | 189 | If you wish to make a change to the README body you must edit `dask/.frigate` instead. 190 | 191 | To generate the readme run Frigate. 192 | 193 | ``` 194 | frigate gen dask > README.md 195 | ``` 196 | 197 | ### Releasing 198 | 199 | Releases of the Helm chart are automatically pushed to the `gh-pages` branch by Travis CI when git tags are created. 200 | 201 | Before releasing you may want to ensure the chart is up to date with the latest Docker images and Dask versions: 202 | 203 | - Update the image tags in `dask/values.yaml` to reflect the [latest release of the Dask Docker images](https://github.com/dask/dask-docker/tags). 204 | - Update the `appVersion` value in `dask/Chart.yaml` to also reflect this version. 205 | 206 | Then to perform a release you need to create and push a new tag. 207 | 208 | You can either use the `ci/release.sh` script. 209 | 210 | ``` 211 | ci/release.sh x.x.x 212 | ``` 213 | 214 | Or manually run the steps below. 215 | 216 | - Update the `version` key in `dask/Chart.yaml` with the new chart version `x.x.x`. 217 | - For ease of releasing set the version as an environment variable `export DASK_HELM_VERSION=x.x.x`. 218 | - Add a release commit `git commit -a -m "bump version to $DASK_HELM_VERSION"`. 219 | - Tag the commit `git tag -a $DASK_HELM_VERSION -m "Version $DASK_HELM_VERSION"`. 220 | - Push the tags `git push upstream main --tags`. 221 | - Travis CI will automatically build and release to the chart repository. 222 | 223 | {%- endblock %} 224 | 225 | {% block credits -%} 226 | {%- endblock -%} 227 | -------------------------------------------------------------------------------- /dask/.helmignore: -------------------------------------------------------------------------------- 1 | .frigate 2 | dev-values.yaml 3 | 4 | # Patterns to ignore when building packages. 5 | # This supports shell glob matching, relative path matching, and 6 | # negation (prefixed with !). Only one pattern per line. 7 | .DS_Store 8 | # Common VCS dirs 9 | .git/ 10 | .gitignore 11 | .bzr/ 12 | .bzrignore 13 | .hg/ 14 | .hgignore 15 | .svn/ 16 | # Common backup files 17 | *.swp 18 | *.bak 19 | *.tmp 20 | *.orig 21 | *~ 22 | # Various IDEs 23 | .project 24 | .idea/ 25 | *.tmproj 26 | .vscode/ 27 | -------------------------------------------------------------------------------- /dask/Chart.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | name: dask 4 | version: 0.0.1-set.by.chartpress 5 | appVersion: "2025.4.0" 6 | description: Distributed computation in Python with task scheduling 7 | home: https://dask.org 8 | icon: https://avatars3.githubusercontent.com/u/17131925?v=3&s=200 9 | sources: 10 | - https://github.com/dask/dask 11 | maintainers: 12 | - name: danielfrg 13 | email: df.rodriguez143@gmail.com 14 | - name: mrocklin 15 | email: mrocklin@gmail.com 16 | - name: beberg 17 | email: beberg@gmail.com 18 | - name: jacobtomlinson 19 | email: jacob@tomlinson.email 20 | -------------------------------------------------------------------------------- /dask/README.md: -------------------------------------------------------------------------------- 1 | This file's content will be generated and packaged with the Helm chart upon release, based on the [`.frigate`](.frigate) template. 2 | 3 | You can see previously generated and packaged README.md files by visiting https://artifacthub.io/packages/helm/dask/dask. 4 | -------------------------------------------------------------------------------- /dask/dev-values.yaml: -------------------------------------------------------------------------------- 1 | # TODO: Configure the Helm chart to use as much values as possible to render as 2 | # much in templates as possible to better test it. 3 | -------------------------------------------------------------------------------- /dask/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Thank you for installing {{ .Chart.Name | upper }}, released at name: {{ .Release.Name }}. 2 | 3 | To learn more about the release, try: 4 | 5 | $ helm status {{ .Release.Name }} # information about running pods and this message 6 | $ helm get all {{ .Release.Name }} # get full Kubernetes specification 7 | 8 | This release includes a Dask scheduler, {{ .Values.worker.replicas }} Dask workers, and {{ .Values.jupyter.replicas }} Jupyter servers. 9 | 10 | The Jupyter notebook server and Dask scheduler expose external services to 11 | which you can connect to manage notebooks, or connect directly to the Dask 12 | cluster. You can get these addresses by running the following: 13 | 14 | {{- if contains "NodePort" .Values.scheduler.serviceType }} 15 | 16 | export DASK_SCHEDULER=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath='{.items[0].status.addresses[0].address}') 17 | export DASK_SCHEDULER_UI_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath='{.items[0].status.addresses[0].address}') 18 | export DASK_SCHEDULER_PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "dask.fullname" . }}-scheduler -o jsonpath='{.spec.ports[?(@.name=="{{ template "dask.fullname" . }}-{{ .Values.scheduler.name }}")].nodePort}') 19 | export DASK_SCHEDULER_UI_PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "dask.fullname" . }}-scheduler -o jsonpath='{.spec.ports[?(@.name=="{{ template "dask.fullname" . }}-{{ .Values.webUI.name }}")].nodePort}') 20 | 21 | {{- else if contains "LoadBalancer" .Values.scheduler.serviceType }} 22 | 23 | export DASK_SCHEDULER=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "dask.fullname" . }}-scheduler -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 24 | export DASK_SCHEDULER_UI_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "dask.fullname" . }}-scheduler -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 25 | export DASK_SCHEDULER_PORT={{ .Values.scheduler.servicePort }} 26 | export DASK_SCHEDULER_UI_PORT={{ .Values.webUI.servicePort }} 27 | 28 | {{- else if contains "ClusterIP" .Values.scheduler.serviceType }} 29 | 30 | export DASK_SCHEDULER="127.0.0.1" 31 | export DASK_SCHEDULER_UI_IP="127.0.0.1" 32 | export DASK_SCHEDULER_PORT=8080 33 | export DASK_SCHEDULER_UI_PORT=8081 34 | kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "dask.fullname" . }}-scheduler $DASK_SCHEDULER_PORT:{{ .Values.scheduler.servicePort }} & 35 | kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "dask.fullname" . }}-scheduler $DASK_SCHEDULER_UI_PORT:{{ .Values.webUI.servicePort }} & 36 | 37 | {{- end }} 38 | 39 | 40 | {{- if contains "NodePort" .Values.jupyter.serviceType }} 41 | 42 | export JUPYTER_NOTEBOOK_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath='{.items[0].status.addresses[0].address}') 43 | export JUPYTER_NOTEBOOK_PORT=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "dask.fullname" . }}-jupyter -o jsonpath='{.spec.ports[0].nodePort}') 44 | 45 | {{- else if contains "LoadBalancer" .Values.jupyter.serviceType }} 46 | 47 | export JUPYTER_NOTEBOOK_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "dask.fullname" . }}-jupyter -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 48 | export JUPYTER_NOTEBOOK_PORT={{ .Values.jupyter.servicePort }} 49 | 50 | {{- else if contains "ClusterIP" .Values.jupyter.serviceType }} 51 | 52 | export JUPYTER_NOTEBOOK_IP="127.0.0.1" 53 | export JUPYTER_NOTEBOOK_PORT=8082 54 | kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "dask.fullname" . }}-jupyter $JUPYTER_NOTEBOOK_PORT:{{ .Values.jupyter.servicePort }} & 55 | 56 | {{- end }} 57 | 58 | echo tcp://$DASK_SCHEDULER:$DASK_SCHEDULER_PORT -- Dask Client connection 59 | echo http://$DASK_SCHEDULER_UI_IP:$DASK_SCHEDULER_UI_PORT -- Dask dashboard 60 | echo http://$JUPYTER_NOTEBOOK_IP:$JUPYTER_NOTEBOOK_PORT -- Jupyter notebook 61 | 62 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. Until then, the commands above will not work for the LoadBalancer service type. 63 | You can watch the status by running 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "dask.fullname" . }}-scheduler' 64 | 65 | NOTE: It may take a few minutes for the URLs above to be available if any EXTRA_PIP_PACKAGES or EXTRA_CONDA_PACKAGES were specified, 66 | because they are installed before their respective services start. 67 | 68 | NOTE: The default password to login to the notebook server is `{{ .Values.jupyter.passwordHint }}`. To change this password, refer to the Jupyter password section in values.yaml, or in the README.md. 69 | -------------------------------------------------------------------------------- /dask/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "dask.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "dask.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "dask.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /dask/templates/additional-worker-deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- range $.Values.additional_worker_groups }} 2 | {{- $worker := merge . $.Values.worker }} 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: {{ template "dask.fullname" $ }}-worker-{{ $worker.name }} 7 | labels: 8 | app: {{ template "dask.name" $ }} 9 | heritage: {{ $.Release.Service | quote }} 10 | release: {{ $.Release.Name | quote }} 11 | chart: {{ template "dask.chart" $ }} 12 | component: worker 13 | spec: 14 | replicas: {{ $worker.replicas }} 15 | selector: 16 | matchLabels: 17 | app: {{ template "dask.name" $ }} 18 | release: {{ $.Release.Name | quote }} 19 | component: worker 20 | strategy: 21 | type: {{ $worker.strategy.type }} 22 | template: 23 | metadata: 24 | labels: 25 | app: {{ template "dask.name" $ }} 26 | release: {{ $.Release.Name | quote }} 27 | component: worker 28 | {{- with $worker.annotations }} 29 | annotations: 30 | {{- . | toYaml | nindent 8 }} 31 | {{- end }} 32 | spec: 33 | {{- with $worker.image.pullSecrets }} 34 | imagePullSecrets: 35 | {{- . | toYaml | nindent 8 }} 36 | {{- end }} 37 | {{- with $worker.mounts.volumes }} 38 | volumes: 39 | {{- . | toYaml | nindent 8 }} 40 | {{- end }} 41 | containers: 42 | - name: {{ template "dask.fullname" $ }}-worker 43 | image: "{{ $worker.image.repository }}:{{ $worker.image.tag }}" 44 | {{- with $worker.image.pullPolicy }} 45 | imagePullPolicy: {{ . }} 46 | {{- end }} 47 | args: 48 | - {{ $worker.image.dask_worker }} 49 | {{- if $worker.custom_scheduler_url }} 50 | - {{ $worker.custom_scheduler_url }} 51 | {{- else }} 52 | - {{ template "dask.fullname" $ }}-scheduler:{{ $.Values.scheduler.servicePort }} 53 | {{- end }} 54 | {{- if $worker.resources.limits }} 55 | - --nthreads 56 | - {{ $worker.threads_per_worker | default $worker.resources.limits.cpu | default $worker.default_resources.cpu | quote }} 57 | - --memory-limit 58 | - {{ $worker.resources.limits.memory | default $worker.default_resources.memory | quote }} 59 | {{- end }} 60 | - --no-dashboard 61 | - --dashboard-address 62 | - {{ $worker.portDashboard | quote }} 63 | {{- with $worker.port }} 64 | - --worker-port 65 | - {{ . | quote }} 66 | {{- end }} 67 | {{- with $worker.extraArgs }} 68 | {{- . | toYaml | nindent 12 }} 69 | {{- end }} 70 | ports: 71 | - containerPort: {{ $worker.portDashboard }} 72 | name: dashboard 73 | {{- with $worker.resources }} 74 | resources: 75 | {{- . | toYaml | nindent 12 }} 76 | {{- end }} 77 | {{- with $worker.env }} 78 | env: 79 | {{- . | toYaml | nindent 12 }} 80 | {{- end }} 81 | {{- with $worker.mounts.volumeMounts }} 82 | volumeMounts: 83 | {{- . | toYaml | nindent 12 }} 84 | {{- end }} 85 | {{- with $worker.nodeSelector }} 86 | nodeSelector: 87 | {{- . | toYaml | nindent 8 }} 88 | {{- end }} 89 | {{- with $worker.securityContext }} 90 | securityContext: 91 | {{- . | toYaml | nindent 8 }} 92 | {{- end }} 93 | {{- with $worker.affinity }} 94 | affinity: 95 | {{- . | toYaml | nindent 8 }} 96 | {{- end }} 97 | {{- with $worker.tolerations }} 98 | tolerations: 99 | {{- . | toYaml | nindent 8 }} 100 | {{- end }} 101 | {{- with $worker.serviceAccountName }} 102 | serviceAccountName: {{ . | quote }} 103 | {{- end }} 104 | --- 105 | {{- end }} 106 | -------------------------------------------------------------------------------- /dask/templates/dask-jupyter-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.jupyter.enabled -}} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ template "dask.fullname" . }}-jupyter-config 6 | labels: 7 | app: {{ template "dask.name" . }} 8 | heritage: {{ .Release.Service | quote }} 9 | release: {{ .Release.Name | quote }} 10 | chart: {{ template "dask.chart" . }} 11 | component: jupyter 12 | data: 13 | jupyter_notebook_config.py: | 14 | c = get_config() 15 | c.NotebookApp.password = '{{ .Values.jupyter.password }}' 16 | 17 | {{- with .Values.jupyter.extraConfig }} 18 | 19 | # jupyter.extraConfig follows below 20 | {{- . | nindent 4 }} 21 | {{- end }} 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /dask/templates/dask-jupyter-deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.jupyter.enabled -}} 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: {{ template "dask.fullname" . }}-jupyter 6 | labels: 7 | app: {{ template "dask.name" . }} 8 | heritage: {{ .Release.Service | quote }} 9 | release: {{ .Release.Name | quote }} 10 | chart: {{ template "dask.chart" . }} 11 | component: jupyter 12 | spec: 13 | replicas: 1 14 | selector: 15 | matchLabels: 16 | app: {{ template "dask.name" . }} 17 | release: {{ .Release.Name | quote }} 18 | component: jupyter 19 | strategy: 20 | type: RollingUpdate 21 | template: 22 | metadata: 23 | labels: 24 | app: {{ template "dask.name" . }} 25 | release: {{ .Release.Name | quote }} 26 | component: jupyter 27 | spec: 28 | {{- with .Values.jupyter.image.pullSecrets }} 29 | imagePullSecrets: 30 | {{- . | toYaml | nindent 8 }} 31 | {{- end }} 32 | containers: 33 | - name: {{ template "dask.fullname" . }}-jupyter 34 | image: "{{ .Values.jupyter.image.repository }}:{{ .Values.jupyter.image.tag }}" 35 | {{- with .Values.jupyter.image.pullPolicy }} 36 | imagePullPolicy: {{ . }} 37 | {{- end }} 38 | {{- with .Values.jupyter.command }} 39 | command: 40 | {{- . | toYaml | nindent 12 }} 41 | {{- end }} 42 | {{- with .Values.jupyter.args }} 43 | args: 44 | {{- . | toYaml | nindent 12 }} 45 | {{- end }} 46 | ports: 47 | - containerPort: 8888 48 | resources: 49 | {{- toYaml .Values.jupyter.resources | nindent 12 }} 50 | volumeMounts: 51 | - name: config-volume 52 | mountPath: /usr/local/etc/jupyter 53 | {{- with .Values.jupyter.mounts.volumeMounts }} 54 | {{- . | toYaml | nindent 12 }} 55 | {{- end }} 56 | env: 57 | - name: DASK_SCHEDULER_ADDRESS 58 | value: {{ template "dask.fullname" . }}-scheduler:{{ .Values.scheduler.servicePort }} 59 | {{- with .Values.jupyter.env }} 60 | {{- . | toYaml | nindent 12 }} 61 | {{- end }} 62 | {{- with .Values.jupyter.livenessProbe}} 63 | livenessProbe: 64 | {{- . | toYaml | nindent 12 }} 65 | {{- end }} 66 | {{- with .Values.jupyter.readinessProbe }} 67 | readinessProbe: 68 | {{- . | toYaml | nindent 12 }} 69 | {{- end }} 70 | volumes: 71 | {{- with .Values.jupyter.mounts.volumes }} 72 | {{- . | toYaml | nindent 8}} 73 | {{- end }} 74 | - name: config-volume 75 | configMap: 76 | name: {{ template "dask.fullname" . }}-jupyter-config 77 | {{- with .Values.jupyter.nodeSelector }} 78 | nodeSelector: 79 | {{- . | toYaml | nindent 8 }} 80 | {{- end }} 81 | {{- with .Values.jupyter.affinity }} 82 | affinity: 83 | {{- . | toYaml | nindent 8 }} 84 | {{- end }} 85 | {{- with .Values.jupyter.securityContext }} 86 | securityContext: 87 | {{- . | toYaml | nindent 8 }} 88 | {{- end }} 89 | {{- with .Values.jupyter.tolerations }} 90 | tolerations: 91 | {{- . | toYaml | nindent 8 }} 92 | {{- end }} 93 | {{- with .Values.jupyter.serviceAccountName }} 94 | serviceAccountName: {{ . | quote }} 95 | {{- end }} 96 | {{- end }} 97 | -------------------------------------------------------------------------------- /dask/templates/dask-jupyter-ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.jupyter.ingress.enabled -}} 2 | {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }} 3 | apiVersion: networking.k8s.io/v1 4 | {{- else }} 5 | apiVersion: networking.k8s.io/v1beta1 6 | {{- end }} 7 | kind: Ingress 8 | metadata: 9 | name: {{ template "dask.fullname" . }}-jupyter 10 | labels: 11 | app: {{ template "dask.fullname" . }}-jupyter 12 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 13 | release: "{{ .Release.Name }}" 14 | heritage: "{{ .Release.Service }}" 15 | {{- with .Values.jupyter.ingress.annotations }} 16 | annotations: 17 | {{- . | toYaml | nindent 4 }} 18 | {{- end }} 19 | spec: 20 | {{- with .Values.jupyter.ingress.ingressClassName }} 21 | ingressClassName: "{{ . }}" 22 | {{- end }} 23 | {{- if .Values.jupyter.ingress.tls }} 24 | tls: 25 | - hosts: 26 | - {{ .Values.jupyter.ingress.hostname | quote }} 27 | secretName: {{ .Values.jupyter.ingress.secretName | default (printf "%s-jupyter-tls" (include "dask.fullname" .)) }} 28 | {{- end }} 29 | rules: 30 | - http: 31 | paths: 32 | - path: / 33 | {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }} 34 | pathType: {{ .Values.jupyter.ingress.pathType }} 35 | backend: 36 | service: 37 | name: {{ template "dask.fullname" . }}-jupyter 38 | port: 39 | number: {{ .Values.jupyter.servicePort }} 40 | {{- else }} 41 | backend: 42 | serviceName: {{ template "dask.fullname" . }}-jupyter 43 | servicePort: {{ .Values.jupyter.servicePort }} 44 | {{- end }} 45 | {{- with .Values.jupyter.ingress.hostname }} 46 | host: {{ . }} 47 | {{- end }} 48 | {{- end }} 49 | -------------------------------------------------------------------------------- /dask/templates/dask-jupyter-service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.jupyter.enabled -}} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ template "dask.fullname" . }}-jupyter 6 | labels: 7 | app: {{ template "dask.name" . }} 8 | heritage: {{ .Release.Service | quote }} 9 | release: {{ .Release.Name | quote }} 10 | chart: {{ template "dask.chart" . }} 11 | component: jupyter 12 | spec: 13 | ports: 14 | - name: {{ template "dask.fullname" . }}-jupyter 15 | port: {{ .Values.jupyter.servicePort }} 16 | targetPort: 8888 17 | selector: 18 | app: {{ template "dask.name" . }} 19 | release: {{ .Release.Name | quote }} 20 | component: jupyter 21 | type: {{ .Values.jupyter.serviceType }} 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /dask/templates/dask-jupyter-serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.jupyter.enabled .Values.jupyter.rbac -}} 2 | kind: ServiceAccount 3 | apiVersion: v1 4 | metadata: 5 | name: dask-jupyter 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app: {{ template "dask.name" . }} 9 | release: {{ .Release.Name | quote }} 10 | component: jupyter 11 | 12 | --- 13 | 14 | kind: Role 15 | apiVersion: rbac.authorization.k8s.io/v1 16 | metadata: 17 | name: dask-jupyter 18 | namespace: {{ .Release.Namespace }} 19 | labels: 20 | app: {{ template "dask.name" . }} 21 | release: {{ .Release.Name | quote }} 22 | component: jupyter 23 | rules: 24 | - apiGroups: ["apps"] 25 | resources: ["deployments"] 26 | verbs: ["get", "list", "watch", "update", "patch"] 27 | - apiGroups: [""] # "" indicates the core API group 28 | resources: ["pods"] 29 | verbs: ["get", "list", "watch"] 30 | - apiGroups: [""] # "" indicates the core API group 31 | resources: ["pods/log"] 32 | verbs: ["get", "list"] 33 | 34 | --- 35 | 36 | kind: RoleBinding 37 | apiVersion: rbac.authorization.k8s.io/v1 38 | metadata: 39 | name: dask-jupyter 40 | namespace: {{ .Release.Namespace }} 41 | labels: 42 | app: {{ template "dask.name" . }} 43 | release: {{ .Release.Name | quote }} 44 | component: jupyter 45 | subjects: 46 | - kind: ServiceAccount 47 | name: dask-jupyter 48 | roleRef: 49 | kind: Role 50 | name: dask-jupyter 51 | apiGroup: rbac.authorization.k8s.io 52 | {{- end }} 53 | -------------------------------------------------------------------------------- /dask/templates/dask-scheduler-deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.scheduler.enabled -}} 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: {{ template "dask.fullname" . }}-scheduler 6 | labels: 7 | app: {{ template "dask.name" . }} 8 | heritage: {{ .Release.Service | quote }} 9 | release: {{ .Release.Name | quote }} 10 | chart: {{ template "dask.chart" . }} 11 | component: scheduler 12 | spec: 13 | replicas: {{ .Values.scheduler.replicas }} 14 | selector: 15 | matchLabels: 16 | app: {{ template "dask.name" . }} 17 | release: {{ .Release.Name | quote }} 18 | component: scheduler 19 | strategy: 20 | type: RollingUpdate 21 | template: 22 | metadata: 23 | labels: 24 | app: {{ template "dask.name" . }} 25 | release: {{ .Release.Name | quote }} 26 | component: scheduler 27 | spec: 28 | {{- with .Values.scheduler.image.pullSecrets }} 29 | imagePullSecrets: 30 | {{- . | toYaml | nindent 8 }} 31 | {{- end }} 32 | containers: 33 | - name: {{ template "dask.fullname" . }}-scheduler 34 | image: "{{ .Values.scheduler.image.repository }}:{{ .Values.scheduler.image.tag }}" 35 | {{- with .Values.scheduler.image.pullPolicy }} 36 | imagePullPolicy: {{ . }} 37 | {{- end }} 38 | args: 39 | - dask-scheduler 40 | - --port={{ .Values.scheduler.servicePort }} 41 | - --dashboard-address=:8787 42 | {{- with .Values.scheduler.extraArgs }} 43 | {{- . | toYaml | nindent 12 }} 44 | {{- end }} 45 | ports: 46 | - containerPort: 8786 47 | - containerPort: 8787 48 | {{- with .Values.scheduler.resources }} 49 | resources: 50 | {{- . | toYaml | nindent 12 }} 51 | {{- end }} 52 | {{- with .Values.scheduler.env }} 53 | env: 54 | {{- . | toYaml | nindent 12 }} 55 | {{- end }} 56 | {{- with .Values.scheduler.livenessProbe }} 57 | livenessProbe: 58 | {{- . | toYaml | nindent 12 }} 59 | {{- end }} 60 | {{- with .Values.scheduler.readinessProbe }} 61 | readinessProbe: 62 | {{- . | toYaml | nindent 12 }} 63 | {{- end }} 64 | 65 | {{- with .Values.scheduler.nodeSelector }} 66 | nodeSelector: 67 | {{- . | toYaml | nindent 8 }} 68 | {{- end }} 69 | {{- with .Values.scheduler.securityContext }} 70 | securityContext: 71 | {{- . | toYaml | nindent 8 }} 72 | {{- end }} 73 | {{- with .Values.scheduler.affinity }} 74 | affinity: 75 | {{- . | toYaml | nindent 8 }} 76 | {{- end }} 77 | {{- with .Values.scheduler.tolerations }} 78 | tolerations: 79 | {{- . | toYaml | nindent 8 }} 80 | {{- end }} 81 | {{- with .Values.scheduler.serviceAccountName }} 82 | serviceAccountName: {{ . | quote }} 83 | {{- end }} 84 | {{- end }} 85 | -------------------------------------------------------------------------------- /dask/templates/dask-scheduler-ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.scheduler.enabled .Values.webUI.ingress.enabled -}} 2 | {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" -}} 3 | apiVersion: networking.k8s.io/v1 4 | {{- else }} 5 | apiVersion: networking.k8s.io/v1beta1 6 | {{- end }} 7 | kind: Ingress 8 | metadata: 9 | name: {{ template "dask.fullname" . }}-scheduler 10 | labels: 11 | app: {{ template "dask.fullname" . }}-scheduler 12 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 13 | release: "{{ .Release.Name }}" 14 | heritage: "{{ .Release.Service }}" 15 | {{- with .Values.webUI.ingress.annotations }} 16 | annotations: 17 | {{- . | toYaml | nindent 4 }} 18 | {{- end }} 19 | spec: 20 | {{- with .Values.webUI.ingress.ingressClassName }} 21 | ingressClassName: "{{ . }}" 22 | {{- end }} 23 | {{- if .Values.webUI.ingress.tls }} 24 | tls: 25 | - hosts: 26 | - {{ .Values.webUI.ingress.hostname | quote }} 27 | secretName: {{ .Values.webUI.ingress.secretName | default (printf "%s-scheduler-tls" (include "dask.fullname" .)) }} 28 | {{- end }} 29 | rules: 30 | - http: 31 | paths: 32 | - path: / 33 | {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }} 34 | pathType: {{ .Values.webUI.ingress.pathType }} 35 | backend: 36 | service: 37 | name: {{ template "dask.fullname" . }}-scheduler 38 | port: 39 | number: {{ .Values.webUI.servicePort }} 40 | {{- else }} 41 | backend: 42 | serviceName: {{ template "dask.fullname" . }}-scheduler 43 | servicePort: {{ .Values.webUI.servicePort }} 44 | {{- end }} 45 | {{- with .Values.webUI.ingress.hostname }} 46 | host: {{ . }} 47 | {{- end }} 48 | {{- end }} 49 | -------------------------------------------------------------------------------- /dask/templates/dask-scheduler-service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.scheduler.enabled -}} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ template "dask.fullname" . }}-scheduler 6 | labels: 7 | app: {{ template "dask.name" . }} 8 | heritage: {{ .Release.Service | quote }} 9 | release: {{ .Release.Name | quote }} 10 | chart: {{ template "dask.chart" . }} 11 | component: scheduler 12 | {{- with .Values.scheduler.serviceAnnotations }} 13 | annotations: 14 | {{- . | toYaml | nindent 4 }} 15 | {{- end }} 16 | spec: 17 | ports: 18 | - name: {{ template "dask.fullname" . }}-scheduler 19 | port: {{ .Values.scheduler.servicePort }} 20 | targetPort: 8786 21 | - name: {{ template "dask.fullname" . }}-webui 22 | port: {{ .Values.webUI.servicePort }} 23 | targetPort: 8787 24 | selector: 25 | app: {{ template "dask.name" . }} 26 | release: {{ .Release.Name | quote }} 27 | component: scheduler 28 | type: {{ .Values.scheduler.serviceType }} 29 | {{- with .Values.scheduler.loadBalancerIP }} 30 | loadBalancerIP: {{ . }} 31 | {{- end }} 32 | {{ end }} 33 | -------------------------------------------------------------------------------- /dask/templates/dask-scheduler-servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.scheduler.metrics.enabled .Values.scheduler.metrics.serviceMonitor.enabled }} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | name: {{ template "dask.fullname" . }}-scheduler-servicemonitor 6 | {{- with .Values.scheduler.metrics.serviceMonitor.namespace }} 7 | namespace: {{ . | quote }} 8 | {{- end }} 9 | labels: 10 | app: {{ template "dask.name" . }} 11 | heritage: {{ .Release.Service | quote }} 12 | release: {{ .Release.Name | quote }} 13 | chart: {{ template "dask.chart" . }} 14 | component: scheduler 15 | {{- with .Values.scheduler.metrics.serviceMonitor.additionalLabels }} 16 | {{- . | toYaml | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | endpoints: 20 | - interval: {{ .Values.scheduler.metrics.serviceMonitor.interval }} 21 | port: {{ template "dask.fullname" . }}-webui 22 | {{- with .Values.scheduler.metrics.serviceMonitor.metricRelabelings }} 23 | metricRelabelings: 24 | {{- . | toYaml . | nindent 8 }} 25 | {{- end }} 26 | {{- if .Values.scheduler.metrics.serviceMonitor.namespaceSelector }} 27 | namespaceSelector: 28 | {{- .Values.scheduler.metrics.serviceMonitor.namespaceSelector | toYaml | nindent 4 }} 29 | {{ else }} 30 | namespaceSelector: 31 | matchNames: 32 | - {{ .Release.Namespace }} 33 | {{- end }} 34 | {{- with .Values.scheduler.metrics.serviceMonitor.jobLabel }} 35 | jobLabel: {{ . }} 36 | {{- end }} 37 | {{- with .Values.scheduler.metrics.serviceMonitor.targetLabels }} 38 | targetLabels: 39 | {{- . | toYaml | nindent 4 }} 40 | {{- end }} 41 | selector: 42 | matchLabels: 43 | app: {{ template "dask.name" . }} 44 | release: {{ .Release.Name | quote }} 45 | component: scheduler 46 | {{- end }} 47 | -------------------------------------------------------------------------------- /dask/templates/dask-worker-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "dask.fullname" . }}-worker 5 | labels: 6 | app: {{ template "dask.name" . }} 7 | heritage: {{ .Release.Service | quote }} 8 | release: {{ .Release.Name | quote }} 9 | chart: {{ template "dask.chart" . }} 10 | component: worker 11 | spec: 12 | replicas: {{ .Values.worker.replicas }} 13 | selector: 14 | matchLabels: 15 | app: {{ template "dask.name" . }} 16 | release: {{ .Release.Name | quote }} 17 | component: worker 18 | {{- with .Values.worker.strategy }} 19 | strategy: 20 | {{- . | toYaml | nindent 4 }} 21 | {{- end }} 22 | template: 23 | metadata: 24 | labels: 25 | app: {{ template "dask.name" . }} 26 | release: {{ .Release.Name | quote }} 27 | component: worker 28 | {{- with .Values.worker.annotations }} 29 | annotations: 30 | {{- . | toYaml | nindent 8 }} 31 | {{- end }} 32 | spec: 33 | {{- with .Values.worker.image.pullSecrets }} 34 | imagePullSecrets: 35 | {{- . | toYaml | nindent 8 }} 36 | {{- end }} 37 | {{- with .Values.worker.mounts.volumes }} 38 | volumes: 39 | {{- . | toYaml | nindent 8}} 40 | {{- end }} 41 | containers: 42 | - name: {{ template "dask.fullname" . }}-worker 43 | image: "{{ .Values.worker.image.repository }}:{{ .Values.worker.image.tag }}" 44 | imagePullPolicy: {{ .Values.worker.image.pullPolicy }} 45 | args: 46 | - {{ .Values.worker.image.dask_worker }} 47 | {{- if .Values.worker.custom_scheduler_url }} 48 | - {{ .Values.worker.custom_scheduler_url }} 49 | {{- else }} 50 | - {{ template "dask.fullname" . }}-scheduler:{{ .Values.scheduler.servicePort }} 51 | {{- end }} 52 | {{- if .Values.worker.resources.limits }} 53 | - --nthreads 54 | - {{ .Values.worker.threads_per_worker | default .Values.worker.resources.limits.cpu | default .Values.worker.default_resources.cpu | quote }} 55 | - --memory-limit 56 | - {{ .Values.worker.resources.limits.memory | default .Values.worker.default_resources.memory | quote }} 57 | {{- end }} 58 | - --no-dashboard 59 | - --dashboard-address 60 | - {{ .Values.worker.portDashboard | quote }} 61 | {{- with .Values.worker.port }} 62 | - --worker-port 63 | - {{ . | quote }} 64 | {{- end }} 65 | {{- with .Values.worker.extraArgs }} 66 | {{ . | toYaml | nindent 12 }} 67 | {{- end }} 68 | ports: 69 | - containerPort: {{ .Values.worker.portDashboard }} 70 | name: dashboard 71 | {{- with .Values.worker.resources }} 72 | resources: 73 | {{- . | toYaml | nindent 12 }} 74 | {{- end }} 75 | {{- with .Values.worker.env }} 76 | env: 77 | {{- . | toYaml | nindent 12 }} 78 | {{- end }} 79 | {{- with .Values.worker.mounts.volumeMounts }} 80 | volumeMounts: 81 | {{- . | toYaml | nindent 12 }} 82 | {{- end }} 83 | {{ with .Values.worker.livenessProbe }} 84 | livenessProbe: 85 | {{- . | toYaml | nindent 12 }} 86 | {{- end }} 87 | {{ with .Values.worker.readinessProbe }} 88 | readinessProbe: 89 | {{- . | toYaml | nindent 12 }} 90 | {{- end }} 91 | 92 | {{- with .Values.worker.nodeSelector }} 93 | nodeSelector: 94 | {{- . | toYaml | nindent 8 }} 95 | {{- end }} 96 | {{- with .Values.worker.securityContext }} 97 | securityContext: 98 | {{- . | toYaml | nindent 8 }} 99 | {{- end }} 100 | {{- with .Values.worker.affinity }} 101 | affinity: 102 | {{- . | toYaml | nindent 8 }} 103 | {{- end }} 104 | {{- with .Values.worker.tolerations }} 105 | tolerations: 106 | {{- . | toYaml | nindent 8 }} 107 | {{- end }} 108 | {{- with .Values.worker.serviceAccountName }} 109 | serviceAccountName: {{ . | quote }} 110 | {{- end }} 111 | -------------------------------------------------------------------------------- /dask/templates/dask-worker-podmonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.worker.metrics.enabled .Values.worker.metrics.podMonitor.enabled -}} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: PodMonitor 4 | metadata: 5 | name: {{ template "dask.fullname" . }}-worker-podmonitor 6 | {{- with .Values.worker.metrics.podMonitor.namespace }} 7 | namespace: {{ . | quote }} 8 | {{- end }} 9 | labels: 10 | app: {{ template "dask.name" . }} 11 | heritage: {{ .Release.Service | quote }} 12 | release: {{ .Release.Name | quote }} 13 | chart: {{ template "dask.chart" . }} 14 | component: worker 15 | {{- with .Values.worker.metrics.podMonitor.additionalLabels }} 16 | {{- . | toYaml | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | podMetricsEndpoints: 20 | - interval: {{ .Values.worker.metrics.podMonitor.interval }} 21 | port: dashboard 22 | scheme: http 23 | {{- with .Values.worker.metrics.podMonitor.metricRelabelings }} 24 | metricRelabelings: 25 | {{- . | toYaml | nindent 8 }} 26 | {{- end }} 27 | {{- if .Values.worker.metrics.podMonitor.namespaceSelector }} 28 | namespaceSelector: 29 | {{- .Values.worker.metrics.podMonitor.namespaceSelector | toYaml | nindent 4 }} 30 | {{- else }} 31 | namespaceSelector: 32 | matchNames: 33 | - {{ .Release.Namespace }} 34 | {{- end }} 35 | {{- with .Values.worker.metrics.podMonitor.jobLabel }} 36 | jobLabel: {{ . }} 37 | {{- end }} 38 | {{- with .Values.worker.metrics.podMonitor.targetLabels }} 39 | podTargetLabels: 40 | {{- . | toYaml | nindent 4 }} 41 | {{- end }} 42 | selector: 43 | matchLabels: 44 | app: {{ template "dask.name" . }} 45 | release: {{ .Release.Name | quote }} 46 | component: worker 47 | {{- end }} 48 | -------------------------------------------------------------------------------- /dask/values.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # nameOverride: dask 3 | # fullnameOverride: dask 4 | 5 | scheduler: 6 | name: scheduler # Dask scheduler name. 7 | enabled: true # Enable/disable scheduler. 8 | image: 9 | repository: "ghcr.io/dask/dask" # Container image repository. 10 | tag: "2025.4.0" # Container image tag. 11 | pullPolicy: IfNotPresent # Container image pull policy. 12 | pullSecrets: # Container image [pull secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). 13 | # - name: regcred 14 | replicas: 1 # Number of schedulers (should always be 1). 15 | serviceType: "ClusterIP" # Scheduler service type. Set to `LoadBalancer` to expose outside of your cluster. 16 | # serviceType: "NodePort" 17 | # serviceType: "LoadBalancer" 18 | loadBalancerIP: null # Some cloud providers allow you to specify the loadBalancerIP when using the `LoadBalancer` service type. If your cloud does not support it this option will be ignored. 19 | servicePort: 8786 # Scheduler service internal port. 20 | serviceAnnotations: {} # Scheduler service annotations. 21 | env: # Environment variables. See `values.yaml` for example values. 22 | # - name: EXTRA_APT_PACKAGES 23 | # value: build-essential openssl 24 | # - name: EXTRA_CONDA_PACKAGES 25 | # value: numba xarray -c conda-forge 26 | # - name: EXTRA_PIP_PACKAGES 27 | # value: s3fs dask-ml prometheus-client --upgrade 28 | 29 | extraArgs: 30 | [] # Extra CLI arguments to be passed to the scheduler 31 | # - --preload 32 | # - scheduler-setup.py 33 | resources: {} # Scheduler pod resources. See `values.yaml` for example values. 34 | # limits: 35 | # cpu: 1.8 36 | # memory: 6G 37 | # requests: 38 | # cpu: 1.8 39 | # memory: 6G 40 | tolerations: [] # Tolerations. 41 | affinity: {} # Container affinity. 42 | nodeSelector: {} # Node Selector. 43 | securityContext: {} # Security Context. 44 | # serviceAccountName: "" 45 | metrics: 46 | enabled: false # Enable scheduler metrics. Pip package [prometheus-client](https://pypi.org/project/prometheus-client/) should be present on scheduler. 47 | serviceMonitor: 48 | enabled: false # Enable scheduler servicemonitor. 49 | namespace: "" # Deploy servicemonitor in different namespace, e.g. monitoring. 50 | namespaceSelector: {} # Selector to select which namespaces the Endpoints objects are discovered from. 51 | # Default: scrape .Release.Namespace only 52 | # To scrape all, use the following: 53 | # namespaceSelector: 54 | # any: true 55 | additionalLabels: {} # Additional labels to add to the ServiceMonitor metadata. 56 | interval: 30s # Interval at which metrics should be scraped. 57 | jobLabel: "" # The label to use to retrieve the job name from. 58 | targetLabels: [] # TargetLabels transfers labels on the Kubernetes Service onto the target. 59 | metricRelabelings: [] # MetricRelabelConfigs to apply to samples before ingestion. 60 | livenessProbe: 61 | {} # Enables scheduler liveness probe. 62 | # httpGet: 63 | # path: /health 64 | # port: 8787 65 | # initialDelaySeconds: 3 66 | # periodSeconds: 10 67 | readinessProbe: 68 | {} # Enables scheduler readiness probe. 69 | # httpGet: 70 | # path: /status 71 | # port: 8787 72 | # initialDelaySeconds: 3 73 | # periodSeconds: 10 74 | 75 | webUI: 76 | name: webui # Dask webui name. 77 | servicePort: 80 # webui service internal port. 78 | ingress: 79 | enabled: false # Enable ingress. 80 | # ingressClassName: 81 | pathType: Prefix # set pathType in ingress 82 | tls: false # Ingress should use TLS. 83 | # secretName: dask-scheduler-tls 84 | hostname: dask-ui.example.com # Ingress hostname. 85 | annotations: 86 | {} # Ingress annotations. See `values.yaml` for example values. 87 | # kubernetes.io/ingress.class: "nginx" 88 | # secretName: my-tls-cert 89 | # kubernetes.io/tls-acme: "true" 90 | 91 | worker: 92 | name: worker # Dask worker name. 93 | image: 94 | repository: "ghcr.io/dask/dask" # Container image repository. 95 | tag: "2025.4.0" # Container image tag. 96 | pullPolicy: IfNotPresent # Container image pull policy. 97 | dask_worker: "dask-worker" # Dask worker command. E.g `dask-cuda-worker` for GPU worker. 98 | pullSecrets: # Container image [pull secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). 99 | # - name: regcred 100 | replicas: 3 # Number of workers. 101 | strategy: 102 | type: RollingUpdate # Strategy used to replace old Pods with new ones. 103 | custom_scheduler_url: null # connect to already existing scheduler, deployed not by this chart. 104 | default_resources: # overwritten by resource limits if they exist 105 | cpu: 1 # Default CPU (DEPRECATED use `resources`). 106 | memory: "4GiB" # Default memory (DEPRECATED use `resources`). 107 | env: # Environment variables. See `values.yaml` for example values. 108 | # - name: EXTRA_APT_PACKAGES 109 | # value: build-essential openssl 110 | # - name: EXTRA_CONDA_PACKAGES 111 | # value: numba xarray -c conda-forge 112 | # - name: EXTRA_PIP_PACKAGES 113 | # value: s3fs dask-ml prometheus-client --upgrade 114 | extraArgs: 115 | [] # Extra CLI arguments to be passed to the worker 116 | # - --preload 117 | # - worker-setup.py 118 | resources: {} # Worker pod resources. See `values.yaml` for example values. 119 | # limits: 120 | # cpu: 1 121 | # memory: 3G 122 | # nvidia.com/gpu: 1 123 | # requests: 124 | # cpu: 1 125 | # memory: 3G 126 | # nvidia.com/gpu: 1 127 | mounts: {} # Worker Pod volumes and volume mounts, mounts.volumes follows kuberentes api v1 Volumes spec. mounts.volumeMounts follows kubernetesapi v1 VolumeMount spec 128 | # volumes: 129 | # - name: data 130 | # emptyDir: {} 131 | # volumeMounts: 132 | # - name: data 133 | # mountPath: /data 134 | annotations: {} # Annotations 135 | tolerations: [] # Tolerations. 136 | affinity: {} # Container affinity. 137 | nodeSelector: {} # Node Selector. 138 | securityContext: {} # Security Context. 139 | # serviceAccountName: "" 140 | # port: "" 141 | portDashboard: 8790 # Worker dashboard and metrics port. 142 | # this option overrides "--nthreads" on workers, which defaults to resources.limits.cpu / default_resources.limits.cpu 143 | # use it if you need to limit the amount of threads used by multicore workers, or to make workers with non-whole-number cpu limits 144 | # threads_per_worker: 1 145 | metrics: 146 | enabled: false # Enable workers metrics. Pip package [prometheus-client](https://pypi.org/project/prometheus-client/) should be present on workers. 147 | podMonitor: 148 | enabled: false # Enable workers podmonitor 149 | namespace: "" # Deploy podmonitor in different namespace, e.g. monitoring. 150 | namespaceSelector: {} # Selector to select which namespaces the Endpoints objects are discovered from. 151 | # Default: scrape .Release.Namespace only 152 | # To scrape all, use the following: 153 | # namespaceSelector: 154 | # any: true 155 | # metrics will apply to the additional worker groups as well 156 | additionalLabels: {} # Additional labels to add to the PodMonitor metadata. 157 | interval: 30s # Interval at which metrics should be scraped. 158 | jobLabel: "" # The label to use to retrieve the job name from. 159 | podTargetLabels: [] # PodTargetLabels transfers labels on the Kubernetes Pod onto the target. 160 | metricRelabelings: [] # MetricRelabelConfigs to apply to samples before ingestion. 161 | livenessProbe: 162 | {} # Enables worker pod liveness probe 163 | # httpGet: 164 | # path: /health 165 | # port: 8790 # The same as portDashboard 166 | # initialDelaySeconds: 3 167 | # periodSeconds: 10 168 | readinessProbe: 169 | {} # Enables worker pod readiness probe 170 | # httpGet: 171 | # path: /status 172 | # port: 8790 # The same as portDashboard 173 | # initialDelaySeconds: 3 174 | # periodSeconds: 10 175 | 176 | additional_worker_groups: [] # Additional groups of workers to create. List of groups with same options as `worker`. 177 | # - name: high-mem # Dask worker group name. 178 | # extraArgs: 179 | # - --resources 180 | # - "MEMORY=6e9" 181 | # resources: 182 | # limits: 183 | # memory: 32G 184 | # requests: 185 | # memory: 32G 186 | # ... 187 | # (Defaults will be taken from the primary worker configuration) 188 | 189 | jupyter: 190 | name: jupyter # Jupyter name. 191 | enabled: true # Enable/disable the bundled Jupyter notebook. 192 | rbac: true # Create RBAC service account and role to allow Jupyter pod to scale worker pods and access logs. 193 | image: 194 | repository: "ghcr.io/dask/dask-notebook" # Container image repository. 195 | tag: "2025.4.0" # Container image tag. 196 | pullPolicy: IfNotPresent # Container image pull policy. 197 | pullSecrets: # Container image [pull secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). 198 | # - name: regcred 199 | # 200 | serviceType: "ClusterIP" # Scheduler service type. Set to `LoadBalancer` to expose outside of your cluster. 201 | # serviceType: "NodePort" 202 | # serviceType: "LoadBalancer" 203 | servicePort: 80 # Jupyter service internal port. 204 | # This hash corresponds to the password 'dask' 205 | password: "sha1:aae8550c0a44:9507d45e087d5ee481a5ce9f4f16f37a0867318c" # Password hash. Default hash corresponds to the password `dask`. 206 | passwordHint: "dask" # This is only used in the help text, don't forget to update the hash too. 207 | env: # Environment variables. See `values.yaml` for example values. 208 | # - name: EXTRA_CONDA_PACKAGES 209 | # value: "numba xarray -c conda-forge" 210 | # - name: EXTRA_PIP_PACKAGES 211 | # value: "s3fs dask-ml --upgrade" 212 | command: null # Container command. 213 | args: # Container arguments. 214 | # - "start.sh" 215 | # - "jupyter" 216 | # - "lab" 217 | extraConfig: |- 218 | # Extra Jupyter config goes here 219 | # E.g 220 | # c.NotebookApp.port = 8888 221 | resources: {} # Jupyter pod resources. See `values.yaml` for example values. 222 | # limits: 223 | # cpu: 2 224 | # memory: 6G 225 | # requests: 226 | # cpu: 2 227 | # memory: 6G 228 | mounts: {} # Worker Pod volumes and volume mounts, mounts.volumes follows kuberentes api v1 Volumes spec. mounts.volumeMounts follows kubernetesapi v1 VolumeMount spec 229 | # volumes: 230 | # - name: data 231 | # emptyDir: {} 232 | # volumeMounts: 233 | # - name: data 234 | # mountPath: /data 235 | tolerations: [] # Tolerations. 236 | affinity: {} # Container affinity. 237 | nodeSelector: {} # Node Selector. 238 | securityContext: {} # Security Context. 239 | serviceAccountName: "dask-jupyter" # Service account for use with RBAC 240 | ingress: 241 | enabled: false # Enable ingress. 242 | # ingressClassName: 243 | tls: false # Ingress should use TLS. 244 | # secretName: dask-jupyter-tls 245 | pathType: Prefix # set pathType in ingress 246 | hostname: dask-jupyter.example.com # Ingress hostname. 247 | annotations: 248 | {} # Ingress annotations. See `values.yaml` for example values. 249 | # kuernetesbernetes.io/ingress.class: "nginx" 250 | # secretName: my-tls-cert 251 | # kub.io/tls-acme: "true" 252 | livenessProbe: 253 | {} # Enables jupyter server liveness probe. 254 | # httpGet: 255 | # path: /login 256 | # port: 8888 257 | # initialDelaySeconds: 3 258 | # periodSeconds: 10 259 | readinessProbe: 260 | {} # Enables jupyter server readiness probe. 261 | # httpGet: 262 | # path: /login 263 | # port: 8888 264 | # initialDelaySeconds: 3 265 | # periodSeconds: 10 266 | -------------------------------------------------------------------------------- /daskhub/.frigate: -------------------------------------------------------------------------------- 1 | {% extends "markdown.jinja2" %} 2 | 3 | {% block description -%} 4 | [![GitHub workflow status - DaskHub](https://img.shields.io/github/workflow/status/dask/helm-chart/Test%20daskhub%20chart?logo=github&label=daskhub)](https://github.com/dask/helm-chart/actions) 5 | [![DaskHub chart version](https://img.shields.io/badge/dynamic/yaml?url=https://helm.dask.org/index.yaml&label=daskhub&query=$.entries.daskhub[:1].version&color=277A9F&logo=helm)](https://helm.dask.org/) 6 | [![Dask version](https://img.shields.io/badge/dynamic/yaml?url=https://helm.dask.org/index.yaml&label=daskhub&query=$.entries.daskhub[:1].appVersion&color=D67548&logo=python&logoColor=white)](https://dask.org/) 7 | 8 | This chart provides a multi-user, Dask-Gateway enabled JupyterHub. 9 | It combines the [JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) 10 | and [Dask Gateway](https://gateway.dask.org/) helm charts. 11 | 12 | For single users, a simpler setup is supported by the `dask` helm chart. 13 | 14 | See [CHANGELOG](./CHANGELOG.md) for a information about changes in the `daskhub` helm chart. 15 | 16 | ## Chart Details 17 | 18 | This chart will deploy the following 19 | 20 | - A standard Dask Gateway deployment using the Dask Gateway helm chart, 21 | configured to use JupyterHub for authentication. 22 | - A standard JupyterHub deployment using the JupyterHub helm chart, 23 | configured proxy Dask Gateway requests and set Dask Gateway-related 24 | environment variables. 25 | 26 | ## Install DaskHub 27 | 28 | This example installs into the namespace `dhub`. Create and pass chart 29 | configuration via `config.yaml`. 30 | 31 | ```console 32 | $ helm upgrade --wait --install --render-subchart-notes \ 33 | dhub dask/daskhub \ 34 | --namespace=dhub \ 35 | --values=config.yaml 36 | ``` 37 | 38 | The output explains how to find the IPs for your JupyterHub and Dask Gateway. 39 | 40 | ```console 41 | $ kubectl -n dhub get service proxy-public 42 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 43 | proxy-public LoadBalancer 10.43.249.239 35.202.158.223 443:31587/TCP,80:30500/TCP 2m40s 44 | ``` 45 | 46 | JupyterHub is available at the `proxy-public` external ip (35.202.158.223 in this example). 47 | 48 | ## Creating a Dask Cluster 49 | 50 | To create a Dask cluster users can create a `dask_gateway.GatewayCluster`. 51 | 52 | ```python 53 | >>> from dask_gateway import GatewayCluster 54 | >>> cluster = GatewayCluster() 55 | >>> client = cluster.get_client() 56 | ``` 57 | 58 | If necessary (say to set options, create clusters that outlive the notebook session, etc.), 59 | users can connect to the Gateway 60 | 61 | 62 | ```python 63 | >>> from dask_gateway import Gateway 64 | >>> gateway = Gateway() 65 | ``` 66 | 67 | See https://gateway.dask.org/ for more on using Dask Gateway. 68 | 69 | ## Matching the user environment 70 | 71 | Dask Clients will be running the JupyterHub's singleuser environment. To ensure 72 | that the same environment is used for the scheduler and workers, you can provide 73 | it as a Gateway option. 74 | 75 | ```yaml 76 | # config.yaml 77 | jupyterhub: 78 | singleuser: 79 | extraEnv: 80 | DASK_GATEWAY__CLUSTER__OPTIONS__IMAGE: '{JUPYTER_IMAGE_SPEC}' 81 | 82 | dask-gateway: 83 | gateway: 84 | extraConfig: 85 | optionHandler: | 86 | from dask_gateway_server.options import Options, Integer, Float, String 87 | def option_handler(options): 88 | if ":" not in options.image: 89 | raise ValueError("When specifying an image you must also provide a tag") 90 | return { 91 | "image": options.image, 92 | } 93 | c.Backend.cluster_options = Options( 94 | String("image", default="pangeo/base-notebook:2022.09.21", label="Image"), 95 | handler=option_handler, 96 | ) 97 | ``` 98 | 99 | The user environment will need to include `dask-gateway`. 100 | 101 | ## Using dask-kubernetes instead of Dask Gateway 102 | 103 | Users who don't need Dask Gateway can use dask-kubernetes to manage creating Dask Clusters. To use dask-kubernetes, you should set 104 | 105 | ``` 106 | # config.yaml 107 | daskhub: 108 | jupyterhub: 109 | singleuser: 110 | servieAccountName: daskkubernetes 111 | 112 | dask-gateway: 113 | enabled: false 114 | 115 | dask-kubernetes: 116 | enabled: true 117 | ``` 118 | 119 | When deploying, helm will create a Kubernetes ServiceAccount, Role, and RoleBinding. This ensures that the pods serving JupyterHub singleusers have the eleveated permissions for starting and stopping pods. 120 | 121 | {%- endblock %} 122 | 123 | {% block credits -%} 124 | {%- endblock -%} 125 | -------------------------------------------------------------------------------- /daskhub/.helmignore: -------------------------------------------------------------------------------- 1 | .frigate 2 | dev-values.yaml 3 | CHANGELOG.md 4 | 5 | # Patterns to ignore when building packages. 6 | # This supports shell glob matching, relative path matching, and 7 | # negation (prefixed with !). Only one pattern per line. 8 | .DS_Store 9 | # Common VCS dirs 10 | .git/ 11 | .gitignore 12 | .bzr/ 13 | .bzrignore 14 | .hg/ 15 | .hgignore 16 | .svn/ 17 | # Common backup files 18 | *.swp 19 | *.bak 20 | *.tmp 21 | *.orig 22 | *~ 23 | # Various IDEs 24 | .project 25 | .idea/ 26 | *.tmproj 27 | .vscode/ 28 | -------------------------------------------------------------------------------- /daskhub/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document logs changes between versions of the `daskhub` helm chart. 4 | 5 | ## 2021.6.1 6 | 7 | ### Version Updates 8 | 9 | * Updated JupyterHub helm chart to version 1.0.1. See the [zero-to-jupyterhub-k8s changelog](https://github.com/jupyterhub/zero-to-jupyterhub-k8s/blob/main/CHANGELOG.md#10) for instructions on upgrading. 10 | * Updated default `singleuser` image to use [`pangeo/base-notebook:2021.06.05](https://hub.docker.com/layers/pangeo/base-notebook/2021.06.05/images/sha256-c02c631921ab98ea00a206ed994359f8e0a4785a317d8c1e13e20df3362fcc2f?context=explore) with [these package versions](https://github.com/pangeo-data/pangeo-docker-images/blob/2021.06.05/base-notebook/packages.txt). 11 | -------------------------------------------------------------------------------- /daskhub/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: daskhub 3 | icon: https://avatars3.githubusercontent.com/u/17131925?v=3&s=200 4 | version: 0.0.1-set.by.chartpress 5 | # appVersion is set to be a combination of the dependencies 6 | appVersion: "jh4.2.0-dg2025.4.0" 7 | description: Multi-user JupyterHub and Dask deployment. 8 | dependencies: 9 | - name: jupyterhub 10 | version: "4.2.0" 11 | repository: https://jupyterhub.github.io/helm-chart/ 12 | import-values: 13 | - child: rbac 14 | parent: rbac 15 | - name: dask-gateway 16 | version: "2025.4.0" 17 | repository: https://helm.dask.org/ 18 | maintainers: 19 | - name: Jacob Tomlinson (Nvidia) 20 | email: jtomlinson@nvidia.com 21 | - name: Joe Hamman (NCAR) 22 | email: jhamman@ucar.edu 23 | - name: Erik Sundell 24 | email: erik@sundellopensource.se 25 | - name: Tom Augspurger 26 | email: tom.w.augspurger@gmail.com 27 | -------------------------------------------------------------------------------- /daskhub/README.md: -------------------------------------------------------------------------------- 1 | This file's content will be generated and packaged with the Helm chart upon release, based on the [`.frigate`](.frigate) template. 2 | 3 | You can see previously generated and packaged README.md files by visiting https://artifacthub.io/packages/helm/dask/daskhub. 4 | -------------------------------------------------------------------------------- /daskhub/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | DaskHub 2 | ------- 3 | 4 | Thank you for installing DaskHub, a multiuser, Dask-enabled JupyterHub! 5 | 6 | Your release is named {{.Release.Name}} and installed into the namespace {{.Release.Namespace}}. 7 | 8 | 9 | Jupyter Hub 10 | ----------- 11 | 12 | You can find if the hub and proxy is ready by doing: 13 | 14 | kubectl --namespace={{.Release.Namespace}} get pod 15 | 16 | and watching for both those pods to be in status 'Ready'. 17 | 18 | You can find the public IP of the JupyterHub by doing: 19 | 20 | kubectl --namespace={{.Release.Namespace}} get svc proxy-public 21 | 22 | It might take a few minutes for it to appear! 23 | -------------------------------------------------------------------------------- /daskhub/templates/dask-kubernetes-rbac.yaml: -------------------------------------------------------------------------------- 1 | {{- if and (index .Values "dask-kubernetes" "enabled") .Values.rbac.enabled -}} 2 | kind: ServiceAccount 3 | apiVersion: v1 4 | metadata: 5 | name: daskkubernetes 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 9 | component: daskkubernetes 10 | heritage: {{ .Release.Service }} 11 | release: {{ .Release.Name }} 12 | 13 | --- 14 | 15 | kind: Role 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | metadata: 18 | name: daskkubernetes 19 | namespace: {{ .Release.Namespace }} 20 | labels: 21 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 22 | component: daskkubernetes 23 | heritage: {{ .Release.Service }} 24 | release: {{ .Release.Name }} 25 | rules: 26 | - apiGroups: [""] # "" indicates the core API group 27 | resources: ["pods", "services"] 28 | verbs: ["get", "list", "watch", "create", "delete"] 29 | - apiGroups: [""] # "" indicates the core API group 30 | resources: ["pods/log"] 31 | verbs: ["get", "list"] 32 | 33 | --- 34 | 35 | kind: RoleBinding 36 | apiVersion: rbac.authorization.k8s.io/v1 37 | metadata: 38 | name: daskkubernetes 39 | namespace: {{ .Release.Namespace }} 40 | labels: 41 | chart: {{ .Chart.Name }}-{{ .Chart.Version }} 42 | component: daskkubernetes 43 | heritage: {{ .Release.Service }} 44 | release: {{ .Release.Name }} 45 | subjects: 46 | - kind: ServiceAccount 47 | name: daskkubernetes 48 | roleRef: 49 | kind: Role 50 | name: daskkubernetes 51 | apiGroup: rbac.authorization.k8s.io 52 | {{- end }} 53 | -------------------------------------------------------------------------------- /daskhub/values.yaml: -------------------------------------------------------------------------------- 1 | # DaskHub configuration values 2 | # ---------------------------- 3 | rbac: 4 | enabled: true # Create and use roles and service accounts on an RBAC-enabled cluster. 5 | 6 | jupyterhub: 7 | # JupyterHub configuration goes here. 8 | # See https://github.com/jupyterhub/zero-to-jupyterhub-k8s/blob/master/jupyterhub/values.yaml 9 | hub: 10 | services: 11 | dask-gateway: 12 | display: false 13 | 14 | extraConfig: 15 | # Register Dask Gateway service and setup singleuser environment. 16 | 00-add-dask-gateway-values: | 17 | # 1. Sets `DASK_GATEWAY__PROXY_ADDRESS` in the singleuser environment. 18 | # 2. Adds the URL for the Dask Gateway JupyterHub service. 19 | import os 20 | 21 | # These are set by jupyterhub. 22 | release_name = os.environ["HELM_RELEASE_NAME"] 23 | release_namespace = os.environ["POD_NAMESPACE"] 24 | 25 | if "PROXY_HTTP_SERVICE_HOST" in os.environ: 26 | # https is enabled, we want to use the internal http service. 27 | gateway_address = "http://{}:{}/services/dask-gateway/".format( 28 | os.environ["PROXY_HTTP_SERVICE_HOST"], 29 | os.environ["PROXY_HTTP_SERVICE_PORT"], 30 | ) 31 | print("Setting DASK_GATEWAY__ADDRESS {} from HTTP service".format(gateway_address)) 32 | else: 33 | gateway_address = "http://proxy-public/services/dask-gateway" 34 | print("Setting DASK_GATEWAY__ADDRESS {}".format(gateway_address)) 35 | 36 | # Internal address to connect to the Dask Gateway. 37 | c.KubeSpawner.environment.setdefault("DASK_GATEWAY__ADDRESS", gateway_address) 38 | # Internal address for the Dask Gateway proxy. 39 | c.KubeSpawner.environment.setdefault("DASK_GATEWAY__PROXY_ADDRESS", "gateway://traefik-{}-dask-gateway.{}:80".format(release_name, release_namespace)) 40 | # Relative address for the dashboard link. 41 | c.KubeSpawner.environment.setdefault("DASK_GATEWAY__PUBLIC_ADDRESS", "/services/dask-gateway/") 42 | # Use JupyterHub to authenticate with Dask Gateway. 43 | c.KubeSpawner.environment.setdefault("DASK_GATEWAY__AUTH__TYPE", "jupyterhub") 44 | 45 | # Adds Dask Gateway as a JupyterHub service to make the gateway available at 46 | # {HUB_URL}/services/dask-gateway 47 | service_url = "http://traefik-{}-dask-gateway.{}".format(release_name, release_namespace) 48 | for service in c.JupyterHub.services: 49 | if service["name"] == "dask-gateway": 50 | if not service.get("url", None): 51 | print("Adding dask-gateway service URL") 52 | service.setdefault("url", service_url) 53 | break 54 | else: 55 | print("dask-gateway service not found, this should not happen!") 56 | 57 | singleuser: 58 | image: 59 | name: pangeo/base-notebook # Image to use for singleuser environment. Must include dask-gateway. 60 | tag: "2025.01.24" 61 | defaultUrl: "/lab" # Use jupyterlab by default. 62 | 63 | dask-gateway: 64 | enabled: true # Enabling dask-gateway will install Dask Gateway as a dependency. 65 | # Further Dask Gateway configuration goes here 66 | # See https://github.com/dask/dask-gateway/blob/master/resources/helm/dask-gateway/values.yaml 67 | gateway: 68 | prefix: "/services/dask-gateway" # Users connect to the Gateway through the JupyterHub service. 69 | auth: 70 | type: jupyterhub # Use JupyterHub to authenticate with Dask Gateway 71 | traefik: 72 | service: 73 | type: ClusterIP # Access Dask Gateway through JupyterHub. To access the Gateway from outside JupyterHub, this must be changed to a `LoadBalancer`. 74 | 75 | dask-kubernetes: 76 | # Use dask-kubernetes, rather than Dask Gateway, for creating Dask Clusters. 77 | # Enabling this also requires 78 | # 1. Setting `jupyterhub.singleuser.serviceAccountName: daskkubernetes`. 79 | # 2. Ensuring that `dask-kubernetes` is in your singleuser environment. 80 | enabled: false 81 | --------------------------------------------------------------------------------