How to configure TLS termination using a local CA¶
This guide shows how to configure TLS termination for Traefik using a self-signed certificate issued by a stand-in local certificate authority.
flowchart LR
subgraph Target cluster
rootca["self-signed-certificates"] ---|tls-certificates| trfk
trfk[Traefik] ---|ingress-per-app| alertmanager
trfk[Traefik] ---|ingress-per-unit| prometheus
trfk[Traefik] ---|traefik-route| grafana
end
curl -.-|via external_hostname| trfk
Note
This guide assumes you have a Juju controller bootstrapped on a k8s cloud that is ready to use. A typical setup using snaps can be found in the Juju docs. Follow the instructions there to install Juju and K8s.
Configure K8s¶
Follow the Getting started guide to install and bootstrap k8s, then configure the default load balancer.
Deploy the apps¶
Deploy Traefik, self-signed-certificates to function as a root CA, and Alertmanager, Prometheus, and Grafana, which use Traefik ingress.
First, create a new model:
juju add-model tls-demo
Next, save the following bundle as tls-demo.yaml:
---
bundle: kubernetes
name: traefik-tls-demo
applications:
traefik:
charm: 'traefik-k8s'
scale: 1
trust: true
channel: 'edge'
options:
external_hostname: 'demo.local'
alertmanager:
charm: 'alertmanager-k8s'
scale: 1
trust: true
channel: 'edge'
prometheus:
charm: 'prometheus-k8s'
scale: 1
trust: true
channel: 'edge'
grafana:
charm: 'grafana-k8s'
scale: 1
trust: true
channel: 'edge'
ca:
charm: 'self-signed-certificates'
scale: 1
channel: 'edge'
relations:
- [traefik:ingress-per-unit, prometheus:ingress]
- [traefik:traefik-route, grafana:ingress]
- [traefik:ingress, alertmanager:ingress]
- [traefik:certificates, ca:certificates]
Finally, deploy the local bundle:
juju deploy --trust ./tls-demo.yaml
Reach an application’s endpoint with ingress¶
HTTP¶
First, obtain the ingress URL by using a Traefik action:
juju run traefik/0 show-proxied-endpoints
The terminal output should look something like:
Running operation 5 with 1 task
- task 6 on unit-traefik-0
Waiting for task 6...
proxied-endpoints: '{
"prometheus/0": {"url": "http://demo.local:80/tls-demo-prometheus-0"},
"alertmanager": {"url": "http://demo.local:80/tls-demo-alertmanager"}
}'
Now obtain Traefik’s IP:
TRAEFIK_IP=$(\
juju status --format json traefik \
| jq -r ".applications.traefik.address"\
)
Use the ingress URL with the application’s HTTP API endpoint:
user@host:~$ curl --resolve "demo.local:80:$TRAEFIK_IP" \
> http://demo.local:80/tls-demo-alertmanager/-/ready
OK
user@host:~$ curl --resolve "demo.local:80:$TRAEFIK_IP" \
> http://demo.local:80/tls-demo-prometheus-0/-/ready
Prometheus Server is Ready.
HTTPS¶
Save the certificate locally:
juju show-unit --format json traefik/0 \
| jq -r '."traefik/0"."relation-info"[3]."application-data".certificates' \
| jq -r '.[1].certificate' \
> /tmp/local.cert
Save Traefik’s IP:
TRAEFIK_IP=$(\
juju status --format json traefik \
| jq -r ".applications.traefik.address"\
)
Curl the endpoint:
curl --resolve demo.local:443:$TRAEFIK_IP \
--fail-with-body \
--capath /tmp \
--cacert /tmp/local.cert \
https://demo.local/tls-demo-alertmanager/-/ready
This should return:
OK