Kubernetes apps
Azimuth allows operators to provide a catalog of applications (apps) that users are able to install onto their Kubernetes clusters via the Azimuth user interface. Multiple apps can be installed on the same Kubernetes cluster, and each app gets its own namespace.
A Kubernetes app in Azimuth essentially consists of a
Helm chart. Azimuth manages specially annotated instances
of the HelmRelease
resource from the
Cluster API addon provider to install
and upgrade apps on the target cluster. These apps can be integrated with Zenith
to expose services to the user without requiring the use of
LoadBalancer services
or Kubernetes ingress.
The available apps and the available versions of those apps are determined by instances of a
custom resource
provided by the
Azimuth Kubernetes operator -
apptemplates.azimuth.stackhpc.com
- which references a chart in a
Helm chart repository. Azimuth uses the
chart metadata to generate the user
interface for the app template, and the values schema
for the chart to generate a form for collecting input from the user.
Azimuth also renders the output of the NOTES.txt file in the user interface, so this can be used to describe how to consume the application.
Warning
If the chart does not have a values schema, the generated form will be blank and the chart will be deployed with the default values.
Tip
In addition, a file called azimuth-ui.schema.yaml
can be included to apply some small
customisations to the generated form, like selecting different controls. See the
azimuth-charts for examples.
Default app templates
Azimuth comes with the following app templates enabled by default:
jupyterhub
- Allows the user to deploy JupyterHub on their clusters. JupyterHub provides a multi-user environment for using Jupyter notebooks where each user gets their own dynamically-provisioned notebook server and storage. The Jupyter notebook interface is exposed using Zenith.
daskhub
- A JupyterHub instance with Dask integration. Dask is a library that aims
to simplify the process of scaling data-intensive Python applications, such as those using
Numpy or pandas. DaskHub installs
Dask Gateway alongside JupyterHub and configures them so that
they integrate seamlessly. This allows users to easily create Dask clusters in their notebooks
that scale out by creating pods on the underlying Kubernetes cluster. As with
jupyterhub
above, the notebook interface is exposed using Zenith. binderhub
- A JupyterHub instance with Binder integration.
BinderHub allows you to create custom computing environments that can be shared and used by
many remote users. As with
jupyterhub
above, the notebook interface is exposed using Zenith. kubeflow
- Allows users to deploy the Kubeflow machine learning toolkit on their clusters. Kubeflow provides an interface for easily accessing best-of-breed machine learning systems using Jupyter notebooks and TensorFlow.
huggingface-llm
- A generative AI chatbot service backed by a HuggingFace large language model. A convenient web interface is exposed via Zenith and the backend API is directly accessible to other applications running on the same Kubernetes cluster for programmatic use cases. For further details, see this blog post.
These can be disabled by setting the following variables:
azimuth_capi_operator_app_templates_jupyterhub_enabled: false
azimuth_capi_operator_app_templates_daskhub_enabled: false
azimuth_capi_operator_app_templates_binderhub_enabled: false
azimuth_capi_operator_app_templates_kubeflow_enabled: false
azimuth_capi_operator_app_templates_huggingface_llm_enabled: false
Custom app templates
If you have Helm charts that you want to make available as apps, you can define them as follows:
azimuth_capi_operator_app_templates_extra:
# The key is the name of the app template
my-custom-app:
# Access control annotations
annotations: {}
# The cluster template specification
spec:
# This is the only required field, and determines the chart that is used
chart:
# The chart repository containing the chart
repo: https://my.company.org/helm-charts
# The name of the chart that the template is for
name: my-custom-app
Access control
See Access control for more details on the access control annotations.
By default, Azimuth will use the last 5 stable versions of the chart (i.e. versions without a
prerelease part, see semver.org) and the name
, icon
and description
from the Chart.yaml file in the chart
to build the user interface. A chart annotation is also supported to define the human-readable
label:
This behaviour can be customised for each app template using the following optional fields:
label
- The human-readable label for the app template, instead of the annotation from
Chart.yaml
. logo
- The URL of the logo for the app template, instead of the
icon
fromChart.yaml
. description
- A short description of the app template, instead of the
description
fromChart.yaml
. versionRange
- Default:
>=0.0.0
(stable versions only).
The range of chart versions to consider.
Must be a comma-separated list of constraints, where each constraint is an operator followed by a SemVer version. The supported operators are==
,!=
,>
,>=
,<
and<=
.
Prerelease versions are only considered if the lower bound includes a prerelease part. If no lower bound is given, an implicit lower bound of>=0.0.0
is used.
Some examples of valid ranges:
>=0.0.0-0
- all versions, including prerelease versions like1.0.0-alpha.1
-
<2.0.0
- all stable versions matching0.X.Y
and1.X.Y
(implicit lower bound) -
>=1.0.0,<3.0.0,!=2.1.5
- all stable versions matching1.X.Y
or2.X.Y
except2.1.5
(useful for excluding specific versions with known issues)
keepVersions
- Default: 5.
The number of versions to keep.
This is used to limit the size of theAppTemplate
resource, because etcd has limits on the maximum size of objects (usually approx. 1MB). This will need to be smaller if the chart has a large values schema. syncFrequency
- Default: 86400 (24 hours).
The number of seconds to wait before checking for new versions of the chart. defaultValues
- Default:
{}
.
Default values for deployments of the app, on top of the chart defaults.
Zenith integration
When Zenith is enabled, every Kubernetes cluster created by Azimuth has an
instance of the Zenith operator watching
it. This operator makes two Kubernetes custom resources available that can be used to expose a
Kubernetes service to users
without using type: NodePort
, type: LoadBalancer
or
Kubernetes ingress:
reservations.zenith.stackhpc.com
- Represents the reservation of a Zenith domain, and results in the generation of a Kubernetes secret containing an SSH keypair associated with the allocated domain.
clients.zenith.stackhpc.com
- Defines a Zenith client, pointing at a Zenith reservation and upstream Kubernetes service.
In addition, services can benefit from the project-level authentication and authorization that is performed by Zenith at it's proxy to prevent unauthorised users from accessing the service. The Zenith services associated with an app are monitored and made available in the Azimuth user interface, making the apps easy to use.
Azimuth supports the following annotations on the reservation to determine how the service is rendered in the user interface:
annotations:
azimuth.stackhpc.com/service-label: "My Fancy Service"
azimuth.stackhpc.com/service-icon-url: https://my.company.org/images/my-fancy-service-icon.png
It is possible to add Zenith integration to an existing chart by creating a new parent chart with the existing chart as a dependency. You can define templates for the Zenith resources in the parent chart, pointing at services created by the child chart.
This is the approach taken by the azimuth-charts
that provide the default jupyterhub
and daskhub
apps.
Created: March 22, 2024