Parallel Storage Node Addition
When a deployment document creates storage nodes on several workers, the Simplyblock Operator can add them concurrently rather than one after another. This significantly reduces the provisioning time of large deployments and expansions.
A node addition reboots its host, so the concurrency is capped by a node-provisioning budget. Workers that host a FoundationDB pod are always added one at a time, regardless of the budget, so that the control plane's own datastore keeps enough coordinators to remain available.
Configuring the Budget
The budget is spec.storageNodes.nodeProvisioningBudget of the StorageCluster. A deployment document sets it for a
new cluster with spec.cluster.nodeProvisioningBudget.
| Value | Behavior |
|---|---|
1 (default) |
Workers are added one at a time, which is safe for all topologies. |
n > 1 |
Up to n workers are in the node-add process at the same time. |
apiVersion: storage.simplyblock.io/v1alpha2
kind: ClusterDeploymentConfig
metadata:
name: simplyblock-deployment
namespace: simplyblock
spec:
approved: false
cluster:
name: simplyblock-cluster
maxSubsystemCount: 50
vcpuCount: 8
nodeProvisioningBudget: 4
nodeSets:
- name: rack-a
groups:
- name: default
workers:
- worker-1
- worker-2
- worker-3
- worker-4
- worker-5
- worker-6
- worker-7
- worker-8
devices:
nvme: ["0000:01:00.0"]
kubectl patch storagecluster simplyblock-cluster -n simplyblock --type=merge \
-p '{"spec": {"storageNodes": {"nodeProvisioningBudget": 4}}}'
The budget counts workers, not storage nodes. A worker with two NUMA sockets, or with several nodes per socket, is added with one request and consumes one slot.
How Slots Are Taken
A new storage node walks its provisioning steps CheckingHost, CheckingConfig, AwaitingSlot, Posting, and
Resolving. In AwaitingSlot, it waits until it can take a slot of the budget, and it holds the slot from the moment
its node addition is posted until it has received a backend UUID or its addition has given up. The slot stays taken
while the worker reboots.
The slots in use are recorded in StorageCluster.status.provisioningSlots, each with the worker it was taken for,
the node that took it, and the time takenAt.
kubectl get storagecluster simplyblock-cluster -n simplyblock \
-o jsonpath='{range .status.provisioningSlots[*]}{.worker}{"\t"}{.node}{"\t"}{.takenAt}{"\n"}{end}'
A node that waits for a slot emits an AwaitingSlot event, which names how many slots are in flight and which
workers hold them. Waiting workers go first in the order of their names, so a worker that is told to wait is not
overtaken by one that arrived later. AwaitingSlot has a deadline of four hours.
kubectl get events -n simplyblock \
--field-selector reason=AwaitingSlot
FoundationDB Workers
A worker counts as a FoundationDB worker when it runs a pod labeled foundationdb.org/fdb-cluster-name. Such a worker
waits, with an AwaitingSlot event, while any other FoundationDB worker is being added, even when the budget has free
slots. Rebooting several FoundationDB hosts at once would reduce the number of available coordinators below the quorum
and make the control plane unavailable.
Note
The FoundationDB rule is independent of the budget. On a cluster where FoundationDB runs on every worker, the additions are sequential whatever the budget says.
Pinning FoundationDB to Dedicated Workers
For the parallelism to be most effective, FoundationDB runs on a dedicated subset of workers rather than on all of
them. The node selector of the control plane, ControlPlane.spec.source.local.nodeSelector, also applies to the
FoundationDB pods. The Helm chart renders it from controlplane.nodeSelector, so the dedicated workers are labeled
before the installation.
kubectl label node worker-1 worker-2 worker-4 simplyblock-control-plane=true
helm install simplyblock-operator simplyblock/simplyblock-operator \
-n simplyblock --create-namespace \
--set controlplane.nodeSelector.create=true \
--set controlplane.nodeSelector.key=simplyblock-control-plane \
--set controlplane.nodeSelector.value=true
With this setup, only the labeled workers host FoundationDB and are added one at a time. All remaining workers are added in parallel within the budget. The installation itself is described in Install the Control Plane.
Verifying the Parallelism
kubectl get storagenodes -n simplyblock -w
While the additions run, up to the budget of workers show the step Posting or Resolving at the same time, and the
others show AwaitingSlot. The control plane integrates an expansion of an active cluster one node at a time
regardless of the budget, as described in Expanding a Storage Cluster.