Kubernetes see history edit this page

Talks about: , , , and

JaaS ships as a container image at ghcr.io/metio/jaas:latest and as a Helm chart at oci://ghcr.io/metio/helm-charts/jaas, also listed on ArtifactHub . Pre-built binaries for Linux, macOS, and Windows are attached to each GitHub release for operators who prefer to run the binary directly.

Prerequisites

The Flux CR-based mode (below) additionally needs:

The OCI volume-mounting mode needs neither Flux nor cert-manager.

Install and update

helm upgrade --install is idempotent: the same command installs the chart the first time and applies your changes on every subsequent run, so it’s the only deploy command you need. To update later, re-run it with an updated --values file or --set flags.

The chart runs JaaS in one of two mutually exclusive modes in a single release. Pick the one that matches your use case; you cannot combine them in one release — the chart’s pre-install preflight rejects the combination.

Mode 1 — OCI volume mounting (HTTP renderer)

JaaS evaluates Jsonnet snippets on demand and returns JSON over HTTP. Snippets and libraries are mounted into the pod from OCI artifacts as image volumes (the snippets and additionalLibraries chart values), read straight from a registry. There are no CRDs, no leader election, and no persistent storage — the pod is stateless.

helm upgrade --install jaas oci://ghcr.io/metio/helm-charts/jaas \
  --namespace jaas-system --create-namespace \
  --values my-values.yaml \
  --wait

A minimal my-values.yamlsnippets and additionalLibraries are maps of name: image-reference:

# Snippets to render — a map of name: image. The name becomes the URL path, so
# this snippet is served at GET /jsonnet/dashboards.
snippets:
  dashboards: ghcr.io/my-org/my-dashboards:latest

# Well-known libraries have a built-in toggle — enable grafonnet with one flag
# (the chart already knows its JOI image). docsonnet and xtd work the same way.
libraries:
  grafonnet:
    enabled: true

# additionalLibraries mounts any OTHER library image — a JOI library without a
# built-in toggle, or your own private bundle. The map KEY is the directory the
# image mounts under and that the renderer adds to its import search path
# (`--library-path /srv/libraries/<key>`); it must be unique. The entry below
# mounts ghcr.io/acme/jsonnet-acme-lib at /srv/libraries/acme.
additionalLibraries:
  acme: ghcr.io/acme/jsonnet-acme-lib:latest

The chart mounts each image read-only and wires the renderer for you. The dashboards snippet is then reachable at GET /jsonnet/dashboards. A library is imported by the path it resolves to under its search directory — for a jb-vendored image like grafonnet, the full vendor path baked into it:

import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet'

The Jsonnet HTTP server listens on port 8080 (configurable via ports.http).

Mode 2 — Flux CR-based (operator)

JaaS watches JsonnetSnippet and JsonnetLibrary CRs, evaluates snippets, and publishes the results as ExternalArtifact resources. Downstream Flux consumers (kustomize-controller, helm-controller, stageset-controller) fetch the rendered JSON from the artifact server.

helm upgrade --install jaas oci://ghcr.io/metio/helm-charts/jaas \
  --namespace jaas-system --create-namespace \
  --set operator.enabled=true \
  --set operator.storage.persistence.enabled=true \
  --wait

A minimal values snippet for the operator shape:

operator:
  enabled: true
  storage:
    # local backend with a PVC — enough for a single-replica install. For
    # multi-replica HA, switch to backend: s3 (see /running/production/).
    backend: local
    persistence:
      enabled: true
      size: 10Gi

The operator publishes artifacts at the URL configured via operator.storage.baseURL. Left empty, it defaults to the in-cluster Service DNS name (http://jaas-storage.<namespace>.svc.cluster.local:<port>), which is correct when downstream Flux consumers fetch artifacts from inside the cluster. Set it explicitly only when consumers dereference the artifacts through an Ingress or external hostname.

Install with Flux (GitOps)

To manage JaaS from a Flux GitOps repository instead of helm on the command line, point an OCIRepository at the chart and install it with a HelmRelease. The values: block takes exactly the same keys as the --values file above — this example is the operator shape with local storage:

apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
  name: jaas
  namespace: jaas-system
spec:
  interval: 1h
  url: oci://ghcr.io/metio/helm-charts/jaas
  ref:
    # Latest released chart. Pin to a specific tag for production; Renovate can
    # keep the pin current.
    semver: ">=0.0.0"
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: jaas
  namespace: jaas-system
spec:
  interval: 1h
  chartRef:
    kind: OCIRepository
    name: jaas
  values:
    operator:
      enabled: true
      storage:
        backend: local
        persistence:
          enabled: true
          size: 10Gi

Both resources live in jaas-system, so the namespace must exist first: create it with kubectl create namespace jaas-system, or include a Namespace manifest alongside them. The source- and helm-controllers reconcile an OCIRepository and HelmRelease directly, so no wrapping Kustomization is required — apply the two with kubectl apply -f, or commit them to whatever Git/OCI source your Flux setup already syncs. For the HTTP-renderer shape, drop the operator block and set snippets / libraries under values: instead. HelmRelease gives you upgrades, rollbacks, and drift correction; pull the chart version forward by bumping the OCIRepository ref.

Manage the CRDs

The chart ships its CRDs (JsonnetSnippet, JsonnetLibrary) inside the regular templates — not Helm’s special crds/ directory — so a helm upgrade --install applies schema changes like any other resource, governed by crds.create (default true). The CRDs carry helm.sh/resource-policy: keep, so a helm uninstall leaves them — and your existing resources — in place; remove them by hand only if you really mean to.

Check Upgrading before upgrading across a release that changes an immutable field such as a Deployment’s spec.selector.matchLabels — those require a manual kubectl --namespace jaas-system delete deploy jaas first.

If you manage CRDs out of band, the raw definitions are published in the repository under config/crd/bases/ and can be applied with kubectl apply --server-side -f.

Customize

Every setting the chart exposes — the two modes above, storage backend, leader election, the admission webhook, NetworkPolicy, service mesh, metrics, and the rest — is a Helm value. Two references cover them:

For production sizing — S3 storage, multi-replica HA, observability, and webhook hardening — see the Production guide .

Verify

For the operator shape, confirm the Deployment is available and the CRDs are registered:

kubectl --namespace jaas-system rollout status deploy/jaas
kubectl get crd jsonnetsnippets.jaas.metio.wtf jsonnetlibraries.jaas.metio.wtf

For the HTTP renderer, confirm the pod is ready and the endpoint answers:

kubectl --namespace jaas-system get pods --selector app.kubernetes.io/name=jaas
kubectl --namespace jaas-system port-forward svc/jaas 8080:8080 &
curl http://localhost:8080/jsonnet/my-dashboard

Next steps