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:
- Billing set up for the org.
- Paid capacity for the workloads you plan to run.
kubectlinstalled locally.- Org owner access if kubectl mode has not been enabled yet.
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:
| Resource | Added capacity |
|---|---|
| App pods | 1 |
| Memory | 1Gi |
| CPU request | 100m |
| CPU limit | 1000m |
| Ephemeral storage quota | 10Gi |
| IPv6 LoadBalancer services | 1 |
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:
- Control-panel resources are labelled
dollarbox.io/managed-by=control-paneland are read-only from kubectl. - Services must be
ClusterIPor IPv6-onlyLoadBalancer. NodePort,ExternalName, host-network pods, node selectors, and unapproved storage classes are rejected. PersistentVolumeClaims must uselocal-path(ephemeral) orlonghorn(persistent, pre-paid pool) and must requestReadWriteOnce.- Pods run under Kubernetes PodSecurity
restricted. - Namespace quota limits pods, memory, CPU, storage, services, secrets, and configmaps.
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:
- Control panel — the kubectl page has a Reserved IPv6 addresses card listing each address, its node, and whether it is in use.
- kubectl — DollarBox keeps a read-only
container-reserved-ipv6ConfigMap in your namespace up to date with your allocation:
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.