mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-03 10:37:21 +09:00
## What this PR does Replace the ephemeral `emptyDisk` volume on tenant Kubernetes worker VMs with persistent PVC-backed storage via KubeVirt `dataVolumeTemplates`. Previously, kubelet certificates, kubeconfig, and containerd state were lost on VM reboot, causing the node to fall out of the tenant cluster. **Changes:** - Rename `ephemeralStorage` field to `diskSize` in NodeGroup configuration - Replace `emptyDisk` volume with `dataVolumeTemplates` using CDI blank source - Add `cdi.kubevirt.io/storage.usePopulator: "false"` annotation to work around CDI volume population issues with LINSTOR CSI - Add optional per-nodeGroup `storageClass` field (defaults to cluster default) - Set fixed 2Gi ephemeral-storage resource for virt-launcher pod - Rename internal mount paths from `/ephemeral` to `/persistent` - Add helm unit tests (`cluster_test.yaml`) covering dataVolumeTemplates defaults, custom disk size, storageClass presence/absence, fixed ephemeral-storage, disk name consistency, and CDI populator annotation - Quote storage values in templates (`diskSize`, `storageClassName`) for Helm correctness - Guard bind-mount commands with `mountpoint -q` checks and create target directories to handle fresh images and cloud-init retries - Set `blockSize.matchVolume` on worker node disks for automatic block size detection, fixing DRBD 4Kn compatibility with QEMU **Known gotchas:** - CDI volume population (prime PVC rebind) causes `ClaimMisbound` errors with LINSTOR CSI driver, regardless of StorageClass (`replicated` or `local`). The `usePopulator: false` annotation switches to the legacy import path which works correctly. This is a known CDI issue documented in [kubevirt/containerized-data-importer#3146](https://github.com/kubevirt/containerized-data-importer/issues/3146). - The `replicated` StorageClass with DRBD `suspend-io` quorum policy can cause transient VM IO errors during LINSTOR satellite restarts (quorum loss). The `local` StorageClass is recommended for worker node disks. When `storageClass` is not specified in a nodeGroup, the cluster default StorageClass is used. - Existing clusters will trigger a rolling replacement of all worker nodes on upgrade due to changed KubevirtMachineTemplate hash. - DRBD volumes use 4096-byte logical sectors (`block-size 4096`). Without explicit block size configuration, QEMU defaults to 512-byte sectors, causing immediate IO errors and VM pause. The `blockSize.matchVolume` setting in the disk spec ensures KubeVirt auto-detects the correct sector size from the volume. **Tested on a live cluster:** - Verified DataVolume provisioning with `local` StorageClass - Verified nodes join the tenant cluster and reach Ready state - Verified node survives VM reboot (pod deletion) and returns to Ready with the same Node object, reusing kubelet certificates from persistent disk ### Screenshots N/A — no UI changes. ### Release note ```release-note feat(kubernetes)!: replace ephemeral emptyDisk with persistent storage for worker nodes Worker node VMs now use persistent PVC-backed disks instead of ephemeral emptyDisk volumes. Kubelet certificates, kubeconfig, and containerd state survive VM reboots, preventing nodes from falling out of the tenant cluster. BREAKING CHANGE: The `ephemeralStorage` field in nodeGroups has been renamed to `diskSize`. A new optional `storageClass` field allows per-nodeGroup storage class selection. Users must update their values overrides accordingly. Worker node disks now use `blockSize.matchVolume` to automatically detect the underlying volume's sector size, ensuring compatibility with DRBD-backed storage classes that use 4096-byte logical sectors. ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Optional storageClass parameter to select storage class for worker node persistent disks (defaults to cluster default). * Makefile test target added to run Helm unit tests for the chart. * **Configuration Changes** * Worker node storage parameter renamed from ephemeralStorage to diskSize (default: 20Gi). * Kubelet/containerd state moved to persistent disk paths and node ephemeral-storage accounting fixed to 2Gi; disk provisioning aligns block sizing with backing volumes. * **Documentation** * Updated docs and chart/schema to reflect the persistent disk model and new fields. <!-- end of auto-generated comment: release notes by coderabbit.ai -->