Add shared arrstack Valkey and wire arr apps' Redis features (#394)
Activates the arr forks (sonarr/radarr/prowlarr) #14 Redis features — SignalR backplane, cross-replica cache-invalidation bus, and distributed rate limiter — which ship deployed but inert because no Valkey exists in arrstack and nothing is wired to it. Ben wants ONE Valkey shared by all three apps. ## Changes - Adds a single shared `ValkeyCluster` (`arrstack-valkey`) under `apps/base/arrstack/valkey/`, modeled on `jellyfin-valkey`: `shards:1`/`replicas:2` HA (one primary + two replicas, automatic failover), image via artifactapi (`artifactapi.k8s.syd1.au.unkin.net/dockerhub/valkey/valkey:9.0.0`), operator-default passwordless `default` user, node spread across hosts, cluster-aware PDB, ephemeral `/data`. - Registers the `valkey` component in the arrstack base kustomization. - Wires `<App>__Redis__Host` + `<App>__Redis__Port` into the `sonarr-env` / `radarr-env` / `prowlarr-env` ConfigMaps, all pointing at the shared service `valkey-arrstack-valkey.arrstack.svc.cluster.local:6379`. ## Notes - Setting `Host` is the activation switch: the fork's `RedisOptions.IsConfigured` gates purely on a non-empty `Host`, so there is no separate Enabled flag. - Passwordless (jellyfin parity — the operator leaves the `default` user without auth), so no `Password`/`Ssl` is wired and there is no secret to reference. - One cluster is safe for all three: each fork namespaces its keys and pub/sub channels by a per-app prefix (`sonarr:ratelimit:` / `radarr:ratelimit:` / `prowlarr:ratelimit:`), so their state never collides. - App `image:` (-unkin5), the waitfordb initContainer, and S3 buckets are untouched. - Validated: `kubectl kustomize` renders clean for both `apps/base/arrstack` and `apps/overlays/au-syd1/arrstack`. Follow-up: after merge, Valkey must come up and the three apps must roll (pick up the new env) before the #14 features can be validated live. --------- Co-authored-by: Ben Vincent <ben@unkin.net> Reviewed-on: #394 Co-authored-by: Unkin Agent <unkin-agent@unkin.net> Co-committed-by: Unkin Agent <unkin-agent@unkin.net>
This commit was merged in pull request #394.
This commit is contained in:
@@ -14,6 +14,7 @@ resources:
|
|||||||
- media-bucket.yaml
|
- media-bucket.yaml
|
||||||
- backups-bucket.yaml
|
- backups-bucket.yaml
|
||||||
- postgres
|
- postgres
|
||||||
|
- valkey
|
||||||
- sonarr
|
- sonarr
|
||||||
- radarr
|
- radarr
|
||||||
- prowlarr
|
- prowlarr
|
||||||
|
|||||||
@@ -22,3 +22,12 @@ data:
|
|||||||
Prowlarr__Server__Port: "9696"
|
Prowlarr__Server__Port: "9696"
|
||||||
Prowlarr__Server__UrlBase: /prowlarr
|
Prowlarr__Server__UrlBase: /prowlarr
|
||||||
Prowlarr__Update__Mechanism: External
|
Prowlarr__Update__Mechanism: External
|
||||||
|
# Shared arrstack Valkey (valkey-operator). Setting Host is what activates the
|
||||||
|
# fork's #14 Redis features (SignalR backplane, cross-replica cache-invalidation
|
||||||
|
# bus, distributed rate limiter): RedisOptions.IsConfigured gates purely on a
|
||||||
|
# non-empty Host, so there is no separate Enabled flag. The operator leaves the
|
||||||
|
# default user passwordless (jellyfin parity), so no Password/Ssl is wired.
|
||||||
|
# Channels/keys are namespaced by this fork's prowlarr:ratelimit: prefix, so the
|
||||||
|
# one cluster is safe to share with sonarr/radarr.
|
||||||
|
Prowlarr__Redis__Host: valkey-arrstack-valkey.arrstack.svc.cluster.local
|
||||||
|
Prowlarr__Redis__Port: "6379"
|
||||||
|
|||||||
@@ -4,6 +4,13 @@ kind: Deployment
|
|||||||
metadata:
|
metadata:
|
||||||
name: prowlarr
|
name: prowlarr
|
||||||
namespace: arrstack
|
namespace: arrstack
|
||||||
|
annotations:
|
||||||
|
# prowlarr-env is a plain (unhashed) ConfigMap consumed by fixed-name envFrom,
|
||||||
|
# so editing it does not roll the Deployment on its own. Reloader watches the
|
||||||
|
# referenced ConfigMap and triggers a rolling restart on change, so adding the
|
||||||
|
# Redis env activates the #14 features on the next ArgoCD sync without a manual
|
||||||
|
# `rollout restart`.
|
||||||
|
configmap.reloader.stakater.com/auto: "true"
|
||||||
spec:
|
spec:
|
||||||
# Active-active: the -unkin2 fork keeps all state in the shared Postgres
|
# Active-active: the -unkin2 fork keeps all state in the shared Postgres
|
||||||
# (arrstack-postgres) and coordinates via Postgres advisory locks, so N
|
# (arrstack-postgres) and coordinates via Postgres advisory locks, so N
|
||||||
|
|||||||
@@ -22,3 +22,12 @@ data:
|
|||||||
Radarr__Server__Port: "7878"
|
Radarr__Server__Port: "7878"
|
||||||
Radarr__Server__UrlBase: /radarr
|
Radarr__Server__UrlBase: /radarr
|
||||||
Radarr__Update__Mechanism: External
|
Radarr__Update__Mechanism: External
|
||||||
|
# Shared arrstack Valkey (valkey-operator). Setting Host is what activates the
|
||||||
|
# fork's #14 Redis features (SignalR backplane, cross-replica cache-invalidation
|
||||||
|
# bus, distributed rate limiter): RedisOptions.IsConfigured gates purely on a
|
||||||
|
# non-empty Host, so there is no separate Enabled flag. The operator leaves the
|
||||||
|
# default user passwordless (jellyfin parity), so no Password/Ssl is wired.
|
||||||
|
# Channels/keys are namespaced by this fork's radarr:ratelimit: prefix, so the
|
||||||
|
# one cluster is safe to share with sonarr/prowlarr.
|
||||||
|
Radarr__Redis__Host: valkey-arrstack-valkey.arrstack.svc.cluster.local
|
||||||
|
Radarr__Redis__Port: "6379"
|
||||||
|
|||||||
@@ -4,6 +4,13 @@ kind: Deployment
|
|||||||
metadata:
|
metadata:
|
||||||
name: radarr
|
name: radarr
|
||||||
namespace: arrstack
|
namespace: arrstack
|
||||||
|
annotations:
|
||||||
|
# radarr-env is a plain (unhashed) ConfigMap consumed by fixed-name envFrom,
|
||||||
|
# so editing it does not roll the Deployment on its own. Reloader watches the
|
||||||
|
# referenced ConfigMap and triggers a rolling restart on change, so adding the
|
||||||
|
# Redis env activates the #14 features on the next ArgoCD sync without a manual
|
||||||
|
# `rollout restart`.
|
||||||
|
configmap.reloader.stakater.com/auto: "true"
|
||||||
spec:
|
spec:
|
||||||
# Active-active: the -unkin2 fork keeps all state in the shared Postgres
|
# Active-active: the -unkin2 fork keeps all state in the shared Postgres
|
||||||
# (arrstack-postgres) and coordinates via Postgres advisory locks, so N
|
# (arrstack-postgres) and coordinates via Postgres advisory locks, so N
|
||||||
|
|||||||
@@ -22,3 +22,12 @@ data:
|
|||||||
Sonarr__Server__Port: "8989"
|
Sonarr__Server__Port: "8989"
|
||||||
Sonarr__Server__UrlBase: /sonarr
|
Sonarr__Server__UrlBase: /sonarr
|
||||||
Sonarr__Update__Mechanism: External
|
Sonarr__Update__Mechanism: External
|
||||||
|
# Shared arrstack Valkey (valkey-operator). Setting Host is what activates the
|
||||||
|
# fork's #14 Redis features (SignalR backplane, cross-replica cache-invalidation
|
||||||
|
# bus, distributed rate limiter): RedisOptions.IsConfigured gates purely on a
|
||||||
|
# non-empty Host, so there is no separate Enabled flag. The operator leaves the
|
||||||
|
# default user passwordless (jellyfin parity), so no Password/Ssl is wired.
|
||||||
|
# Channels/keys are namespaced by this fork's sonarr:ratelimit: prefix, so the
|
||||||
|
# one cluster is safe to share with radarr/prowlarr.
|
||||||
|
Sonarr__Redis__Host: valkey-arrstack-valkey.arrstack.svc.cluster.local
|
||||||
|
Sonarr__Redis__Port: "6379"
|
||||||
|
|||||||
@@ -4,6 +4,13 @@ kind: Deployment
|
|||||||
metadata:
|
metadata:
|
||||||
name: sonarr
|
name: sonarr
|
||||||
namespace: arrstack
|
namespace: arrstack
|
||||||
|
annotations:
|
||||||
|
# sonarr-env is a plain (unhashed) ConfigMap consumed by fixed-name envFrom,
|
||||||
|
# so editing it does not roll the Deployment on its own. Reloader watches the
|
||||||
|
# referenced ConfigMap and triggers a rolling restart on change, so adding the
|
||||||
|
# Redis env activates the #14 features on the next ArgoCD sync without a manual
|
||||||
|
# `rollout restart`.
|
||||||
|
configmap.reloader.stakater.com/auto: "true"
|
||||||
spec:
|
spec:
|
||||||
# Active-active: the -unkin2 fork keeps all state in the shared Postgres
|
# Active-active: the -unkin2 fork keeps all state in the shared Postgres
|
||||||
# (arrstack-postgres) and coordinates via Postgres advisory locks, so N
|
# (arrstack-postgres) and coordinates via Postgres advisory locks, so N
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
resources:
|
||||||
|
- valkeycluster.yaml
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
# Single shared HA Valkey for the arr apps (sonarr/radarr/prowlarr), managed by
|
||||||
|
# valkey-operator. It activates the fork's #14 Redis features: the SignalR
|
||||||
|
# backplane, the cross-replica cache-invalidation bus, and the distributed rate
|
||||||
|
# limiter. One cluster is safe for all three because each fork namespaces its
|
||||||
|
# keys and pub/sub channels by a per-app prefix (sonarr:ratelimit: /
|
||||||
|
# radarr:ratelimit: / prowlarr:ratelimit:), so their state never collides.
|
||||||
|
#
|
||||||
|
# Modeled on jellyfin-valkey: shards:1 + replicas:2 is one primary with two
|
||||||
|
# replicas in a single shard group (three ValkeyNodes total); losing the primary
|
||||||
|
# triggers an automatic failover so a node/pod loss no longer drops the shared
|
||||||
|
# state the app replicas coordinate through. The operator runs Valkey
|
||||||
|
# cluster-mode-enabled with protected-mode off and leaves the built-in `default`
|
||||||
|
# user passwordless, so clients connect with no auth/TLS; StackExchange.Redis
|
||||||
|
# seeds off the single service and auto-discovers topology plus failovers.
|
||||||
|
# scheduling.node.spread.shard:Required keeps the three nodes on distinct hosts,
|
||||||
|
# so one host loss removes at most one node; podDisruptionBudget.mode:Cluster
|
||||||
|
# lets the operator manage a quorum-aware PDB. Persistence is omitted (/data is an
|
||||||
|
# emptyDir): the coordination state is ephemeral (short TTLs / transient pub/sub),
|
||||||
|
# replication+failover already provide redundancy, and an operator-managed PVC
|
||||||
|
# cannot carry the k8up.io/backup:"false" annotation the namespace k8up Schedule
|
||||||
|
# needs to skip in-use RWO volumes.
|
||||||
|
apiVersion: valkey.io/v1alpha1
|
||||||
|
kind: ValkeyCluster
|
||||||
|
metadata:
|
||||||
|
name: arrstack-valkey
|
||||||
|
namespace: arrstack
|
||||||
|
spec:
|
||||||
|
shards: 1
|
||||||
|
replicas: 2
|
||||||
|
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/valkey/valkey:9.0.0
|
||||||
|
exporter:
|
||||||
|
enabled: false
|
||||||
|
scheduling:
|
||||||
|
node:
|
||||||
|
spread:
|
||||||
|
shard:
|
||||||
|
mode: Required
|
||||||
|
podDisruptionBudget:
|
||||||
|
mode: Cluster
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 128Mi
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
Reference in New Issue
Block a user