VinylCache Spec Reference#
VinylCache is the central custom resource managed by cloud-vinyl.
API group: vinyl.bluedynamics.eu/v1alpha1
Kind: VinylCache
Scope: Namespaced
Spec fields#
Top-level#
Field |
Type |
Required |
Description |
|---|---|---|---|
|
integer |
yes |
Number of Vinyl Cache pods in the StatefulSet. |
|
list |
yes |
One or more backend services. |
|
object |
no |
Director configuration (defaults: |
|
object |
no |
Clustering / peer-routing configuration. |
|
object |
no |
Runtime parameters passed to |
|
object |
no |
Edge Side Includes (ESI) processing. See the |
|
object |
no |
Cache invalidation configuration. |
|
duration |
no |
Wait after last change before VCL push (default: |
|
integer |
no |
Maximum VCL push retry attempts (default: |
|
duration |
no |
Initial retry backoff (default: |
|
duration |
no |
Maximum retry backoff (default: |
|
boolean |
no |
Enable PROXY protocol v2 on port 8081. |
|
integer |
no |
PROXY protocol port (default: |
|
object |
no |
Annotations on the traffic Service. |
|
object |
no |
Extra labels on Vinyl Cache pods. |
|
list |
no |
Additional pod volumes appended to operator-managed defaults. Reserved names rejected by webhook. See SSD-backed storage how-to. |
|
list |
no |
Additional mounts on the varnish container. Each |
|
list |
no |
StatefulSet-native per-replica PVC templates. Reference the claim |
backends#
Each entry in spec.backends defines an upstream service:
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
yes |
Unique backend identifier (used in VCL). |
|
string |
yes |
Kubernetes Service name in the same namespace. |
|
integer |
no |
Overrides the Service port; defaults to the Service’s first port. |
|
duration |
no |
Connection timeout (default: |
|
duration |
no |
Time-to-first-byte timeout (default: |
|
duration |
no |
Between-bytes timeout (default: |
|
integer |
no |
Maximum concurrent connections to this backend. |
|
string |
no |
Health probe URL (e.g. |
|
duration |
no |
Health probe interval (default: |
|
duration |
no |
Health probe timeout (default: |
|
integer |
no |
Consecutive successes required to mark healthy. |
|
integer |
no |
Rolling window for health evaluation. |
backends[].director#
Per-backend director override. If unset, the generator emits a shard director with default parameters, grouping all resolved per-pod backends for this serviceRef.
Field |
Type |
Required |
Description |
|---|---|---|---|
|
enum |
no |
One of |
|
float |
no |
|
|
duration |
no |
Ramp-up window after adding a backend. Default |
|
enum |
no |
|
|
enum |
no |
|
|
string |
no |
Header used as hash key for the |
See the per-backend directors how-to for when to override each type.
director#
Field |
Type |
Default |
Description |
|---|---|---|---|
|
string |
|
Director type. Currently only |
|
float |
|
Fraction of requests sent to alternate backend to pre-populate its cache. |
|
duration |
|
Traffic throttle duration for newly healthy backends. |
|
string |
|
Shard key source. |
|
string |
|
Health evaluation strategy ( |
Note on
shard.byandshard.healthy:
Cluster-peer director (when
cluster.enabled: true): honored automatically — the operator emits<director>.backend(by=<by>, healthy=<healthy>)invcl_recv.Per-backend directors: still request-time arguments. The CRD accepts the fields but you must use them in your own VCL snippet, e.g.
set req.backend_hint = plone.backend(by=URL, healthy=CHOSEN);.
cluster#
Field |
Type |
Default |
Description |
|---|---|---|---|
|
boolean |
|
Enable cluster peer routing between pods. |
|
string |
|
Director type for peer-to-peer routing. |
varnishParameters#
A map[string]string. Each entry becomes one -p flag on varnishd: the key
must be a bare varnishd parameter name (lowercase letters, digits, and
underscores, starting with a letter — the admission webhook rejects anything
else, including padding whitespace or uppercase), and the value is passed
through unchanged. For example:
varnishParameters:
thread_pool_min: "100"
thread_pool_max: "1000"
feature: "+esi_disable_xml_check"
renders as -p feature=+esi_disable_xml_check -p thread_pool_max=1000 -p thread_pool_min=100
on the varnish container — note the args come out sorted by key (feature <
thread_pool_max < thread_pool_min), not in the order they were written in
YAML, so the pod template does not churn between reconciles for the same
params.
Two parameters are blocked by the admission webhook regardless of value,
because they allow arbitrary code execution at VCL-compile time:
vcc_allow_inline_c and cc_command.
ESI (Edge Side Includes) processing is not controlled through this map —
see the esi section below. varnishParameters’ feature key is still relevant
alongside it, for the one real varnishd feature bit ESI sometimes needs
(esi_disable_xml_check); see that section for when and why.
esi#
Field |
Type |
Default |
Description |
|---|---|---|---|
|
boolean |
|
Enable Edge Side Includes (ESI) processing. |
esi:
enabled: true
Setting esi.enabled: true makes the generated VCL set beresp.do_esi = true
whenever a backend response carries Surrogate-Control: content="ESI/1.0".
ESI is core varnishd functionality, not a VMOD, and — unlike most varnishd
behaviour toggles — it is not controlled by any varnishParameters/-p feature=... flag either: real varnishd has no esi feature bit, so passing
{"feature": "+esi"} (an earlier, now-removed convention) crashes varnishd
outright with Unknown feature bit (+esi) rather than enabling anything.
esi.enabled replaces that convention and carries no such risk — it never
reaches varnishd’s argv at all.
If response bodies don’t reliably start with < (varnishd’s ESI
implementation sniffs the body to decide whether to scan it for <esi:...>
tags), also set the real varnishd feature token alongside it:
esi:
enabled: true
varnishParameters:
feature: "+esi_disable_xml_check"
invalidation#
Field |
Type |
Default |
Description |
|---|---|---|---|
|
boolean |
|
Use soft purge (stale-while-revalidate). |
|
list |
|
CIDRs permitted to send |
|
object |
nil |
Xkey (surrogate key) configuration. When set, |
|
boolean |
|
Use soft purge for xkey invalidation. |
|
boolean |
|
When |
|
list |
|
CIDRs permitted to send |
|
integer |
|
Inert in v0.4.2 — field is accepted but not enforced; rate-limiting is tracked as follow-up work. |
Note on BAN security: any client whose source IP is in
vinyl_ban_allowedcan invalidate the entire cache with an arbitrary ban expression. Scopeban.allowedSourcestightly to trusted callers only. Ban expressions should preferobj.http.x-url/obj.http.x-hostoverreq.*fields — only the former can be processed by the ban lurker, soreq.*bans accumulate without being compacted.Clients send BAN requests like:
curl -X BAN -H 'X-Vinyl-Ban: obj.http.x-url ~ "^/news/"' http://varnish.svc/
Status fields#
Field |
Type |
Description |
|---|---|---|
|
string |
|
|
string |
|
|
string |
SHA-256 hash of the currently active VCL. |
|
list |
Standard Kubernetes conditions ( |
Example#
apiVersion: vinyl.bluedynamics.eu/v1alpha1
kind: VinylCache
metadata:
name: my-cache
namespace: production
spec:
replicas: 3
backends:
- name: api
serviceRef:
name: api-service
port: 8080
probe:
url: /healthz
interval: 5s
threshold: 3
director:
type: shard
shard:
warmup: 0.1
rampup: 30s
cluster:
enabled: true
invalidation:
purge:
soft: true
xkey:
softPurge: true
debounce:
duration: 1s
retry:
maxAttempts: 3
backoffBase: 5s
backoffMax: 5m