Production Install

This guide installs Bloodraven for production. For a short first run, use Getting Started or the Playground first.
Prerequisites
- Kubernetes 1.31 or newer. CI tests the CRD admission rules (CEL, list-map keys, status bounds) against 1.31, and the Helm chart refuses older clusters. On 1.31 and 1.32, keep the
CRDValidationRatchetingfeature gate on (the default; it is GA and always on from 1.33). With it off the CRDs still install, but the API server skips one creation-time check, thatspec.initFromBackup.pointInTime.archiveProfileNamenames an entry ofspec.backup.profiles; such a restore fails withRestoreBuildFailedinstead. - Helm 3.
- Nodes labelled by site as described in Placement Contract.
- A tested StorageClass for MySQL PVCs.
- external-dns and the
externaldns.k8s.io/v1alpha1DNSEndpointCRD. - cert-manager, if it issues the Secret that
spec.tls.secretNamenames. - Prometheus and Grafana if you want the shipped monitoring path.
- Object storage or PVC storage for backups.
- Dragonfly
v1.38.0+image access if you enablespec.dragonflyfor cache/session co-management. After the first probe,status.dragonfly.replTakeoverSupportedreports whether the running image advertisesREPLTAKEOVER.
Namespace layout
| Namespace | Contains |
|---|---|
bloodraven | Operator Deployment, RBAC, metrics Service |
orders | MysqlFailoverGroup, MySQL pods, app-facing Services, backup Jobs |
monitoring | Prometheus, Grafana, alert rules, dashboard ConfigMaps |
Install CRDs
GitOps users should choose one owner for CRDs. Do not let both Helm and a separate CRD application race to own the same files.
Pin one release and use it for both the chart and the CRDs. The release tag carries a v prefix; the chart version does not.
BLOODRAVEN_VERSION=v1.6.0
helm upgrade --install bloodraven bloodraven/bloodraven \
--namespace bloodraven \
--create-namespace \
--version "${BLOODRAVEN_VERSION#v}"
Helm installs CRDs from the chart's crds/ directory on first install. If CRDs are managed separately, apply all five from the same release tag with server-side apply:
for crd in mysqlfailovergroups mysqlbackups mysqlbackupverifications mysqldatabases mysqlstandbyclusters; do
kubectl apply --server-side --force-conflicts \
-f "https://raw.githubusercontent.com/ShipStream/bloodraven/${BLOODRAVEN_VERSION}/config/crd/bases/shipstream.io_${crd}.yaml"
done
Never apply CRDs from main. main can carry schema changes that no released operator understands.
Use --server-side for CRD installs and upgrades. The MysqlFailoverGroup CRD is larger than the 256 KiB limit on the kubectl.kubernetes.io/last-applied-configuration annotation that client-side kubectl apply writes, so a plain kubectl apply -f fails with metadata.annotations: Too long: may not be more than 262144 bytes.
Then install the operator chart after the platform CRD app has applied the CRDs. Helm does not upgrade CRDs in crds/; apply CRD updates explicitly during upgrades.
Helm values
Application deployment coordination is opt-in. See the Deployment API values for auxiliary.deployAPI.enabled, the required existing escrow TLS Secret, audience, and optional NetworkPolicy. Apply the matching CRD updates before declaring MysqlDatabase.spec.deploymentClients; Helm upgrades alone do not upgrade CRDs.
image:
repository: ghcr.io/shipstream/bloodraven
tag: "1.3.2"
pullPolicy: IfNotPresent
replicaCount: 1
# Optional Organization license JWT. Public assertion, not a secret.
# license: "eyJhbGciOiJFZERTQSIsImtpZCI6ImJyLTEiLCJ0eXAiOiJKV1QifQ...."
leaderElection:
enabled: true
metrics:
service:
enabled: true
serviceMonitor:
enabled: true
interval: 30s
scrapeTimeout: 10s
labels:
release: kube-prometheus-stack
grafanaDashboards:
enabled: true
namespace: monitoring
folder: Bloodraven
auxiliary:
service:
enabled: false
wsAllowedOrigins: "https://dashboard.example.com"
Apply:
helm upgrade --install bloodraven bloodraven/bloodraven \
--namespace bloodraven \
--create-namespace \
--values bloodraven-values.yaml
NetworkPolicy recommendations
Allow only these paths:
| Source | Destination | Port | Why |
|---|---|---|---|
| Operator | Kubernetes API | 443 | Reconcile CRDs, Services, Events, Jobs |
| Operator | MySQL pods | 3306 | Health, promotion, user management |
| Operator | Dragonfly Services | 6379, admin port 9999 by default | Optional Dragonfly observation, replication wiring, promotion, and snapshot upgrade |
| MySQL sidecar | Kubernetes API | 443 | Lease and fencing coordination |
| Prometheus | Operator metrics Service | 8080 | Metrics scraping |
| Applications | Primary and replica Services | 3306 | Data plane |
| Applications | Active Dragonfly Service | 6379 | Optional Redis-compatible cache/session data plane |
| Backup Jobs | S3 endpoint | 443 | Backup artifacts |
Post-install verification
kubectl rollout status deployment/bloodraven -n bloodraven
kubectl get crd mysqlfailovergroups.shipstream.io mysqlbackups.shipstream.io mysqlbackupverifications.shipstream.io
kubectl get service -n bloodraven
kubectl auth can-i list mysqlfailovergroups.shipstream.io --as=system:serviceaccount:bloodraven:bloodraven
Before production traffic
- Complete Production Hardening.
- Create per-role credentials with Credentials and TLS.
- Configure Prometheus and Grafana.
- Configure S3 backups or PVC backups.
- If using Dragonfly, configure application Redis clients to use
<group>-dragonflyand validatestatus.dragonfly.phase=Ready. - Run a planned failover in a staging environment.

