The Syncer Operator is a Kubernetes operator that provides two Custom Resources to synchronize ConfigMaps and Secrets across namespaces. Built using the Operator SDK framework, it offers flexible and secure resource synchronization capabilities.
- ConfigMapSync: Sync multiple ConfigMaps from source namespace to target namespaces
- SecretSync: Sync multiple Secrets from source namespace to target namespaces
- Automatic reconciliation when source resources change
- Independent control over ConfigMap and Secret synchronization
- Granular RBAC permissions
- Target namespace selection by:
- Explicit namespace list
- Label selector
- Both (combined targeting)
graph TD
A[ConfigMapSync Controller] -->|Watches| B[ConfigMapSync CRD]
A -->|Watches| C[ConfigMaps]
A -->|Watches| D[Namespaces]
B -->|Defines| E[Source Namespace]
B -->|Defines| F[Target Selection]
F -->|List| G[Explicit Namespaces]
F -->|Labels| H[Namespace Labels]
A -->|Creates/Updates| I[Synced ConfigMaps]
J[SecretSync Controller] -->|Watches| K[SecretSync CRD]
J -->|Watches| L[Secrets]
J -->|Watches| M[Namespaces]
K -->|Defines| N[Source Namespace]
K -->|Defines| O[Target Selection]
O -->|List| P[Explicit Namespaces]
O -->|Labels| Q[Namespace Labels]
J -->|Creates/Updates| R[Synced Secrets]
-
Install the operator:
make deploy IMG=your-registry/syncer:tag
-
Create a ConfigMapSync resource with label selector:
apiVersion: syncer.containeers.com/v1alpha1 kind: ConfigMapSync metadata: name: my-config-sync namespace: default spec: sourceNamespace: source-ns targetNamespaces: - target-ns1 - target-ns2 targetNamespaceSelector: matchLabels: environment: staging sync-enabled: "true" configMaps: - name: config1 - name: config2
-
Create a SecretSync resource with label selector:
apiVersion: syncer.containeers.com/v1alpha1 kind: SecretSync metadata: name: my-secret-sync namespace: default spec: sourceNamespace: source-ns targetNamespaces: - target-ns1 - target-ns2 targetNamespaceSelector: matchLabels: environment: staging sync-enabled: "true" secrets: - name: secret1 - name: secret2
- Watches for ConfigMapSync resources
- Monitors specified ConfigMaps in source namespace
- Watches for namespace changes (for label-based targeting)
- Determines target namespaces by:
- Including explicitly listed namespaces
- Including namespaces matching label selector
- Synchronizes ConfigMaps to all target namespaces
- Updates status with sync information
- Watches for SecretSync resources
- Monitors specified Secrets in source namespace
- Watches for namespace changes (for label-based targeting)
- Determines target namespaces by:
- Including explicitly listed namespaces
- Including namespaces matching label selector
- Synchronizes Secrets to all target namespaces
- Updates status with sync information
-
Clone the repository:
git clone https://github.com/containeers/syncer
-
Install dependencies:
go mod tidy
-
Run locally:
make install run
The operator creates two separate ServiceAccounts with different permissions:
- ConfigMapSync controller: Access to ConfigMaps and namespace list/watch
- SecretSync controller: Access to Secrets and namespace list/watch
This separation ensures better security by following the principle of least privilege.
# Label namespaces for targeting
kubectl label namespace dev environment=dev sync-enabled=true
kubectl label namespace staging environment=staging sync-enabled=true
kubectl label namespace qa environment=qa sync-enabled=true
apiVersion: syncer.containeers.com/v1alpha1
kind: ConfigMapSync
metadata:
name: app-config-sync
spec:
sourceNamespace: prod
# Optional explicit namespace list
targetNamespaces:
- always-sync-ns
# Label selector for dynamic targeting
targetNamespaceSelector:
matchLabels:
environment: staging
sync-enabled: "true"
matchExpressions:
- key: environment
operator: In
values: ["dev", "staging"]
configMaps:
- name: app-config
- name: feature-flags
apiVersion: syncer.containeers.com/v1alpha1
kind: SecretSync
metadata:
name: app-secret-sync
spec:
sourceNamespace: prod
# Optional explicit namespace list
targetNamespaces:
- always-sync-ns
# Label selector for dynamic targeting
targetNamespaceSelector:
matchLabels:
environment: staging
sync-enabled: "true"
matchExpressions:
- key: environment
operator: In
values: ["dev", "staging"]
secrets:
- name: db-credentials
- name: api-keys
The operator provides detailed status information about synced resources:
status:
conditions:
- lastTransitionTime: "2024-03-14T10:00:00Z"
message: Successfully synced to all target namespaces
reason: SyncSuccessful
status: "True"
type: Ready
targetNamespaces:
- name: dev
syncStatus: Synced
lastSyncTime: "2024-03-14T10:00:00Z"
- name: staging
syncStatus: Synced
lastSyncTime: "2024-03-14T10:00:00Z"
labelSelectedNamespaces:
- dev
- staging
- qa
The operator exposes Prometheus metrics at :8080/metrics
including:
- Number of successful syncs
- Number of failed syncs
- Sync duration
- Resource counts
- Number of target namespaces (explicit and label-selected)
- Label selector match statistics
This project is licensed under the MIT License - see the LICENSE file for details.