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
27 changes: 27 additions & 0 deletions api/v1alpha1/vinylcache_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ type VinylCacheSpec struct {
// +optional
Pod PodSpec `json:"pod,omitempty"`

// volumeClaimTemplates are appended verbatim to the generated StatefulSet's
// spec.volumeClaimTemplates. Each template yields one PVC per replica
// (named <claim>-<statefulset>-<ord>) that persists across pod restarts
// for that replica. Useful for per-replica SSD-backed file storage.
// Reference the claim name from spec.pod.volumeMounts; reference the
// resulting mountPath from spec.storage[].path.
// +optional
VolumeClaimTemplates []corev1.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"`

// monitoring configures Prometheus metrics and alerting rules.
// +optional
Monitoring MonitoringSpec `json:"monitoring,omitempty"`
Expand Down Expand Up @@ -520,6 +529,24 @@ type PodSpec struct {
// priorityClassName is the name of the PriorityClass for Varnish pods.
// +optional
PriorityClass string `json:"priorityClassName,omitempty"`

// volumes are additional pod-level volumes appended to the operator-managed
// defaults (agent-token, varnish-secret, varnish-workdir, varnish-tmp,
// bootstrap-vcl). Use to back spec.storage[].path with a PVC, an EmptyDir
// with sizeLimit, or any VolumeSource supported by Kubernetes. Reserved
// names collide with operator-managed volumes and are rejected by the
// admission webhook. Volume names must also be unique across volumes and
// volumeClaimTemplates.
// +optional
Volumes []corev1.Volume `json:"volumes,omitempty"`

// volumeMounts are additional mounts appended to the varnish container.
// Each entry must reference a name present in spec.pod.volumes or
// spec.volumeClaimTemplates. Reserved mount paths (/run/vinyl,
// /etc/varnish/secret, /var/lib/varnish, /tmp, /etc/varnish/default.vcl)
// are rejected by the admission webhook.
// +optional
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
}

// MonitoringSpec configures Prometheus monitoring for the Varnish cluster.
Expand Down
21 changes: 21 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2,395 changes: 2,395 additions & 0 deletions charts/cloud-vinyl/crds/vinylcache.yaml

Large diffs are not rendered by default.

2,395 changes: 2,395 additions & 0 deletions config/crd/bases/vinyl.bluedynamics.eu_vinylcaches.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/sources/how-to/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Step-by-step guides for common tasks with cloud-vinyl.

install
create-cache
ssd-backed-storage
per-backend-directors
purge-ban
upgrade
Expand Down
100 changes: 100 additions & 0 deletions docs/sources/how-to/ssd-backed-storage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Back spec.storage[].type=file with a user-provisioned volume

By default, `spec.storage[].type=file` lands the cache spill file in the operator's `/var/lib/varnish` EmptyDir. That works for small working sets on nodes with SSD-backed ephemeral storage, but has limits: no persistence across pod restart, no `sizeLimit`, no choice of StorageClass, no isolation from node ephemeral use (logs, image layers).

This guide shows how to back the spill file with (1) an EmptyDir with an explicit size limit, or (2) a StorageClass-provisioned PVC per pod.

## Option 1 — EmptyDir with sizeLimit (simplest)

Useful when you want to cap cache disk use and isolate it from node ephemeral capacity, without per-pod persistence.

```yaml
apiVersion: vinyl.bluedynamics.eu/v1alpha1
kind: VinylCache
metadata:
name: my-cache
spec:
replicas: 2
image: varnish:7.6
backends:
- name: app
serviceRef:
name: app-service
port: 8080
storage:
- name: mem
type: malloc
size: 1Gi
- name: disk
type: file
path: /var/lib/varnish-cache/spill.bin
size: 50Gi
pod:
volumes:
- name: cache-scratch
emptyDir:
sizeLimit: 60Gi
volumeMounts:
- name: cache-scratch
mountPath: /var/lib/varnish-cache
```

The file lives on node ephemeral storage, but capped at 60 GiB regardless of how much the node has.

## Option 2 — PVC per pod via `volumeClaimTemplates`

Useful for persistence across pod restarts (faster warmup after a roll), or for isolating cache I/O onto a dedicated SSD StorageClass (`hcloud-volumes`, `gp3`, a CSI-driver-provisioned NVMe, etc.):

```yaml
apiVersion: vinyl.bluedynamics.eu/v1alpha1
kind: VinylCache
metadata:
name: my-cache
spec:
replicas: 2
image: varnish:7.6
backends:
- name: app
serviceRef:
name: app-service
port: 8080
storage:
- name: mem
type: malloc
size: 1Gi
- name: disk
type: file
path: /var/lib/varnish-cache/spill.bin
size: 80Gi
volumeClaimTemplates:
- metadata:
name: cache-ssd
spec:
accessModes: [ReadWriteOnce]
storageClassName: hcloud-volumes
resources:
requests:
storage: 100Gi
pod:
volumeMounts:
- name: cache-ssd
mountPath: /var/lib/varnish-cache
```

The StatefulSet creates one PVC per replica — `cache-ssd-my-cache-0`, `cache-ssd-my-cache-1`, etc. They persist across pod deletion (StatefulSet semantics) so a rolling restart doesn't throw away the warmed cache.

Make sure `spec.storage[].size` is well under the PVC size (Varnish needs filesystem overhead — allow ~20%).

## Reserved names and paths

These names cannot be used for your volumes (they collide with operator-managed volumes):

- `agent-token`, `varnish-secret`, `varnish-workdir`, `varnish-tmp`, `bootstrap-vcl`

These mount paths are reserved by the operator:

- `/run/vinyl`, `/etc/varnish/secret`, `/etc/varnish/default.vcl`, `/var/lib/varnish`, `/tmp`

`spec.storage[].path` cannot live under a reserved mount — you must declare your own `pod.volumeMounts` entry that covers the path.

The admission webhook rejects violations with a clear message.
8 changes: 6 additions & 2 deletions docs/sources/reference/vinylcache-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
| `proxyProtocol.port` | integer | no | PROXY protocol port (default: `8081` when enabled). |
| `service.annotations` | object | no | Annotations on the traffic Service. |
| `pod.labels` | object | no | Extra labels on Vinyl Cache pods. |
| `pod.volumes` | list | no | Additional pod volumes appended to operator-managed defaults. Reserved names rejected by webhook. See [SSD-backed storage how-to](../how-to/ssd-backed-storage.md). |
| `pod.volumeMounts` | list | no | Additional mounts on the varnish container. Each `name` must reference a `spec.pod.volumes` entry or a `spec.volumeClaimTemplates` claim name. Reserved mount paths rejected by webhook. |
| `volumeClaimTemplates` | list | no | StatefulSet-native per-replica PVC templates. Reference the claim `name` from `spec.pod.volumeMounts`. |

### backends

Expand Down Expand Up @@ -130,9 +133,10 @@ spec:
replicas: 3
backends:
- name: api
host: api-service.production.svc.cluster.local
serviceRef:
name: api-service
port: 8080
healthCheck:
probe:
url: /healthz
interval: 5s
threshold: 3
Expand Down
Loading
Loading