Overview
You can use a Traefik ingress instance for routing application traffic to services in your cluster. And because Konvoy also includes the cert-manager certificate controller, you can use these services together to provide HTTPS ingress with a custom domain name and certificate to services in your Konvoy cluster.
Prerequisites
- We assume you already have a Konvoy cluster provisioned using at least v1.5.0. If the cluster is provisioned using an older version of Konvoy (i.e., v1.4.x), please update kubernetes-base-addons to version stable-1.16-1.4.0 or newer.
- We assume you can setup a DNS A record for the IP used by your Traefik instance (or CNAME for the cluster ingress load balancer hostname in the public cloud cases like AWS).
Configure DNS for your custom domain
First, make sure to set up your custom domain to point at either your Trafik instance IP, or it's DNS name. You can run the following command to get the IP or Load balancer that was created by kubeaddons for the default Traefik service:
kubectl get svc traefik-kubeaddons -n kubeaddons
The name printed as the 'EXTERNAL-IP' is the IP or DNS name you would use. If the EXTERNAL-IP is a DNS name (like an Amazon Loadbalancer), you should configure a CNAME record to point at this address with your DNS provider. If it's an IP address, you would configure an A record with your provider.
Create a certificate for your custom domain
The Konvoy cert-manager addon can be used to create a certificate for your domain. You can create either a self-signed certificate (using the selfSigned issuer) or a Let's Encrypt Certificate. For our example, we'll use Let's Encrypt, as this will provide a certificate that will be trusted by most web browsers.
To limit the issuer to just one namespace, use the 'Issuer' type; if you want to set up Let's Encrypt for multiple namespaces, use a ClusterIssuer. For our example, we'll use the simpler form:
cat <<EOF | kubectl apply -f - apiVersion: certmanager.k8s.io/v1alpha1 kind: Issuer metadata: name: letsencrypt namespace: default spec: acme: # You must replace this email address with your own. # Let's Encrypt will use this to contact you about expiring # certificates, and issues related to your account. email: <yourname>@<yourcompany>.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: # Secret resource that will be used to store the account's private key. name: letsencrypt-private-key http01: {} EOF
Now that we have an issuer, we can create the Certificate for our domain:
cat <<EOF | kubectl apply -f - apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: le-certs namespace: default spec: secretName: le-certs issuerRef: kind: Issuer name: letsencrypt commonName: www.mycustomdomain.com dnsNames: - www.mycustomdomain.com acme: config: - http01: ingressClass: traefik domains: - www.mycustomdomain.com EOF
Once you apply this specification, cert-manager will contact Let's Encrypt and request a custom certificate for your domain. This involves several steps; you can follow the steps by using the following command:
kubectl describe certificates le-certs
Once the cert is created, it will be stored in the secret 'le-certs'.
Setting up a custom ingress
For our example, we'll assume we have a simple nginx service already running as 'nginx-service' that we want to expose at:
https://www.mycustomdomain.com/my_custom_service
Now that we have a cert, and the service running, we can put this all together with an Ingress. In our Ingress, we’ll specify the hostname to match and the TLS certificate we just created. By using the ‘host’ rule, our ingress will only be used for traffic that specifies the correct host header. We also specify the TLS configuration to use for this host. Finally, we specify the url path to use (/mycustomservice) and tell Traefik to strip that prefix so that our nginx app does not see it:
cat <<EOF | kubectl apply -f - apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx-mycustomdomain namespace: default annotations: kubernetes.io/ingress.class: traefik traefik.frontend.rule.type: PathPrefixStrip spec: tls: - hosts: - www.mycustomdomain.com secretName: le-certs rules: - host: www.mycustomdesign.com http: paths: - path: /my_custom_service backend: serviceName: nginx-service servicePort: 80 EOF
After applying all these, you should be able to point a browser or other HTTPS client at:
https://www.mycustomdomain.com/my_custom_service
References:
[1]: https://www.letsencrypt.org
[2]: https://docs.cert-manager.io/en/release-0.10/getting-started/index.html