A lightweight Kubernetes controller that replicates ConfigMaps and Secrets across namespaces. Annotate a source object and Replikate copies it into every matching namespace — keeping copies in sync on change, cleaning them up on delete, and populating new namespaces automatically.
replikate.brainchurts.com/sync: "<selector>" "team=web" # → namespaces matching the label "" # → every namespace
Source changed → every copy is updated. Source or annotation removed → copies are deleted via a finalizer. A new namespace appears that matches → it is populated automatically.
Replikate never overwrites an object it does not manage, and only writes when something actually changed. It's annotation-compatible with AppsCode's config-syncer, and adopts existing copies in place during a cutover rather than deleting and recreating them.
# install into the cluster (image built by CI) $ make deploy IMAGE_REPO=ghcr.io/cwolsen7905/replikate \ IMAGE_TAG=v0.1.0
apiVersion: v1
kind: ConfigMap
metadata:
name: shared-config
annotations:
replikate.brainchurts.com/sync: "team=web"
data:
LOG_LEVEL: "info" # the namespace gets a copy near-instantly $ kubectl label namespace some-ns team=web $ kubectl get configmap shared-config -n some-ns
Controller flags and the matching Helm values — sensible defaults, tune what you need.
| Flag | Default | Notes |
|---|---|---|
| -annotation-domain | replikate.brainchurts.com | Prefix of the /sync annotation the controller watches. |
| -exclude-namespaces | kube-system,kube-public,kube-node-lease | Never replicate copies into these namespaces. |
| -leader-elect | false | Elect a single active replica (the Helm chart turns this on). |
| -metrics-bind-address | :8080 | Prometheus metrics endpoint. |
| -health-probe-bind-address | :8081 | Liveness / readiness probes. |
| -enable-webhook | false | Optional validating admission webhook. |
| Value | Default | Notes |
|---|---|---|
| annotationDomain | replikate.brainchurts.com | Wires the flag above. |
| excludeNamespaces | kube-system, kube-public, kube-node-lease | Namespace skip-list. |
| leaderElection.enabled | true | HA-safe; only one replica reconciles at a time. |
| rbac.create | true | ClusterRole/Binding for ConfigMap + Secret access. |
| resources (req → lim) | 50m/64Mi → 200m/128Mi | Lightweight footprint out of the box. |
| metrics.serviceMonitor.enabled | false | Scrape via the Prometheus Operator. |
| webhook.enabled | false | Validating webhook (port 9443, failurePolicy Fail). |
| podDisruptionBudget.enabled | false | Keep at least one replica during disruptions. |
Watch the sources and the namespaces; make the copies match; only write when something changed.
Replikate is a single controller built on controller-runtime. It watches two things — annotated source objects and the set of namespaces — and on any change reconciles the desired state: a managed copy of each source in every namespace its selector matches. It only writes when something actually differs, so the logs stay meaningful.
Ownership is explicit. Every copy is stamped managed-by=replikate, and the controller refuses to touch an object it doesn't own — emitting a Conflict event instead of fighting another source. A finalizer guarantees copies are removed when the source or annotation goes away, and the namespace watch means a new matching namespace is populated automatically.
It runs leader-elected, so multiple replicas are HA-safe with exactly one active reconciler. Cross-cluster (hub-and-spoke) replication is designed and on the roadmap.