Warning
This documentation is actively being updated as the project evolves and may not be complete in all areas.
Install with Operator¶
This guide covers installing Jumpstarter with the Kubernetes operator, using:
Ingress on vanilla Kubernetes
Route on OpenShift
It mirrors how make deploy METHOD=operator deploys the operator and creates a Jumpstarter custom resource (CR), but uses production-friendly manifests and release artifacts.
Prerequisites¶
A Kubernetes, OpenShift, or OKD cluster
kubectl(oroc) configured for your clusterCluster-admin permissions (required to install CRDs and operator RBAC)
A DNS domain for Jumpstarter service endpoints (for example,
jumpstarter.example.com)An ingress controller on Kubernetes, or Routes on OpenShift/OKD
Note
This page focuses on operator installation and core CR configuration. It does not cover full setup of external components such as Dex/other OIDC providers or cert-manager installation.
Install the operator¶
If your Kubernetes cluster already has OLM, install the operator from OperatorHub and then continue with the Jumpstarter custom resource in this guide.
OperatorHub package page:
Note
On vanilla Kubernetes, this OperatorHub path assumes OLM is already installed and configured in your cluster.
Log in to the OpenShift/OKD web console with cluster-admin permissions.
Go to Operators -> OperatorHub.
Search for Jumpstarter Operator and install it.
Wait until the installed operator status is
Succeeded.
Verify from CLI:
$ oc get csv -n openshift-operators | grep jumpstarter
Create a Subscription (example: subscription.yaml):
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: jumpstarter-operator
namespace: openshift-operators
spec:
channel: alpha
name: jumpstarter-operator
source: community-operators
sourceNamespace: openshift-marketplace
installPlanApproval: Automatic
Apply and verify:
$ oc apply -f subscription.yaml
$ oc get csv -n openshift-operators | grep jumpstarter
Apply the operator installer from a release asset:
$ kubectl apply -f https://github.com/jumpstarter-dev/jumpstarter/releases/download/<release-tag>/operator-installer.yaml
For example:
$ kubectl apply -f https://github.com/jumpstarter-dev/jumpstarter/releases/download/v0.8.1/operator-installer.yaml
Wait for the operator deployment:
$ kubectl wait --namespace jumpstarter-operator-system \
--for=condition=available deployment/jumpstarter-operator-controller-manager \
--timeout=120s
Create a namespace for Jumpstarter¶
$ kubectl create namespace jumpstarter-lab
Create a Jumpstarter custom resource¶
The operator reconciles the Jumpstarter CR and creates Deployments, Services, and networking resources (Ingresses or Routes) for controller/router/login endpoints.
apiVersion: operator.jumpstarter.dev/v1alpha1
kind: Jumpstarter
metadata:
name: jumpstarter
namespace: jumpstarter-lab
spec:
baseDomain: jumpstarter.example.com
certManager:
enabled: true
controller:
image: quay.io/jumpstarter-dev/jumpstarter-controller:0.8.1-rc.2
imagePullPolicy: IfNotPresent
replicas: 1
grpc:
endpoints:
- address: grpc.jumpstarter.example.com:443
ingress:
enabled: true
class: nginx
login:
endpoints:
- address: login.jumpstarter.example.com:443
ingress:
enabled: true
class: nginx
routers:
image: quay.io/jumpstarter-dev/jumpstarter-controller:0.8.1-rc.2
imagePullPolicy: IfNotPresent
replicas: 1
grpc:
endpoints:
- address: router.jumpstarter.example.com:443
ingress:
enabled: true
class: nginx
apiVersion: operator.jumpstarter.dev/v1alpha1
kind: Jumpstarter
metadata:
name: jumpstarter
namespace: jumpstarter-lab
spec:
baseDomain: jumpstarter.example.com
certManager:
enabled: true
controller:
image: quay.io/jumpstarter-dev/jumpstarter-controller:0.8.1-rc.2
imagePullPolicy: IfNotPresent
replicas: 1
grpc:
endpoints:
- address: grpc.jumpstarter.example.com:443
route:
enabled: true
login:
endpoints:
- address: login.jumpstarter.example.com:443
route:
enabled: true
routers:
image: quay.io/jumpstarter-dev/jumpstarter-controller:0.8.1-rc.2
imagePullPolicy: IfNotPresent
replicas: 1
grpc:
endpoints:
- address: router.jumpstarter.example.com:443
route:
enabled: true
Save as jumpstarter.yaml, then apply:
$ kubectl apply -f jumpstarter.yaml
Verify deployment¶
Check CR status and workloads:
$ kubectl get jumpstarter -n jumpstarter-lab
$ kubectl get deploy,svc,ingress -n jumpstarter-lab # Kubernetes
$ kubectl get deploy,svc,route -n jumpstarter-lab # OpenShift/OKD
Note
route is only available on OpenShift/OKD. On vanilla Kubernetes, use ingress.
Note
For OpenShift/OKD, set spec.baseDomain to a domain that resolves to your route hosts (for example, jumpstarter.example.com). Ensure DNS is configured so these route hostnames resolve correctly.
OAuth and cert-manager integration notes¶
OAuth / OIDC integration: Configure this through
spec.authentication.jwtin theJumpstarterCR (issuer URL, audiences, and claim mappings). The operator applies this configuration to controller runtime settings, but does not install or configure your identity provider.cert-manager integration: Set
spec.certManager.enabled: trueto let the operator manage server certificates. You can use operator-managed self-signed certificates or reference an existingIssuer/ClusterIssuerwithspec.certManager.server.issuerRef. Installing and configuring cert-manager itself remains an external prerequisite.
For detailed authentication examples and field-level reference, see Authentication.
cert-manager configuration examples¶
These examples are aligned with scenarios covered by the operator e2e tests in controller/deploy/operator/test/e2e/e2e_test.go.
Self-signed cert-manager mode¶
apiVersion: operator.jumpstarter.dev/v1alpha1
kind: Jumpstarter
metadata:
name: jumpstarter
namespace: jumpstarter-lab
spec:
baseDomain: jumpstarter.example.com
certManager:
enabled: true
server:
selfSigned:
enabled: true
controller:
grpc:
endpoints:
- address: grpc.jumpstarter.example.com:443
ingress:
enabled: true
class: nginx
routers:
grpc:
endpoints:
- address: router.jumpstarter.example.com:443
ingress:
enabled: true
class: nginx
The operator creates and uses:
<name>-selfsigned-issuer<name>-ca<name>-ca-issuer<name>-controller-tls<name>-router-<replica>-tls
External issuer reference (ClusterIssuer)¶
apiVersion: operator.jumpstarter.dev/v1alpha1
kind: Jumpstarter
metadata:
name: jumpstarter
namespace: jumpstarter-lab
spec:
baseDomain: jumpstarter.example.com
certManager:
enabled: true
server:
issuerRef:
name: my-cluster-issuer
kind: ClusterIssuer
controller:
grpc:
endpoints:
- address: grpc.jumpstarter.example.com:443
route:
enabled: true
routers:
grpc:
endpoints:
- address: router.jumpstarter.example.com:443
route:
enabled: true
In this mode, the operator issues certificates with your referenced issuer and does not create the self-signed issuer chain.
Login endpoint with cert-manager default TLS secret naming¶
When cert-manager is enabled and controller.login.tls.secretName is not set, the generated login Ingress uses the default TLS secret name login-tls.
For Ingress-based login endpoints, you can use controller.login.endpoints[].ingress.annotations to integrate with ACME issuers (for example Let’s Encrypt) managed by cert-manager.
apiVersion: operator.jumpstarter.dev/v1alpha1
kind: Jumpstarter
metadata:
name: jumpstarter
namespace: jumpstarter-lab
spec:
baseDomain: jumpstarter.example.com
certManager:
enabled: true
server:
selfSigned:
enabled: true
controller:
login:
endpoints:
- address: login.jumpstarter.example.com:443
ingress:
enabled: true
class: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
Login endpoint with explicit TLS secret¶
If you want a specific login certificate secret, set controller.login.tls.secretName:
apiVersion: operator.jumpstarter.dev/v1alpha1
kind: Jumpstarter
metadata:
name: jumpstarter
namespace: jumpstarter-lab
spec:
baseDomain: jumpstarter.example.com
certManager:
enabled: true
server:
selfSigned:
enabled: true
controller:
login:
tls:
secretName: login-custom-tls
endpoints:
- address: login.jumpstarter.example.com:443
ingress:
enabled: true
class: nginx
Operator behavior insights¶
From the current operator implementation in controller/deploy/operator, these behaviors are useful to know when authoring manifests:
If
spec.baseDomainis empty and the cluster exposes OpenShift Route APIs, the operator auto-detects the cluster domain and setsspec.baseDomaintojumpstarter.<namespace>.<cluster-domain>.If an endpoint has no enabled service type, the operator auto-selects one in this order:
route(if available), theningress, thenclusterIP.gRPC endpoints (
controller.grpc,routers.grpc) use TLS passthrough semantics in generated Ingress/Route resources; login endpoints use edge TLS termination.Controller and router auth secrets are created once with fixed names (
jumpstarter-controller-secret,jumpstarter-router-secret) and are intentionally not owner-referenced, so they persist across CR deletion/recreation.Router replicas are implemented as one Deployment per replica, and
$(replica)placeholders in endpoint addresses are substituted per replica.When router NodePort is enabled for multiple replicas, the operator offsets NodePort by replica index for router services.
Even when cert-manager is disabled, the operator still creates
jumpstarter-service-ca-cert(with emptyca.crt) for CLI discoverability.Status conditions are populated on the
Jumpstarterresource and include deployment readiness plus cert-manager/certificate readiness when cert-manager is enabled.
Jumpstarter API field reference¶
The Jumpstarter CRD is operator.jumpstarter.dev/v1alpha1.
Top-level spec fields¶
Field |
Type |
Description |
|---|---|---|
|
|
Base DNS domain for generated endpoint hostnames (for example |
|
|
Certificate management settings for controller/router/login TLS integration. |
|
|
Controller deployment, endpoint, and runtime settings. |
|
|
Router deployment scale, resources, topology, and endpoint settings. |
|
|
Internal, Kubernetes token, JWT, and auto-provisioning authentication settings. |
Controller and router fields¶
Field |
Type |
Description |
|---|---|---|
|
|
Controller container image. |
|
|
Pull policy ( |
|
|
Controller resource requests/limits. |
|
|
Number of controller pods. |
|
|
Timeout before exporter is considered offline. |
|
|
Manual TLS secret name for controller gRPC when cert-manager is disabled. |
|
|
Controller gRPC endpoint definitions (address + exposure method). |
|
|
gRPC keepalive tuning options. |
|
|
Optional TLS secret used by login edge-termination ingress/route. |
|
|
Login endpoint definitions (address + exposure method). |
|
|
Router container image. |
|
|
Pull policy ( |
|
|
Router resource requests/limits. |
|
|
Router replica count (operator creates one deployment per replica). |
|
|
Pod spread constraints for router deployments. |
|
|
Manual TLS secret name for router gRPC when cert-manager is disabled. |
|
|
Router endpoint definitions; supports |
|
|
Router gRPC keepalive tuning options. |
Authentication fields¶
Field |
Type |
Description |
|---|---|---|
|
|
Enables internal token-based auth. |
|
|
Username/subject prefix for internal auth. |
|
|
Internal token validity period. |
|
|
Enables Kubernetes service account token auth. |
|
|
JWT authenticators (issuer, audiences, claim mappings). |
|
|
Auto-create users authenticated by external providers. |
cert-manager fields¶
Field |
Type |
Description |
|---|---|---|
|
|
Enables operator cert-manager integration. |
|
|
Enables operator-managed self-signed CA mode. |
|
|
Self-signed CA certificate duration. |
|
|
Issued server certificate duration. |
|
|
Renewal lead time before expiration. |
|
|
Existing Issuer/ClusterIssuer name. |
|
|
|
|
|
Issuer API group (default |
|
|
Optional PEM CA bundle published for clients. |
Endpoint schema (used in gRPC/login endpoint arrays)¶
Field |
Type |
Description |
|---|---|---|
|
|
Host/address, optional port, supports |
|
|
Create OpenShift Route for endpoint. |
|
|
Route metadata overrides. |
|
|
Create Kubernetes Ingress for endpoint. |
|
|
Ingress class name. |
|
|
Ingress metadata overrides. |
|
|
Create NodePort service for endpoint. |
|
|
Requested NodePort value. |
|
|
NodePort service metadata overrides. |
|
|
Create LoadBalancer service for endpoint. |
|
|
Service port for LoadBalancer exposure. |
|
|
LoadBalancer service metadata overrides. |
|
|
Create ClusterIP service for endpoint. |
|
|
ClusterIP service metadata overrides. |
Status conditions¶
Condition type |
Meaning |
|---|---|
|
Overall operator-managed deployment readiness. |
|
Controller deployment is available. |
|
All router deployments are available. |
|
cert-manager CRDs are present (when enabled). |
|
Configured issuer is ready (when enabled). |
|
Controller TLS secret is ready (when enabled). |
|
Router TLS secrets are ready for all replicas (when enabled). |