Add Worker Nodes
You can scale the cluster by joining worker nodes to the NuFi master node. The procedure below assumes an airgapped environment.
Prerequisites
| Item | Requirement |
|---|---|
| OS | Ubuntu 22.04+ (same architecture as the master) |
| CPU | 4 cores or more |
| RAM | 16 GB or more |
| Disk | 100 GB or more |
| GPU (optional) | NVIDIA driver pre-installed |
Network Requirements
| Direction | Port | Protocol | Purpose |
|---|---|---|---|
| Worker → Master | 6443 | TCP | K3s API |
| Worker → Master | 8472 | UDP | Flannel VXLAN |
Worker Bundle
The files required to join a worker are included in the worker-bundle directory provided by the NuFi vendor.
worker-bundle/
├── join-worker.sh # Join script
├── k3s # k3s binary
├── k3s.tar.zst # Airgap container images
├── nvidia-container-toolkit/ # NVIDIA CTK (optional)
└── docs/
└── worker-join-guide.md
Get the Token
On the master node, retrieve the join token.
Request
sudo cat /var/lib/rancher/k3s/server/node-token
Response
K10abcdef1234567890abcdef1234567890abcdef1234567890::server:abcdef1234567890
The node-token grants permission for a worker node to join. Take care not to expose it externally.
Run the Join
On the worker node, move into the bundle directory and run the script.
cd worker-bundle
sudo ./join-worker.sh <masterIP> <token>
| Argument | Description | Example |
|---|---|---|
masterIP | IP address of the master node | 192.168.10.1 |
token | The full node-token value retrieved above | K10abc...::server:abc... |
Example run:
sudo ./join-worker.sh 192.168.10.1 \
K10abcdef1234567890abcdef1234567890abcdef1234567890::server:abcdef1234567890
Execution Stages
The script automatically performs the following stages.
[1/6] Verify required files
[2/6] System configuration (swap off, sysctl, NVIDIA CTK)
[3/6] Install k3s binary
[4/6] Stage airgap images
[5/6] Register k3s-agent service
[6/6] Wait for join completion
If an NVIDIA GPU is detected, the containerd nvidia runtime is configured automatically.
Verify the Join
On the master node, list the nodes.
Request
kubectl get nodes
Response
NAME STATUS ROLES AGE VERSION
master-01 Ready control-plane,master 3d v1.34.3+k3s1
worker-01 Ready <none> 30s v1.34.3+k3s1
When the new worker node appears as Ready, the join is complete.
Airgap image import and CNI initialization can take about 30–90 seconds. If the node is not yet Ready, wait about 2 minutes and check again.
Troubleshooting
Check Logs
# Service status
sudo systemctl status k3s-agent
# Live log
sudo journalctl -u k3s-agent -f
# Last 100 lines
sudo journalctl -u k3s-agent -n 100
Common Errors
| Symptom | Cause | Resolution |
|---|---|---|
401 or Failed to get node-ca-hash | Token typo or whitespace included | Copy the token again and pass it without surrounding whitespace |
dial tcp :6443: connect: timeout | Firewall is blocking 6443 | Allow worker → master TCP 6443 |
Repeated flannel ... no route | Firewall is blocking UDP 8472 | Allow worker → master UDP 8472 |
certificate not yet valid | Worker node clock is out of sync | Sync time with sudo date -s "YYYY-MM-DD HH:MM:SS" |
Node doesn't show up in kubectl get nodes | Airgap image missing or architecture mismatch | Check image import via journalctl -u k3s-agent |
Cancel and Retry the Join
To start the join from scratch, run the following on the worker.
sudo systemctl stop k3s-agent
sudo systemctl disable k3s-agent
sudo rm -f /etc/systemd/system/k3s-agent.service
sudo rm -f /etc/systemd/system/k3s-agent.service.env
sudo rm -rf /var/lib/rancher/k3s /etc/rancher/k3s
sudo systemctl daemon-reload
If the node still appears in the list on the master, remove it.
kubectl delete node <worker-node-name>
Then proceed again from Run the Join.