|
| 1 | +--- |
| 2 | +title: "Automatic Volume Placement" |
| 3 | +description: "Reference for the PVC annotations and StorageCluster fields that control which storage node becomes a new volume's primary node." |
| 4 | +weight: 40050 |
| 5 | +--- |
| 6 | + |
| 7 | +A new volume's primary storage node is resolved from up to three PVC annotations, evaluated in a |
| 8 | +fixed order. If none apply, the storage cluster's built-in default placement is used. |
| 9 | + |
| 10 | +## Resolution Order |
| 11 | + |
| 12 | +| Order | Annotation | Set by | |
| 13 | +|-------|---------------------------------------------------|------------------------| |
| 14 | +| 1 | `simplyblock.io/selected-storage-node` | User | |
| 15 | +| 2 | `simplyblock.io/placement-hint` | Operator (automatic) | |
| 16 | +| 3 | `simplyblock.io/pod-affinity: "true"` (opt-in only) | User | |
| 17 | +| — | *(none of the above)* | Storage cluster default placement | |
| 18 | + |
| 19 | +## Annotations |
| 20 | + |
| 21 | +| Annotation | Type | Default | Description | |
| 22 | +|--------------------------------------------|-----------------------------|---------|----------------------------------------------------------------------------------------------------------------------------| |
| 23 | +| `simplyblock.io/selected-storage-node` | string (storage node UUID) | — | Pins the volume to a specific storage node. On a new PVC, sets the primary node directly. On a bound PVC, triggers a live migration to the new node. | |
| 24 | +| `simplyblock.io/host-id` | string (storage node UUID) | — | Deprecated alias for `selected-storage-node`. Normalized into it automatically on admission. | |
| 25 | +| `simplybk/host-id` | string (storage node UUID) | — | Deprecated legacy prefix for `host-id`. Normalized the same way. | |
| 26 | +| `simplyblock.io/placement-hint` | string (storage node UUID) | — | Written automatically by the operator when load-aware placement selects a node for a new volume. Not user-set, and does not pin the volume. | |
| 27 | +| `simplyblock.io/pod-affinity` | boolean | `false` | Opts a PVC into co-location with its consuming Pod's resolved node. Requires a `WaitForFirstConsumer` StorageClass. | |
| 28 | +| `simplyblock.io/disable-smart-placement` | boolean | `false` | Disables load-aware placement for this PVC. Does not affect an explicit pin or `pod-affinity` co-location (those are already opt-in per PVC and need no separate opt-out). | |
| 29 | + |
| 30 | +### `simplyblock.io/selected-storage-node` |
| 31 | + |
| 32 | +```bash title="Pin a new PVC to a specific storage node" |
| 33 | +kubectl annotate pvc my-pvc -n simplyblock \ |
| 34 | + simplyblock.io/selected-storage-node=4e53efdd-86c9-424f-940c-e437eb6a2e95 |
| 35 | +``` |
| 36 | + |
| 37 | +The value must be a known storage node UUID, found with `{{ cliname }} storage-node list --cluster-id=<CLUSTER_ID>`. |
| 38 | +Otherwise, the PVC is rejected by a validating webhook. On an already-bound PVC, a |
| 39 | +[migration](../operations/volume-migration.md#migrating-by-pinning-a-pvc) to the new node is triggered by |
| 40 | +this annotation instead. |
| 41 | + |
| 42 | +### `simplyblock.io/pod-affinity` |
| 43 | + |
| 44 | +```yaml title="Co-locate a new volume with its consuming Pod" |
| 45 | +kind: PersistentVolumeClaim |
| 46 | +apiVersion: v1 |
| 47 | +metadata: |
| 48 | + name: my-pvc |
| 49 | + annotations: |
| 50 | + simplyblock.io/pod-affinity: "true" |
| 51 | +spec: |
| 52 | + accessModes: |
| 53 | + - ReadWriteOnce |
| 54 | + resources: |
| 55 | + requests: |
| 56 | + storage: 10Gi |
| 57 | + storageClassName: simplyblock-csi-sc |
| 58 | +``` |
| 59 | +
|
| 60 | +| Requirement | Detail | |
| 61 | +|------------------------------------------------|---------------------------------------------------------------------------------------------| |
| 62 | +| StorageClass binding mode | `WaitForFirstConsumer` (see [Defining a StorageClass](storage-class.md)) | |
| 63 | +| Supported scheduling mechanisms | `nodeSelector`, node affinity, pod affinity | |
| 64 | +| Not supported | `spec.nodeName` set directly on the Pod ([kubernetes/kubernetes#89953](https://github.com/kubernetes/kubernetes/issues/89953){:target="_blank" rel="noopener"}) | |
| 65 | +| Multiple co-located storage nodes on one worker | One is selected at random | |
| 66 | +| Precedence | Only applies when the volume is not already pinned or covered by a placement hint | |
| 67 | + |
| 68 | +### `simplyblock.io/disable-smart-placement` |
| 69 | + |
| 70 | +```bash title="Exclude a single PVC from automatic placement" |
| 71 | +kubectl annotate pvc my-pvc -n simplyblock \ |
| 72 | + simplyblock.io/disable-smart-placement=true |
| 73 | +``` |
| 74 | + |
| 75 | +Suppresses load-aware placement for this PVC, regardless of cluster-wide configuration. Placement then falls |
| 76 | +through to whatever is next in the [resolution order](#resolution-order): an explicit pin, `pod-affinity` |
| 77 | +co-location if the PVC also requests it, or the storage cluster's default placement. |
| 78 | + |
| 79 | +## Load-Aware Placement |
| 80 | + |
| 81 | +Load-aware placement for new volumes is controlled by the same `StorageCluster` field that also feeds |
| 82 | +[auto-rebalancing's latency benchmark](../operations/volume-migration.md#auto-rebalancing): |
| 83 | + |
| 84 | +| Field | Type | Default | Description | |
| 85 | +|------------------------------------------------|--------|---------|------------------------------------------------------------------------------------------------------------| |
| 86 | +| `volumeAutoPlacement.latencyBenchmarkEnabled` | bool | `false` | Enables load-aware placement for new volumes, independent of `volumeAutoPlacement.enabled` (continuous rebalancer only). | |
| 87 | + |
| 88 | +```yaml title="Enabling load-aware placement for new volumes" |
| 89 | +spec: |
| 90 | + volumeAutoPlacement: |
| 91 | + latencyBenchmarkEnabled: true |
| 92 | + prometheusURL: "http://prometheus.simplyblock.svc:9090" |
| 93 | +``` |
| 94 | + |
| 95 | +A node is eligible when it is online, passes its health check, and is below its configured logical volume |
| 96 | +limit. |
| 97 | + |
| 98 | +## Clones and Snapshot Restores |
| 99 | + |
| 100 | +None of the above applies to a PVC created from a `VolumeSnapshot` or another PVC (`dataSource`). A clone |
| 101 | +or restore always uses its source volume's node. |
0 commit comments