← All projects
Kubernetes

Replikate

Live · v0.1.0 Go · BSD-3-Clause · in-cluster controller

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.

Language
Go
License
BSD-3-Clause
Runtime
In-cluster controller
Image
amd64 + arm64
Synopsis
annotation
replikate.brainchurts.com/sync: "<selector>"

  "team=web"   # → namespaces matching the label
  ""           # → every namespace
Description

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.

Examples
install
# install into the cluster (image built by CI)
$ make deploy IMAGE_REPO=ghcr.io/cwolsen7905/replikate \
       IMAGE_TAG=v0.1.0
annotate a ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: shared-config
  annotations:
    replikate.brainchurts.com/sync: "team=web"
data:
  LOG_LEVEL: "info"
label a namespace
# the namespace gets a copy near-instantly
$ kubectl label namespace some-ns team=web
$ kubectl get configmap shared-config -n some-ns
Capabilities
Selector or cluster-wide
Target namespaces by label selector, or leave the value empty to reach all of them.
Kept in lockstep
Copies are watched, not left until the next resync — a hand-edited replica is restored near-instantly.
Finalizer cleanup
Delete the source or drop the annotation and every managed copy is removed cleanly.
Auto-populate
A new namespace that matches the selector is filled in without any manual step.
Conflict-safe migration
Adopts config-syncer copies in place, and refuses to fight another source over a copy.
Configuration

Configuration reference.

Controller flags and the matching Helm values — sensible defaults, tune what you need.

Controller flags
FlagDefaultNotes
-annotation-domainreplikate.brainchurts.comPrefix of the /sync annotation the controller watches.
-exclude-namespaceskube-system,kube-public,kube-node-leaseNever replicate copies into these namespaces.
-leader-electfalseElect a single active replica (the Helm chart turns this on).
-metrics-bind-address:8080Prometheus metrics endpoint.
-health-probe-bind-address:8081Liveness / readiness probes.
-enable-webhookfalseOptional validating admission webhook.
Helm chart · values.yaml
ValueDefaultNotes
annotationDomainreplikate.brainchurts.comWires the flag above.
excludeNamespaceskube-system, kube-public, kube-node-leaseNamespace skip-list.
leaderElection.enabledtrueHA-safe; only one replica reconciles at a time.
rbac.createtrueClusterRole/Binding for ConfigMap + Secret access.
resources (req → lim)50m/64Mi → 200m/128MiLightweight footprint out of the box.
metrics.serviceMonitor.enabledfalseScrape via the Prometheus Operator.
webhook.enabledfalseValidating webhook (port 9443, failurePolicy Fail).
podDisruptionBudget.enabledfalseKeep at least one replica during disruptions.
Architecture

One controller, one reconcile loop.

Watch the sources and the namespaces; make the copies match; only write when something changed.

The loop
Annotated source
ConfigMap / Secret with replikate.brainchurts.com/sync
Controller · reconcile
watches sources + namespaces · leader-elected
Managed copies
one per matching namespace · kept in sync
How it behaves

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.