This repository contains a custom Kubernetes controller that can be used to replicate secrets and config maps, in order to make them available in multiple namespaces or to avoid for them to be updated on chart deployments.
$ helm upgrade --install kubernetes-replicator ./deploy/helm-chart/kubernetes-replicator
$ # Create roles and service accounts
$ kubectl apply -f https://github.com/mittwald/kubernetes-replicator/master/deploy/rbac.yaml
$ # Create actual deployment
$ kubectl apply -f https://github.com/mittwald/kubernetes-replicator/master/deploy/deployment.yaml
You can configure a secret or a configMap to receive a copy of another secret or configMap:
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
v1.kubernetes-replicator.olli.com/replicate-from: default/some-secret
data: {}
Annotations are:
v1.kubernetes-replicator.olli.com/replicate-from
: The source of the data to receive a copy from. Can be a full path<namespace>/<name>
, or just a name if the source is in the same namespace.v1.kubernetes-replicator.olli.com/replicate-once
: Set it to"true"
for being replicated only once, no matter to the future changes of the source. Can be useful if the source is a randomly generated password, but you don't want your local passowrd to change anymore.
Unless you run kubernetes-replicator with the --allow-all
flag, you need to explicitely allow the source to be replicated:
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
v1.kubernetes-replicator.olli.com/replication-allowed: "true"
data: {}
At leat one of the two annotations is required (if the --allow-all
is not used):
v1.kubernetes-replicator.olli.com/replication-allowed
: Set it to"true"
to explicitely allow replication, or"false"
to explicitely diswallow itv1.kubernetes-replicator.olli.com/replication-allowed-namespaces
: a comma separated list of namespaces or namespaces patterns to explicitely allow. ex:"my-namespace,test-namespace-[0-9]+"
Other annotations are:
v1.kubernetes-replicator.olli.com/replicate-once
: Set it to"true"
for being replicated only once, no matter future changes. Can be useful if the secret is a randomly generated password, but you don't want the local copies to change anymore.v1.kubernetes-replicator.olli.com/replicate-once-version
: A semver2 version. When a higher version is set, this secret or confingMap is replicated again, even if replicated once. It allows a thinner control on thev1.kubernetes-replicator.olli.com/replicate-once
annotation. If absent, version is assumed to be"0.0.0"
."5"
will be interpreted as"5.0.0"
.
The content of the target secret of configMap will be emptied if the source does nto exist or is deleted.
You can configure a secret or a configMap to replicate itself automatically to desired locations:
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
v1.kubernetes-replicator.olli.com/replicate-to: default/other-secret
data: {}
At leat one of the two annotations is required:
v1.kubernetes-replicator.olli.com/replicate-to
: The target(s) of the annotation, comma separated. Can be a name, a full path<namespace>/<name>
, or a pattern<namesapce_pattern>/<name>
. If just given a name, it will be combined with the namespace of the source, or with thev1.kubernetes-replicator.olli.com/replicate-to-namespaces
annotation if present. ex:"other-secret,other-namespace/another-secret,test-namespace-[0-9]+/nyan-secret"
v1.kubernetes-replicator.olli.com/replicate-to-namespaces
: The target namespace(s) for replication, comma separated. it will be combined with the name of the source, or with thev1.kubernetes-replicator.olli.com/replicate-to
if present. ex:"other-namespace,test-namespace-[0-9]+"
Other annotations are:
v1.kubernetes-replicator.olli.com/replicate-once
: Set it to"true"
for being replicated only once, no matter future changes. Can be useful if the secret is a randomly generated password, but you don't want the local copies to change anymore.v1.kubernetes-replicator.olli.com/replicate-once-version
: A semver2 version. When a higher version is set, this secret or confingMap is replicated again, even if replicated once. It allows a thinner control on thev1.kubernetes-replicator.olli.com/replicate-once
annotation. If absent, version is assumed to be"0.0.0"
."5"
will be interpreted as"5.0.0"
.
Replication will be cancelled if the target secret or configMap already exists but was not created by replication from this source. However, as soon as that existing target is deleted, it will be replaced by a replication of the source.
Once the source secret or configMap is deleted or its annotations are changed, the target is deleted.
v1.kubernetes-replicator.olli.com/replicate-from
and v1.kubernetes-replicator.olli.com/replicate-to
annotations can be mixed together, in order to replicate the data of another secret of configMap to a specified target.
Create the source secret
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: database-credentials
namespace: default
annotations:
v1.kubernetes-replicator.olli.com/replication-allowed: "true"
stringData:
host: mydb.com
database: mydb
password: qwerty
You can now create an empty secret everywhere you needs this (including in helm charts)
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: local-database-credentials
annotations:
v1.kubernetes-replicator.olli.com/replicate-from: "default/database-credentials"
Or you can give your secret a target, such that it won't be reset by helm on further deployments
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: source-database-credentials
annotations:
v1.kubernetes-replicator.olli.com/replicate-from: "default/database-credentials"
v1.kubernetes-replicator.olli.com/replicate-to: "target-database-credentials"
Create your source secret with a random password, and replicate it once
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: admin-password-source
annotations:
v1.kubernetes-replicator.olli.com/replicate-to: "admin-password"
v1.kubernetes-replicator.olli.com/replicate-once: "true"
# in case of the secret format changes
v1.kubernetes-replicator.olli.com/replicate-once-version: "0"
stringData:
password: {{ randAlphaNum 64 | quote }}
And use it in your deployment
apiVersion: extensions/v1beta1
kind: Deployment
spec:
template:
spec:
containers:
- name: my-container
image: gcr.io/my-project/my-container:latest
env:
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: admin-password
key: password
Create your TLS secret
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
name: my-tls
namespace: jx
annotations:
v1.kubernetes-replicator.olli.com/replicate-to-namespaces: "jx-.*"
stringData:
tls.crt: |
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
tls.key: |
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
And use it in your ingresses in any namespace you replicated to
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
spec:
tls:
- hosts:
- example.com
secretName: my-tls