Syncing cert-manager certificate secret across Namespaces using kubed- 2 mins
A common use-case for cert-manager is requesting TLS signed certificates to secure your ingress resources. This can be done by simply adding this annotation
cert-manager.io/cluster-issuer: nameOfClusterIssuer to your Ingress resources and cert-manager will facilitate creating the Certificate resource for you.
When you have multiple ingresses in separate namespaces, this annotation ends up creating certificate resources in each of the namespaces. If you use Let’s encrypt, the limit of Duplicate Certificates is 5 per week, and it is easy to hit this limit if you have a lot of namespaces. You can decide to create the TLS secret for the certificate in one namespace and copy manually across all namespaces, but that will be a pain to manage and maintain. cert-manager docs recommends using kubed with its secret syncing feature to solve this problem.
Sync ingress certificate secret across namespaces using kubed
In order for the target Secret to be synced, the Secret resource must first be created with the correct annotations before the creation of the Certificate, else the Secret will need to be edited instead. When I tried this out, I created the Certificate first and edited the secret annotation afterwards.
The example below creates a certificate resource in
sandbox namespace. This in turn creates a secret
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: cert-secret namespace: sandbox spec: secretName: cert-secret issuerRef: name: letsencrypt-prod kind: ClusterIssuer dnsNames: - domain.example.com
Now apply the
kubed.appscode.com/sync: "" annotation to the
cert-secret created by the cert-manager Certificate resource.
kubectl annotate secret cert-secret kubed.appscode.com/sync=""
This annotation will cause Kubed operator to copy the secret to all existing and new namespaces. If you want to synchronize this secret to some selected namespaces instead of all namespaces, you can do that by specifying namespace label-selector in the annotation. For example:
You can now create your ingress resources to use the copied secret and you will no longer need this cert-manager annotation
cert-manager.io/cluster-issuer: nameOfClusterIssuer in your ingress.
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: test-ingress annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - domain.example.com secretName: cert-secret rules: ...