Files
capsule/playground
Oliver BählerandGitHub 647b113702 chore: add deprecation notices (#2089)
* fix: revert pv labeling to dircet api reads

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* fix: revert pv labeling to dircet api reads

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: add deprecation warnings

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* chore: implement playground

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* chore: implement playground

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

---------

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
2026-08-19 15:08:47 +02:00
..

Capsule local playground

This playground creates a two-node kind cluster and installs Capsule, Capsule Proxy, Dex, Headlamp, and ingress-nginx through Flux. HTTP services share ports 80 and 443 through host-based ingress routing. Capsule Proxy is the only component exposed on its own port (9001).

The kind API server is configured as an OIDC relying party for Dex after Dex and ingress become ready. It uses Kubernetes' reloadable authentication config, so there is no API-server/Dex bootstrap cycle. Dex users are mapped from the name claim to the sample Capsule owners (alice, bob, and gatsby). These local usernames are registered explicitly as Capsule users, and authorization comes from tenant ownership and the RBAC managed by Capsule. The pinned Dex version does not emit the groups entries from staticPasswords, so the admin login is deliberately not granted Kubernetes cluster-admin by default.

Prerequisites

  • Docker
  • kind
  • kubectl
  • Flux CLI
  • GNU envsubst (usually provided by gettext)
  • OpenSSL
  • curl and jq
  • make

The development targets (make dev and make dev-capsule) additionally need Go and Helm. The pinned ko binary is installed automatically by the root Makefile when it is not already available.

The default hostnames need to resolve to loopback. Register them in /etc/hosts with:

make hosts

This target is idempotent and prompts for sudo only when a hostname is missing. The equivalent manual entry is:

127.0.0.1 dex.capsule.local headlamp.capsule.local proxy.capsule.local gangplank.capsule.local

On macOS, verify resolution through the system resolver with:

dscacheutil -q host -a name headlamp.capsule.local

host and dig query DNS servers directly, so they can report NXDOMAIN for entries that work correctly through /etc/hosts.

Inside kind, CoreDNS maps the configured Dex hostname to the ingress controller. The worker address is also registered as a host alias on the kube-apiserver static Pod, allowing it to discover Dex's signing keys at the same issuer URL.

Then start the environment from this directory:

make up

To start the same environment with Capsule built from the current checkout, use:

make dev

The default endpoints are:

Headlamp uses Dex for login. These local-only accounts use the username as the password; enter the email address in Dex's login form:

Email Username Password Access
alice@projectcapsule.dev alice alice Owns solar; also sees the green namespaces shared by the sample proxy rule
bob@projectcapsule.dev bob bob Owns green
gatsby@projectcapsule.dev gatsby gatsby Owns wind; also sees the solar namespaces shared by the sample proxy rule
renewable@projectcapsule.dev renewable renewable Authenticates as the local renewable user
admin@example.com admin admin Authenticates successfully but has no elevated Kubernetes RBAC by default

The setup generates one persistent local CA under installation/.generated/ and reuses it for Dex, Headlamp, Capsule, Capsule Proxy, and kube-apiserver OIDC trust. Changing a hostname reissues only the affected service certificate; it does not rotate the CA. A workstation browser will report the certificate as untrusted unless that CA is imported locally.

The reloadable API-server configuration is generated at installation/.generated/authentication-config.yaml. It starts with an empty jwt list while the cluster bootstraps, then make up replaces it with the Dex issuer, shared CA, audience, and claim mappings after Dex is reachable.

Configuration

Copy .env.example to .env and change the hostnames or public URLs as needed. The Makefile supplies the shown defaults even when .env does not exist. CLUSTER_NAME and PROXY_PORT can also be overridden when another local kind cluster already uses the defaults.

To inspect the exact resources after Kustomize and environment substitution:

make render

Substitution is restricted to the declared host and URL variables. This keeps other dollar-prefixed content, including Dex password hashes, unchanged.

Useful lifecycle commands:

make status          # inspect the cluster and Flux releases
make apply           # reapply playground configuration after editing it
make dev-capsule     # rebuild and redeploy only Capsule from the current checkout
make capsule-stable  # return Capsule to the pinned Flux-managed release
make down            # delete the kind cluster

Developing Capsule in the playground

make dev first performs the normal playground setup, including the platform and user examples, and then builds the Capsule controller with ko. The image is loaded directly into the kind nodes and the release is upgraded from the local ../charts/capsule chart. Local chart templates and CRDs are therefore deployed together with the controller code.

While a development build is installed, reconciliation of the capsule HelmRelease is suspended so Flux cannot replace it with the pinned chart. The other playground releases, including Capsule Proxy, remain managed by Flux. The local Helm upgrade reuses the playground values and its persistent CA.

After changing the source, rebuild and roll out Capsule without recreating the cluster:

make dev-capsule

From the repository root, the existing make dev-setup-capsule target delegates to this playground target.

The repository root's legacy make dev-setup target uses a different handoff: it runs the Capsule controller on the workstation and points admission webhooks at LAPTOP_HOST_IP. Before installing that development release, it waits for flux-system/capsule to become ready and deletes only that HelmRelease. Waiting for deletion lets the Flux Helm controller finish uninstalling the pinned release before local Helm takes ownership. All other playground HelmReleases remain managed by Flux.

LAPTOP_HOST_IP=192.168.1.10 make dev-setup

Each invocation uses a timestamped development tag. Set one explicitly when a predictable image name is useful:

make dev-capsule DEV_VERSION=my-branch

The default local image is ko.local/capsule. Its registry and repository can be changed with DEV_IMAGE_REGISTRY and DEV_IMAGE_REPOSITORY.

To leave development mode and restore the release declared in installation/capsule/release.flux.yaml, run:

make capsule-stable

If root make dev-setup deleted the Capsule HelmRelease, capsule-stable recreates it from the playground installation manifests before asking Flux to reconcile it.