The Journey to Traefik Enterprise Edition: HTTPS for Everyone
Welcome to the fourth step of our journey towards Traefik Enterprise Edition.
Before jumping in, you should check the previous posts:
Today, we’ll focus on how to use TraefikEE with Let’s Encrypt to get HTTPS by default, for your application.
Create a Kubernetes Cluster with kops
Following the same steps as the previous blog post (“Create a cluster with kops”), start a kops cluster with one Kubernetes manager and three Kubernetes nodes:
$ export NAME=traefikee-demo.containous.cloud
$ export KOPS_STATE_STORE=s3://<YOUR BUCKET>
$ export ROUTE53_ZONE_ID=<ROUTE53_ZONE_ID>
$ export NB_MASTER_NODE=1
$ export NB_WORKER_NODE=3
$ kops create cluster \
--zones us-east-1a \
--dns-zone="${ROUTE53_ZONE_ID}" \
--node-size="t2.large" \
--master-count="${NB_MASTER_NODE}" \
--node-count="${NB_WORKER_NODE}" \
--yes \
"${NAME}"
After a few minutes, your cluster is started with four Kubernetes nodes:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-20-34-251.ec2.internal Ready node 2m v1.11.6
ip-172-20-49-209.ec2.internal Ready node 2m v1.11.6
ip-172-20-53-165.ec2.internal Ready node 2m v1.11.6
ip-172-20-56-217.ec2.internal Ready master 3m v1.11.6
Pick a Public Domain Name
In the previous blog post, we used a domain name generated by Amazon Web Services as the main entry point to reach our platform.
You cannot use this “generated” public hostname, because Let’s Encrypt has a “forbidden domains list.” Some domains are considered too risky, and any request for issuing certificates under these domains is automatically refused. It’s the case with domains in *.amazonaws.com.
To solve this challenge, let’s pick a custom public domain name. Any domain or sub-domain (like test.company.org
) can be used. You have to be able to create DNS records of type CNAME
on this domain.
(A voice in the background): I don’t want to pay for a domain used for evaluating a product. Maybe later if it goes further, but not now.
Containous: You can get free DNS using Dot-T-K, or even cheap ones using NameCheap.
For the next steps, we’ll pick the domain demo.containo.us
.
Install TraefikEE
Then, install a simple TraefikEE cluster, without dashboard, as we did on the previous blog post:
$ traefikeectl install \
--licensekey="$(cat /keybase/…/traefikee-license)" \
--kubernetes
...
✔ Installation successful
Once the installation succeeded, verify that the TraefikEE cluster is composed of six nodes, three control nodes and three data nodes, as expected:
$ traefikeectl list-nodes
...
Name Role
---- ----
traefikee-control-node-0 CONTROL NODE
data-node-traefikee-data-node-9ndbp DATA NODE
data-node-traefikee-data-node-vqgzr DATA NODE
traefikee-control-node-1 CONTROL NODE
traefikee-control-node-2 CONTROL NODE (Current Leader)
data-node-traefikee-data-node-5w66x DATA NODE
Configure the Domain DNS Records
The next step is to create a CNAME
DNS record, on the public domain name, pointing to the Load Balancer’s hostname, created during TraefikEE’s installation.
Get the load balancer’s public hostname with the following command (field EXTERNAL-IP):
$ kubectl get svc -n traefikee traefikee-lb
NAME TYPE EXTERNAL-IP
traefikee-lb LoadBalancer a16ff-456.us-east-1.elb.amazonaws.com
Then, create the DNS CNAME record to this hostname (choose a short TTL):
IN CNAME demo.containo.us a16ff-456.us-east-1.elb.amazonaws.com
The DNS propagation takes some time, due to the “TTL”. Verify that your computer can resolve the DNS name with tools asdig
, drill
or nslookup
:
$ dig CNAME demo.containo.us
...
;; QUESTION SECTION:
;demo.containo.us. IN CNAME
;; ANSWER SECTION:
demo.containo.us. 60 IN CNAME a16ff-456.us-east-1.elb.amazonaws.com.
;; Query time: 38 msec
;; SERVER: 212.224.255.252#53(212.224.255.252)
;; WHEN: Wed Feb 06 11:21:25 CET 2019
;; MSG SIZE rcvd: 136
Configure TraefikEE for HTTPS
Then, we configure TraefikEE to enable HTTPS and Let’s Encrypt for certificate on HTTPS. The configuration is the same as Traefik’s (check Traefik's documentation for more details):
### Configure 2 entrypoints for https and https
--entryPoints='Name:http Address::80 Redirect.EntryPoint:https' \
--entryPoints='Name:https Address::443 TLS' \
--defaultentrypoints=https,http \
### Enable ACME protocol for the HTTPS entry point
--acme.entryPoint=https \
### Set up ACME protocol for Let's Encrypt TLS-APLN-01 Challenge
[email protected] \
--acme.tlsChallenge \
### Tell Traefik to get certificate's hostname from backend's rules
--acme.onHostRule=true
(A voice in the background): When using Traefik with Let’s Encrypt, I often get certificates requests failures because of the rate limit on Let’s Encrypt side.
Containous: Traefik allows to test your HTTPS configuration with the “staging” environment, without rate limiting, but with untrusted certificates . It’s useful to validate configuration before switching to “production” certificates. Add the flag--acme.caServer='https://acme-staging-v02.api.letsencrypt.org/directory'
to the configuration.
Be careful! You cannot change the caServer unless you reinstall TraefikEE.
The main difference from using Traefik here, is that TraefikEE is a distributed system, so you need to specify the configuration after TraefikEE’s installation.
The traefikeectl
tool provides a command named deploy
to send any routing configuration to the TraefikEE cluster. You can read more on this topic on the reference documentation for routing configurations.
Now, let’s deploy the following configuration to the TraefikEE cluster and that’s all!
traefikeectl deploy --kubernetes \
--entryPoints='Name:http Address::80 Redirect.EntryPoint:https' \
--entryPoints='Name:https Address::443 TLS' \
--defaultentrypoints=https,http \
--acme.entryPoint=https \
[email protected] \
--acme.tlsChallenge \
--acme.onHostRule=true
(A voice in the background): Why is there a —-kubernetes
flag in this configuration?
Containous: This flag tells TraefikEE to watch for any Kubernetes Ingress. It’s the same directive as the one in Traefik.
Deploy an Application
As we previously did on the post, “A Tour of TraefikEE”, we deploy a test application based on https://github.com/containous/whoami.
You can reuse the same YAML file, but you have to change the directive host
in the ingress, and map it to your public domain name. I’m using the following one-line shell command for this:
$ curl --location --silent --show-error https://bit.ly/2WE5XFk \
| sed 's/localhost/demo.damienduportal.org/g' \
| kubectl apply -f -
deployment.extensions/whoami created
ingress.extensions/whoami created
service/whoami created
You can check that Kubernetes is using the right domain name by checking the ingress “whoami”:
$ kubectl get ingress whoami --namespace=traefikee
NAME HOSTS ADDRESS PORTS AGE
whoami demo.damienduportal.org 80 9m
The page https://demo.damienduportal.org/whoami is now, (after a few seconds, required for issuing certificates), securely served over HTTPS, with a valid certificate, issued by Let’s Encrypt:
If you try to access http://demo.damienduportal.org/whoami, then you are redirected to https://demo.damienduportal.org/whoami as expected.
That’s all for today, you are ready to use HTTPS on your applications!
You can now clean your kops cluster with:
kops delete cluster --name="${NAME}"
On the next post, “The Journey to Traefik Enterprise Edition: Smooth Operations,” we’ll focus on how to configure and operate TraefikEE remotely with the traefikeectl
command line.