gameplane / docs
PLATFORM

Cluster nodes, kubeconfig, and join tokens

Read node health and capacity, protect administrative access, and add workers only when cluster operations are enabled.

Cluster & Storagev0.214 MIN
Kubeconfig and node-join tokens are administrative credentials

Treat kubeconfig files and bootstrap tokens as secrets: keep them out of tickets, chat, logs, and shell history. Downloaded kubeconfigs expire after 1 hour and are bound to a read-only role, but the underlying cluster API access must still be guarded.

Releases up to and including v0.3.0 are published under ghcr.io/valgulnecron, so this page uses that registry; releases after v0.3.0 move to ghcr.io/gameplanepanel.

Read cluster and node health

Confirm distribution, version, ready count, roles, pressure, uptime, pod capacity, CPU, and memory before changing infrastructure.

Treat NotReady and pressure as Kubernetes-level triage.A node reporting NotReady or memory/disk pressure needs investigation before accepting new workloads. Use kubectl to inspect node status and events.
Compare allocatable capacity with GameServer requests.Node capacity is the sum of all requests and limits across your GameServers. If requested capacity exceeds available nodes, new servers will remain Pending.
Preserve headroom for control plane, ingress, agents, and backup jobs.Leave 10–20% of cluster capacity free for system workloads and operational overhead. Game server requests should target 70–80% of total capacity.

View node details via kubectl

The Gameplane dashboard’s Cluster page displays node names, roles, status (Ready/NotReady), CPU/memory allocatable capacity, and current usage (if metrics-server is installed). For deeper inspection:

# View all nodes with status
kubectl get nodes -o wide

# Inspect a single node (status, conditions, capacity, allocatable, labels, taints)
kubectl describe node <node-name>

# Check node metrics (requires metrics-server)
kubectl top nodes
kubectl top nodes <node-name>

Download and protect kubeconfig

The download action requires clusterOps.enabled in your Helm values and the downloader to hold the admin role. The generated file is a short-lived credential bound to read-only access.

Verify context before use and start with read-only commands.Test the kubeconfig by running `kubectl --kubeconfig=gameplane-kubeconfig.yaml auth can-i get nodes --list` to confirm read-only access. Never use `--as=system:masters` or attempt privilege escalation.
Store with restrictive permissions; never attach to support tickets.Save kubeconfigs with `chmod 600`. If you must share cluster diagnostics, extract only the necessary logs or metrics—never the kubeconfig itself.
Record recipients and revoke underlying access when no longer needed.The downloaded kubeconfig expires after 1 hour automatically. If you distribute it, track who received it and consider rotating access if the credential is leaked.

Enable cluster operations

To unlock kubeconfig download and node-join actions, set clusterOps.enabled in your Helm values and reinstall:

# charts/gameplane/values.yaml (or helm upgrade --set)
clusterOps:
  enabled: true
  # Optional: external API server address for off-cluster access
  # Omit to use the in-cluster API server address (unreachable from outside)
  # externalAddress: "k8s.example.com:6443"

Then redeploy:

helm upgrade gameplane oci://ghcr.io/valgulnecron/charts/gameplane \
  --version 0.2.0-beta.8 \
  --set clusterOps.enabled=true

When clusterOps.enabled=false (the default), the Cluster page disables both buttons with a hint.

Add a node

Mint a short-lived token for the intended cluster, run the generated join procedure, then verify readiness and allocatable capacity.

Workflow

  1. Click “Add node” in the Cluster page’s actions menu.
  2. The API generates a 24-hour bootstrap token and returns the complete kubeadm join command.
  3. Copy the command and run it on the new node (must have kubeadm, kubelet, and a matching Kubernetes version):
    kubeadm join api.k8s.example.com:6443 --token <id>.<secret> \
      --discovery-token-ca-cert-hash sha256:<hex>
  4. Wait 30–60 seconds for the node to register and become Ready.
  5. Verify:
    kubectl get nodes
    kubectl top node <new-node-name>
  6. Label or taint the node if needed (e.g., for game server affinity or isolation):
    kubectl label node <new-node-name> game-server=true
    kubectl taint node <new-node-name> dedicated=gameservers:NoSchedule
  7. Deploy a test GameServer to confirm scheduling and capacity.

Join token lifecycle

  • Lifetime: 24 hours from creation.
  • Single-use: The token expires automatically after use; no revocation needed.
  • Per-cluster: Each bootstrap token is tied to the cluster the API server was reached from. Multi-cluster installs require generating a token for each control plane. Node-join token creation and kubeconfig issuance are local-cluster operations and are unavailable while viewing a remote cluster; remote node inventory instead needs the read permissions listed in the remote agent gateway guide.
  • CA cert hash: The discovery token CA cert hash (--discovery-token-ca-cert-hash) pins the cluster’s root CA and prevents man-in-the-middle attacks. It is always required.

Troubleshooting join failures

  • “No ClusterCIDR configured” — typically a Kubernetes configuration issue, not Gameplane-specific. Check your cluster’s pod CIDR configuration.
  • “Kubelet not ready” — the kubelet may take 1–2 minutes to initialize. Wait and retry kubectl get nodes.
  • “TLS handshake timeout” — the new node cannot reach the API server. Verify network connectivity and firewall rules.
  • “Token already used” — bootstrap tokens are one-time; generate a new token if the join fails.

CLUSTER OPS

01   01 Read version, Ready, roles, pressure, pods, CPU, memory
02   02 Kubeconfig requires clusterOps.enabled; handle as admin secret
03   03 Join token → Ready + labels/taints/capacity + test workload