Problem Statement
There are cases you need to share wildcard SSL certificats between different namespaces through k8s ingress controller(traefik 2.x). From security perspective, you should not do this. But, but, but…, you still need it when it comes to reality.
Scenario
You deploy your kubernetes cluster in your private cloud and having lots of services deployed on top of it. Your service, however will only expose domain-a.com
, domain-b.com
to the world. You also have wildcard certificate files for both domain.
If you have more than 3 namespaces in your cluster, then you have to create those tls secrets for 3 different namespaces. When you renew your certificates, you need to modify them one by one too.
When we use Traefik 2.x for our ingress controller, then there comes to question, Can I set namespace for TLS secretName in IngressRoute?
Manage TLS certification in Cluster
User TLS certification in different namespaces
For IngressRoute - I would like to be able to set namespace for TLS secretName.
Currently, I am putting my IngressRoutes into the same namespace as the service they refer to.
And it is currently not possible to point the TLS secretName at another namespace.
So if I have more than one IngressRoute using the same certificate, then I need to create a secret for every namespace.
Secrets are namespaced for isolation and security reasons. We should not support cross-namespace secret mounting, as it would allow users to fish for secrets.
I have my services in various namespaces other than default and want to have my IngressRoutes in the same namespace.
However, I am using the same wildcard certificate for multiple IngressRoutes, while I have to put the secret in a single namespace.
How do I go about managing this, if I don’t want to create a secret per namespace?
Solution
You can specify TLS certificates to Traefik (TLS secrets mounted in Traefik pod) as defined in https://docs.traefik.io/v2.0/https/tls/#user-defined .
Then, for your IngressRoute, you specify tls: {} and Traefik will match based on the router rule.
A quick example had been added into the community forum topic you started at https://community.containo.us/t/can-i-set-namespace-for-tls-secretname-in-ingressroute/2619.
Create secrets for Traefik
For installation of Traefik, please refer to official site. Suppose you install traefik in traefik-system
system.
Prepare your certificates, naming tls-a.key, tls-a.crt, tls-b.key, tls-b.crt. Get base64 of them for yaml files.
1 | $ cat tls-a.key | base64 |
Your tls.yaml
file.
1 | apiVersion: v1 |
Apply it to your cluster.
1 | $ kubectl apply -f tls.yaml |
Modify your traefik configuration
In your traefik yaml file, you have to add/modify as following.
1 | apiVersion: v1 |
We use --providers.file.filename
for dynamic configuration for our traefik, and having volumeMounts[].mountPath same as certFile path, the traefik can retrieve those files when it needs it. Apply it to your traefik.
Configure your IngressRoute
Here you have 2 services in two different namespaces. The service end points are:
then modify your ingressroute.yaml
1 | apiVersion: v1 |
The most import part is tls
as {}
, no more tls.secretName
.
Happy hacking…