Beta This is a new service — your feedback will help us to improve it.

kubectl mode

Kubectl mode gives org owners and admins a kubeconfig for that org's Kubernetes namespace. It is not cluster-admin access. The credential is bound to a Role for common app resources such as Deployments, Services, ConfigMaps, app Secrets, and PersistentVolumeClaims.

Access control

Org owners enable kubectl mode from the dashboard. Only owners and admins can download or refresh kubectl credentials (TOTP required). Org members can view the kubectl page for reference information such as reserved IPv6 addresses, but cannot issue credentials.

A kubectl credential grants namespace-wide control within your org's namespace: exec into any pod, create and delete workloads and secrets, and consume shared quota. It is not limited to resources you created yourself.

Before you start

You need:

Enable kubectl mode

Open the control panel dashboard. In Deploy modes, org owners can click Enable kubectl. After it is enabled, org owners and admins can open kubectl mode and download their own kubeconfig.

Run a smoke test with the downloaded file:

KUBECONFIG=./dollarbox-your-org.kubeconfig kubectl get pods

Keep the kubeconfig private. If it is exposed, use Refresh credentials on the kubectl page. Refreshing credentials revokes existing kubeconfigs for that user immediately and downloads a replacement.

Capacity model

Capacity follows the same billing model as simple mode. Each subscribed dollarbox adds:

ResourceAdded capacity
App pods1
Memory1Gi
CPU request100m
CPU limit1000m
Ephemeral storage quota10Gi
IPv6 LoadBalancer services1

Manage subscribed dollarboxes from Billing in the control panel. Capacity cannot be lowered below containers or kubectl workloads that still exist. Failed control-panel containers reserve capacity until you delete them.

Guardrails

Your kubeconfig is namespace-scoped. DollarBox also enforces admission and namespace policy:

Networking between workloads

Pods in your namespace can reach each other directly over the network. Run a multi-component stack (for example a web app talking to postgres and redis) by exposing internal dependencies as ClusterIP Services and connecting over in-cluster DNS — no LoadBalancer is needed for internal hops.

apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  type: ClusterIP
  selector:
    app: postgres
  ports:
    - port: 5432
      targetPort: 5432

Your web pods then connect to postgres:5432 inside the namespace. Only the services you expose as an IPv6 LoadBalancer are reachable from outside, so keep internal dependencies on ClusterIP.

Cross-org isolation is unchanged: pods cannot receive traffic from other orgs' namespaces, and egress to other tenants' pod or service networks stays blocked. The network policies that enforce this are platform-managed (labelled dollarbox.io/managed-by=control-panel) — you cannot create or edit NetworkPolicies from kubectl.

DollarBox opens external ingress automatically, but only to your LoadBalancer Services and only on their target ports. When you apply a LoadBalancer Service, the platform reconciles a matching ingress policy (named allow-lb-<service>) within a few minutes — there is no cluster-admin step. ClusterIP Services (databases, caches, internal APIs) are never exposed externally; they stay reachable only inside your namespace.

Reserved IPv6 addresses

Each subscribed dollarbox reserves one IPv6 address per node for your org. These addresses are sticky: they stay yours across restarts, deletes, recreates, and node failover, and are never handed to another customer while you hold the matching capacity.

A LoadBalancer Service must request one of your reserved addresses with the metallb.io/loadBalancerIPs annotation. A Service with no address — or an address outside your reservation — is rejected by admission control (tenant pools do not auto-assign).

See your reserved addresses two ways:

KUBECONFIG=./dollarbox-your-org.kubeconfig \
  kubectl get configmap container-reserved-ipv6 -o jsonpath='{.data.addresses}'

Minimal deployment example

This example runs nginx and exposes it on an IPv6 LoadBalancer. It consumes one pod and one LoadBalancer from your paid capacity.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: web
          image: nginx:1.25-alpine
          ports:
            - containerPort: 80
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: ["ALL"]
---
apiVersion: v1
kind: Service
metadata:
  name: web
  annotations:
    # One of your reserved addresses — see "Reserved IPv6 addresses" on the
    # kubectl page, or the container-reserved-ipv6 ConfigMap.
    metallb.io/loadBalancerIPs: <one-of-your-reserved-addresses>
spec:
  type: LoadBalancer
  ipFamilies: [IPv6]
  ipFamilyPolicy: SingleStack
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80

Apply it:

KUBECONFIG=./dollarbox-your-org.kubeconfig kubectl apply -f web.yaml

Check the assigned IPv6 address:

KUBECONFIG=./dollarbox-your-org.kubeconfig kubectl get svc web

Working with control-panel containers

Simple-mode containers and kubectl workloads share the same namespace and quota. Do not try to edit control-panel resources with kubectl. Use the control panel to edit or restart those containers.

If kubectl-created workloads exhaust quota, later control-panel deploys can fail until you delete resources or increase subscribed capacity.