0.4.0: csi external-snapshotter v8.1.0 (Phase 3a — VolumeSnapshot CRDs + controller)

This commit is contained in:
OdooSky Bot
2026-05-02 22:01:26 +03:00
parent cf0fd4c477
commit 8fca9aadfa
3 changed files with 326 additions and 2 deletions

View File

@@ -23,8 +23,8 @@ description: |
Git). Git).
type: application type: application
version: 0.3.3 version: 0.4.0
appVersion: "0.3.3" appVersion: "0.4.0"
dependencies: dependencies:
- name: cert-manager - name: cert-manager

View File

@@ -0,0 +1,313 @@
{{- /*
csi-snapshotter — vendored from kubernetes-csi/external-snapshotter
v8.1.0. Required by Longhorn's CSI VolumeSnapshot path (Phase 3 of
ADR 0003). Longhorn ships csi-snapshotter SIDECARS but does not ship
the snapshot-controller + standard snapshot.storage.k8s.io CRDs —
those are decoupled from any specific CSI driver.
Tower's spawn-env / Refresh ↓ uses the standard CSI VolumeSnapshot
API (`snapshot.storage.k8s.io/v1`) so the orchestration code is
portable across CSI drivers. Without these CRDs + controller, the
VolumeSnapshot kind doesn't exist and every snapshot-based op fails.
Source manifests:
https://github.com/kubernetes-csi/external-snapshotter/tree/v8.1.0
Pin: v8.1.0 (current upstream stable as of 2026-05).
Why one big template instead of `crds/`: Argo doesn't process Helm's
`crds/` directory — only `templates/`. So CRDs land here, with
`helm.sh/hook: crd-install` annotations to make the ordering safe
on first install (CRDs apply before any CR that references them).
Toggle: `.Values.csiSnapshotter.enabled` (default true). Disable
only on clusters where the snapshotter is provisioned out-of-band.
*/ -}}
{{- if .Values.csiSnapshotter.enabled }}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: volumesnapshotclasses.snapshot.storage.k8s.io
annotations:
argocd.argoproj.io/sync-options: ServerSideApply=true
spec:
group: snapshot.storage.k8s.io
names:
kind: VolumeSnapshotClass
listKind: VolumeSnapshotClassList
plural: volumesnapshotclasses
shortNames: [vsclass, vsclasses]
singular: volumesnapshotclass
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .driver
name: Driver
type: string
- description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted.
jsonPath: .deletionPolicy
name: DeletionPolicy
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1
schema:
openAPIV3Schema:
description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot.
properties:
apiVersion:
type: string
deletionPolicy:
description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Required.
enum: [Delete, Retain]
type: string
driver:
description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required.
type: string
kind:
type: string
metadata:
type: object
parameters:
additionalProperties:
type: string
description: parameters is a key-value map with storage driver specific parameters for creating snapshots.
type: object
required: [deletionPolicy, driver]
type: object
served: true
storage: true
subresources: {}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: volumesnapshotcontents.snapshot.storage.k8s.io
annotations:
argocd.argoproj.io/sync-options: ServerSideApply=true
spec:
group: snapshot.storage.k8s.io
names:
kind: VolumeSnapshotContent
listKind: VolumeSnapshotContentList
plural: volumesnapshotcontents
shortNames: [vsc, vscs]
singular: volumesnapshotcontent
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .status.readyToUse
name: ReadyToUse
type: boolean
- jsonPath: .status.restoreSize
name: RestoreSize
type: integer
- jsonPath: .spec.deletionPolicy
name: DeletionPolicy
type: string
- jsonPath: .spec.driver
name: Driver
type: string
- jsonPath: .spec.volumeSnapshotClassName
name: VolumeSnapshotClass
type: string
- jsonPath: .spec.volumeSnapshotRef.name
name: VolumeSnapshot
type: string
- jsonPath: .spec.volumeSnapshotRef.namespace
name: VolumeSnapshotNamespace
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1
schema:
openAPIV3Schema:
description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system
type: object
x-kubernetes-preserve-unknown-fields: true
served: true
storage: true
subresources:
status: {}
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: volumesnapshots.snapshot.storage.k8s.io
annotations:
argocd.argoproj.io/sync-options: ServerSideApply=true
spec:
group: snapshot.storage.k8s.io
names:
kind: VolumeSnapshot
listKind: VolumeSnapshotList
plural: volumesnapshots
shortNames: [vs]
singular: volumesnapshot
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Indicates if the snapshot is ready to be used to restore a volume.
jsonPath: .status.readyToUse
name: ReadyToUse
type: boolean
- description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created.
jsonPath: .spec.source.persistentVolumeClaimName
name: SourcePVC
type: string
- description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object.
jsonPath: .spec.source.volumeSnapshotContentName
name: SourceSnapshotContent
type: string
- description: Represents the minimum size of volume required to rehydrate from this snapshot.
jsonPath: .status.restoreSize
name: RestoreSize
type: string
- description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot.
jsonPath: .spec.volumeSnapshotClassName
name: SnapshotClass
type: string
- description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to.
jsonPath: .status.boundVolumeSnapshotContentName
name: SnapshotContent
type: string
- description: Timestamp when the point-in-time snapshot was taken by the underlying storage system.
jsonPath: .status.creationTime
name: CreationTime
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1
schema:
openAPIV3Schema:
description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot.
type: object
x-kubernetes-preserve-unknown-fields: true
served: true
storage: true
subresources:
status: {}
---
# RBAC + controller deployment for the snapshot-controller. Lives
# in kube-system per upstream convention. The controller watches
# VolumeSnapshot CRs and orchestrates the CSI driver-side snapshot
# (in our case Longhorn's csi-snapshotter sidecar does the actual
# work; this controller bridges the standard CRD <-> CSI calls).
apiVersion: v1
kind: ServiceAccount
metadata:
name: snapshot-controller
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: snapshot-controller-runner
rules:
- apiGroups: [""]
resources: [persistentvolumes]
verbs: [get, list, watch]
- apiGroups: [""]
resources: [persistentvolumeclaims]
verbs: [get, list, watch, update]
- apiGroups: [storage.k8s.io]
resources: [storageclasses]
verbs: [get, list, watch]
- apiGroups: [""]
resources: [events]
verbs: [list, watch, create, update, patch]
- apiGroups: [snapshot.storage.k8s.io]
resources: [volumesnapshotclasses]
verbs: [get, list, watch]
- apiGroups: [snapshot.storage.k8s.io]
resources: [volumesnapshotcontents]
verbs: [create, get, list, watch, update, delete, patch]
- apiGroups: [snapshot.storage.k8s.io]
resources: [volumesnapshotcontents/status]
verbs: [patch]
- apiGroups: [snapshot.storage.k8s.io]
resources: [volumesnapshots]
verbs: [get, list, watch, update, patch, delete]
- apiGroups: [snapshot.storage.k8s.io]
resources: [volumesnapshots/status]
verbs: [update, patch]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: snapshot-controller-role
subjects:
- kind: ServiceAccount
name: snapshot-controller
namespace: kube-system
roleRef:
kind: ClusterRole
name: snapshot-controller-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kube-system
name: snapshot-controller-leaderelection
rules:
- apiGroups: [coordination.k8s.io]
resources: [leases]
verbs: [get, watch, list, delete, update, create]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: snapshot-controller-leaderelection
namespace: kube-system
subjects:
- kind: ServiceAccount
name: snapshot-controller
namespace: kube-system
roleRef:
kind: Role
name: snapshot-controller-leaderelection
apiGroup: rbac.authorization.k8s.io
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: snapshot-controller
namespace: kube-system
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: snapshot-controller
template:
metadata:
labels:
app.kubernetes.io/name: snapshot-controller
spec:
serviceAccountName: snapshot-controller
containers:
- name: snapshot-controller
image: registry.k8s.io/sig-storage/snapshot-controller:v8.1.0
args:
- --v=5
- --leader-election=true
- --retry-crd-interval-max=30s
imagePullPolicy: IfNotPresent
{{- end }}
{{- if and .Values.longhorn.enabled .Values.csiSnapshotter.enabled }}
---
# VolumeSnapshotClass for Tower's CSI VolumeClone path. type=snap
# is Longhorn's in-place CoW snapshot (fast, local). type=bak
# is the slower S3-bound block backup, used by Phase 5 only.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: longhorn-snapshot-class
driver: driver.longhorn.io
deletionPolicy: Delete
parameters:
type: snap
{{- end }}

View File

@@ -130,6 +130,17 @@ registry:
# VolumeClone Refresh ↓ path # VolumeClone Refresh ↓ path
# Existing instances on `local-path` are unaffected — Longhorn # Existing instances on `local-path` are unaffected — Longhorn
# co-exists, doesn't replace local-path. # co-exists, doesn't replace local-path.
# csiSnapshotter — vendored kubernetes-csi/external-snapshotter
# v8.1.0. Provides the standard `snapshot.storage.k8s.io/v1` CRDs
# + snapshot-controller. Required for Tower's CSI VolumeClone path
# (Refresh ↓ + spawn-env seed). See ADR 0003 phase 3.
#
# Only needed when Longhorn (or any other snapshot-capable CSI
# driver) is in use; default true so future server connects get the
# substrate ready out of the box.
csiSnapshotter:
enabled: true
longhorn: longhorn:
enabled: false enabled: false
# Replicas per Longhorn volume. Standard tier (single server) = # Replicas per Longhorn volume. Standard tier (single server) =