vmware-archive / kube-prod-runtime

A standard infrastructure environment for Kubernetes
Apache License 2.0
760 stars 134 forks source link

How to use a wildcard DNS and certs? #320

Open rberrelleza opened 5 years ago

rberrelleza commented 5 years ago

Is there a way to configure kubeprod to use a pre-created wildcard DNS entry and cert for all the services deployed?

Since all the services deployed will have the same subdomain (e.g. services.example.com), having a single DNS entry for .services.example.com and a single cert for .services.example.com would speed up service provisioning a lot, instead of the 1-3 minutes it takes today.

falfaro commented 5 years ago

That's a very good question.

At the moment, they way BKPR enables ingress support for Grafana, Kibana and Prometheus is by requesting one X.509 certificate from Let's Encrypt for each of them (3 certificates in total). This is handled by the cert-manager pod. At the same time, the external-dns pod will configure three A and TXT records for these ingress resources.

If I understand you correctly, you would like BKPR to behave different than this: you already have a wildcard DNS entry and X.509 certificate for your entire domain. Please correct me if I understood it wrong.

rberrelleza commented 5 years ago

I have two different ideas in mind:

We currently do this manually ( we have a script to copy the certificate between namespaces and all that) but it would be great to have it taken care of.

The cert-manager and nginx-ingress teams discussed this and decided not to implement it, but this might be a problem that makes more sense to fix at BKPR's level.

anguslees commented 5 years ago

All of this is possible, with appropriate overrides to the manifests :)

For the first case (you already have DNS and certs), you can just create the DNS entry and k8s Secret containing the TLS secret, and external-dns and cert-manager should see they're already there and not override them (I haven't tested this).

If you want to provide these values through the override mechanism instead of managing them through a different tool, here's how to do that through BKPR/jsonnet:

// This is kubeprod-manifest.jsonnet 
local kube = import "kube.libsonnet";
(import "https://releases.kubeprod.io/files/v1.1.0/manifests/platforms/gke.jsonnet") {
   config:: import "kubeprod-autogen.json",

   // Place your overrides here
   grafana+: {
      local grafana = self,

      ingress+: {
         metadata+: {
            annotations+: {
               "kubernetes.io/tls-acme": "false",  // turn off letsencrypt for this Ingress
               "external-dns.alpha.kubernetes.io/controller": "noexist", // turn off external-dns for this Ingress
            },
         },
         host: "grafana.example.com",  // or whatever hostname.  Assumed to already exist.
      },

      // Create a new Secret containing a TLS key from local crt/key files
      mycert: kube.Secret(grafana.ingress.spec.tls[0].secretName) {
         type: "kubernetes.io/tls",
         data_: {
           "tls.crt": importstr "mycert.crt",  // PEM file, read during jsonnet expansion
           "tls.key": importstr "mycert.key",  // (ditto)
         },
      },
   },
}

I think your second case is what BKPR does out of the box (manage DNS and cert for you). If I missed something, and it isn't obvious how to do that from looking at the above example, please follow up.

(I would be overjoyed if someone could verify the above actually works (heh!), and send a PR that adds the above question/answer to a doc or faq.)

arapulido commented 5 years ago

@rberrelleza were you able to test the suggestion above?

rberrelleza commented 5 years ago

Not yet @arapulido . I'm configuring a cluster this week, I'll try the suggestion.

arapulido commented 5 years ago

@rberrelleza any updates?

arapulido commented 5 years ago

@rberrelleza Hello! did you finally test this?

ghost commented 5 years ago

I did, It didn't work. I think using grafana in the example is confusing. this is better to demonstrate with a new resource.