mirrors is a custom Kubernetes controller operating with special CRD objects.
Main purpose of mirrors currently is to copy Kubernetes Secret objects to and from various locations.
mirrors supports 2 kinds of source and/or destination of a secret:
- Kubernetes Secret
- HashiCorp Vault Secret
It means that the following scenarios are possible using mirrors for automatic secret mirroring:
- copy a Kubernetes Secret from one namespace to any other by a regex (e.g. copying registry credentials or TLS certificate between namespaces)
- copy a Kubernetes Secret from a namespace to HashiCorp Vault
- copy a secret from HashiCorp Vault secret to one or many Kubernetes namespaces
All these scenarios unlock possibilities to mirror any given secret to and from one or many Kubernetes clusters.
SecretMirror available fields are documented here.
Let's say we have a following Kubernetes secret:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
username: hellothere
password: generalkenobiIt is deployed to a namespace default within a Kubernetes cluster. Using the following SecretMirror object one can easily replicate this secret to any namespace which matches the regular expression demo-namespace-\d+:
apiVersion: mirrors.kts.studio/v1alpha2
kind: SecretMirror
metadata:
name: mysecret
spec:
source:
name: mysecret
destination:
namespaces:
- demo-namespace-\d+After deploying this SecretMirror a Secret named mysecret is going to
be copied to all the destination namespaces and will do this continuously
once every 3 minutes (this can be configured with a pollPeriodSeconds setting in each SecretMirror).
mirrors was specifically designed so that it's not monitoring changes in Secret
objects in order to avoid stressing Kubernetes API with a lot of requests
and updates (because usually there are a lot of Secrets in a
typical Kubernetes cluster).
As you can see destination.namespaces is an array, so it is possible to
specify multiple regexps. Secret will be copied to all the matched namespaces.
Security note: mirrors specifically does not allow copying a secret from arbitrary namespace, only from the
namespace where a SecretMirror is deployed.
You can easily replicate a secret mysecret to your HashiCorp Vault cluster by using the following spec:
apiVersion: mirrors.kts.studio/v1alpha2
kind: SecretMirror
metadata:
name: mysecret
spec:
source:
name: mysecret
destination:
type: vault
vault:
addr: https://vault.example.com
path: /secret/data/myteam/mysecret
auth:
approle:
secretRef:
name: vault-approleThis SecretMirror will use an AppRole auth mechanism in order to login to Vault and obtain a token.
There should exist a vault-approle secret containing appRole credentials:
apiVersion: v1
kind: Secret
metadata:
name: vault-approle
type: Opaque
stringData:
role-id: your-role-id
secret-id: your-secret-idIt is also possible to authenticate using a VAULT_TOKEN directly:
apiVersion: mirrors.kts.studio/v1alpha2
kind: SecretMirror
metadata:
name: mysecret
spec:
source:
name: mysecret
destination:
type: vault
vault:
addr: https://vault.example.com
path: /secret/data/myteam/mysecret
auth:
token:
secretRef:
name: vault-tokenwith the secret, containing vault token:
apiVersion: v1
kind: Secret
metadata:
name: vault-token
namespace: default
type: Opaque
stringData:
token: s.YOURTOKENBut this is highly discouraged, because currently there is no token renewal
mechanism in mirrors so if your token will expire mirrors can do nothing
with that, and you will be forced to update a token in the secret.
In order to copy a Secret from HashiCorp Vault to Kubernetes use the following SecretMirror:
apiVersion: mirrors.kts.studio/v1alpha2
kind: SecretMirror
metadata:
name: mysecret2
spec:
source:
name: mysecret2
type: vault
vault:
addr: https://vault.example.com
path: /secret/data/myteam/mysecret
auth:
approle:
secretRef:
name: vault-approle
destination:
namespaces:
- important-namespace-\d+It is required to specify source.name as it will be the future name of Kuberentes secrets created in the cluster.
More examples can be found at config/samples folder.
In order to install mirrors controller you need to execute the following:
helm repo add kts https://charts.kts.studio
helm repo update
helm upgrade --install mirrors kts/mirrorsOr using built-in kustomize deployment:
git clone https://github.com/ktsstudio/mirrors
cd mirrors
cd config/default
kustomize edit set image controller=ktshub/mirrors:0.2.7
kustomize build . | kubectl apply -f -The following specific mirrors metrics are exposed:
| metric | description |
|---|---|
mirrors_sync_total |
Number of successful mirror syncs |
mirrors_ns_current_count |
Number of namespaces to which a secret has been successfully mirrored |
mirrors_vault_lease_renew_ok_total |
Number of successful lease renewals |
mirrors_vault_lease_renew_error_total |
Number of errored lease renewals |