Licensed to be used in conjunction with basebox, only.
// installation
Kubernetes
Applies to
Product: Server · Audience: Platform Operator
Cluster requirements for basebox, ingress controller, CloudNativePG and the differences between single-node and CPU/GPU-node layouts. At the end of this step your cluster offers everything the basebox umbrella chart requires.
Official documentation: Kubernetes with kubeadm · Calico · CloudNativePG · ingress-nginx
What the chart requires
| Requirement | Value |
|---|---|
| Kubernetes | 1.23+ (verified: 1.33.7; 1.33+ recommended) |
| Helm | 3.x (verified: 3.20.0) |
| Ingress controller | Any; the chart ships nginx annotations |
| Storage | Dynamic volume provisioning with a default storage class |
| Databases | CloudNativePG operator in the cluster |
| GPU | NVIDIA GPU Operator (or equivalent) on GPU nodes – see NVIDIA / GPU |
| Registry | Pull access to gitea.basebox.health from the nodes' runtime |
1. Install Kubernetes (kubeadm)
The verified path with kubeadm, containerd and Calico is under Server Preparation Guide → Step 7 with all commands. The order:
- Add the Kubernetes repository (1.33), install
kubelet kubeadm kubectland pin them withapt-mark hold. - Disable swap; set kernel modules
overlay,br_netfilterand the sysctl parameters for bridge netfilter and IP forwarding. - Configure containerd before running
kubeadm init– the default configuration has the CRI plugin disabled: sudo kubeadm init --pod-network-cidr=10.244.0.0/16, then set up kubeconfig for your user.- Network plugin:
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.31.3/manifests/calico.yaml - Check:
kubectl get nodesshows the nodeReady.
Alternative distributions such as k3s work; note the DNS problem with systemd-resolved there – solution in the FAQ.
2. Single node or several nodes
Single node (the reference configurations): control plane and workloads on the same machine. The control-plane taint prevents pods from being scheduled by default. Two paths:
- Tolerations in the values of the components that need them (GPU Operator; see its values file in the Server Preparation Guide) – the clean path for production.
- Remove the taint – for development/test only:
CPU and GPU nodes: the basebox platform runs on CPU nodes, service models and inference on GPU nodes. Label nodes (nvidia.com/gpu: "true", possibly gpu-type) and use nodeSelector/tolerations in the values of the GPU services – examples on the Inference Server and Ragsrv pages. The GPU Operator only needs to work on the GPU nodes.
Separate clusters for platform and inference: Deployment topologies.
3. Ingress controller
The chart configures ingress resources with nginx annotations: 20 MB body for uploads, large buffers for JWT headers, 24-hour timeouts for WebSocket and streaming, buffering off, CORS, cache control. Install ingress-nginx (or a controller that understands these annotations) and note the ingress class (nginx) and the external IP:
The annotations in detail: Helm chart overview → Ingress configuration.
4. Storage class
basebox needs dynamic volume provisioning for the PostgreSQL clusters, media and model caches. For evaluation a local storage class suffices (local-path, default in the quick start); for production a storage class on SSD/NVMe with snapshots or replication. Set it as default or name it in the values (storageClass). Capacity planning: Storage.
5. CloudNativePG operator
Every basebox service with a database (AISRV, storesrv, ragsrv, Keycloak) gets its own PostgreSQL cluster, managed by CloudNativePG:
helm repo add cnpg https://cloudnative-pg.github.io/charts
helm upgrade --install cnpg \
--namespace cnpg-system \
--create-namespace \
cnpg/cloudnative-pg
kubectl get pods -n cnpg-system
The umbrella chart also contains the operator as a dependency (cnpg-operator.fullnameOverride: cnpg); install it only once – either beforehand as here or via the chart.
6. cert-manager (optional)
For public domains with automatic certificates: install cert-manager and create a ClusterIssuer (e.g. letsencrypt-prod). Not needed with an internal CA or for evaluation – see Networking.
7. Verify
kubectl get nodes -o wide
kubectl get pods -A
kubectl get storageclass
kubectl get svc -A | grep -i ingress
kubectl get pods -n cnpg-system
kubectl get pods -n gpu-operator # on GPU nodes
kubectl describe nodes | grep -A5 "Allocated resources"
Everything Ready/Running, a default storage class, an ingress IP, GPU resources on the GPU nodes – then the cluster is ready.
Common failure patterns
| Symptom | Cause | Solution |
|---|---|---|
kubeadm init: "unknown service runtime.v1.RuntimeService" |
containerd CRI disabled | Step 1.3, then kubeadm reset and init again |
Pods Pending |
Control-plane taint, no storage class, no GPU | Tolerations; kubectl get pvc; check GPU Operator |
inference/ragsrv-support: "Temporary error in name resolution" |
k3s with systemd-resolved | Point coredns at an external DNS (FAQ) |
| Image pull fails on nodes | Registry access of the runtime | Test the pull from the runtime, not just from the workstation |
Next step: Storage