Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions docs/kubernetes/operations/security/authentication-encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,44 @@ When connecting a volume with host access control enabled, the `--host-nqn` flag
{{ cliname }} volume connect <VOLUME_ID> --host-nqn <HOST_NQN>
```

## Configuring DHCHAP via the StoragePool CRD

On Kubernetes deployments managed by the Simplyblock Operator, DHCHAP and host access control are configured
declaratively on the `StoragePool` custom resource instead of through `{{ cliname }}`.

```yaml title="Example of a StoragePool with DHCHAP enabled for two worker nodes"
apiVersion: storage.simplyblock.io/v1alpha1
kind: StoragePool
metadata:
name: pool-a
namespace: simplyblock
spec:
clusterName: cluster-a
dhchap: true
allowedNodes:
- worker-1
- worker-2
```

The keys are generated as soon as `dhchap` is set, but authentication is only enforced once `allowedNodes` is
non-empty. Everything the flow above does by hand is then reconciled by the operator:

- Each node in `allowedNodes` is registered as an allowed host of the pool, under a deterministic NQN derived
from that node's Kubernetes UID (`nqn.2014-08.io.simplyblock:uuid:<node-uid>`).
- Each allowed node is labeled `simplyblock.io/pool.<namespace>.<cluster>.<pool>: allowed`, and the generated
`StorageClass` is restricted to that label through `allowedTopologies`. The first `Pod` to consume a
`PersistentVolumeClaim` of this pool can therefore only be scheduled onto an allowed node.
- The same label is written into the `nodeAffinity` of the `PersistentVolume` when the volume is created, which
restricts every later scheduling decision on the already-bound volume.
- The node's own NQN and the pool's DHCHAP secrets are presented by the CSI node plugin on connect, so no
`--host-nqn` has to be supplied anywhere in the Kubernetes flow.

`dhchap` is immutable, because the `parameters` and `allowedTopologies` of the generated `StorageClass` cannot
be patched in the Kubernetes API once it exists. `allowedNodes` stays mutable. Changing it relabels the nodes
and updates the pool's allowed hosts, and it never rewrites the `StorageClass`.

See the [Operator Reference](../../../reference/operator/reference.md) for the full `StoragePool` field list,
and [Storage Class](../../usage/storage-class.md) for the `dhchap_node_label` parameter this generates.

For a detailed explanation of the security mechanisms and configuration, see
[NVMe-oF Security](../../../architecture/concepts/nvmf-security.md).
39 changes: 20 additions & 19 deletions docs/kubernetes/usage/storage-class.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,23 @@ If `namespace-volumes` is set to `yes`, the number of namespaces per subsystem h

## Available Parameters

| Parameter Name | Value Type | Description | Optional | Default |
|---------------------------|------------|-------------------------------------------------------------------------------------------------------------------------------------|----------|----------|
| cluster_id | string | Defines the backing cluster id for the storage class. Required unless `zone_cluster_map` or `region_cluster_map` is used. | true | |
| zone_cluster_map | string | JSON map of Kubernetes zone to simplyblock cluster id (for topology-aware multi-cluster provisioning). | true | |
| region_cluster_map | string | JSON map of Kubernetes region to simplyblock cluster id (for topology-aware multi-cluster provisioning). | true | |
| fabric | string | Defines the fabric type to connect to the storage cluster. Valid values are `tcp` and `rdma`. | true | `tcp` |
| csi.storage.k8s.io/fstype | string | Defines the filesystem to format the logical volume. If not specific, a raw block device is given to the container. | true | |
| pool_name | string | Defines the simplyblock storage pool name to use. | false | testing1 |
| qos_rw_iops | int | Defines the maximum IOPS reserved for a logical volume of this storage class. A zero (0) means no maximum. | true | 0 |
| qos_rw_mbytes | int | Defines the maximum total throughput in megabytes reserved for a logical volume of this storage class. A zero (0) means no maximum. | true | 0 |
| qos_r_mbytes | int | Defines the maximum read throughput in megabytes reserved for a logical volume of this storage class. A zero (0) means no maximum. | true | 0 |
| qos_w_mbytes | int | Defines the maximum write throughput in megabytes reserved for a logical volume of this storage class. A zero (0) means no maximum. | true | 0 |
| compression | bool | Defines if the logical volume of this storage class will be stored compressed or not. | true | false |
| encryption | bool | Defines if the logical volume of this storage class will be encrypted or not. | true | false |
| distr_ndcs | int | Defines the number of data chunks for the erasure coding scheme. | true | 1 |
| distr_npcs | int | Defines the number of parity chunks for the erasure coding scheme. | true | 1 |
| lvol_priority_class | int | Defines the priority class of a logical volume of this storage class. | true | 0 |
| max_namespace_per_subsys | int | Defines the number of namespaces per NVMe subsystem. | true | 1 |
| tune2fs_reserved_blocks | int | Defines the number of reserved blocks for tune2fs operations. | true | 0 |
| Parameter Name | Value Type | Description | Optional | Default |
|---------------------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----------|
| cluster_id | string | Defines the backing cluster id for the storage class. Required unless `zone_cluster_map` or `region_cluster_map` is used. | true | |
| zone_cluster_map | string | JSON map of Kubernetes zone to simplyblock cluster id (for topology-aware multi-cluster provisioning). | true | |
| region_cluster_map | string | JSON map of Kubernetes region to simplyblock cluster id (for topology-aware multi-cluster provisioning). | true | |
| fabric | string | Defines the fabric type to connect to the storage cluster. Valid values are `tcp` and `rdma`. | true | `tcp` |
| csi.storage.k8s.io/fstype | string | Defines the filesystem to format the logical volume. If not specific, a raw block device is given to the container. | true | |
| pool_name | string | Defines the simplyblock storage pool name to use. | false | testing1 |
| qos_rw_iops | int | Defines the maximum IOPS reserved for a logical volume of this storage class. A zero (0) means no maximum. | true | 0 |
| qos_rw_mbytes | int | Defines the maximum total throughput in megabytes reserved for a logical volume of this storage class. A zero (0) means no maximum. | true | 0 |
| qos_r_mbytes | int | Defines the maximum read throughput in megabytes reserved for a logical volume of this storage class. A zero (0) means no maximum. | true | 0 |
| qos_w_mbytes | int | Defines the maximum write throughput in megabytes reserved for a logical volume of this storage class. A zero (0) means no maximum. | true | 0 |
| compression | bool | Defines if the logical volume of this storage class will be stored compressed or not. | true | false |
| encryption | bool | Defines if the logical volume of this storage class will be encrypted or not. | true | false |
| distr_ndcs | int | Defines the number of data chunks for the erasure coding scheme. | true | 1 |
| distr_npcs | int | Defines the number of parity chunks for the erasure coding scheme. | true | 1 |
| lvol_priority_class | int | Defines the priority class of a logical volume of this storage class. | true | 0 |
| max_namespace_per_subsys | int | Defines the number of namespaces per NVMe subsystem. | true | 1 |
| tune2fs_reserved_blocks | int | Defines the number of reserved blocks for tune2fs operations. | true | 0 |
| dhchap_node_label | string | Node label key carried by the allowed nodes of a DHCHAP pool, restricting volumes of this class to those nodes. Set by the operator from a `StoragePool`'s `dhchap` and `allowedNodes` fields. | true | |
Loading