Please read Provisioning Kubernetes Ingress(es) first, before continuing.
To expose an HTTP application running on MKE with a TLS certificate to either
inside or outside the DC/OS cluster, a Kubernetes
Ingress
resource must be created.
The need to enable TLS for a given Ingress resource is signaled by the presence
of a non-empty .spec.tls
field. The presence of that field will cause dklb to
enable HTTPS for the Ingress resource. The user is responsible for making sure
that the specified secrets contain certificates for all hosts specified in it.
EdgeLB will know how to pick the best certificate for a given host.
You can use the same options to customize your EdgeLB pool as described here.
By default dklb
will use port 80 for the HTTP frontend port and 443 for the
HTTPS frontend port. You can define custom ports via the .frontends.http.port
and .frontends.https.port
fields.
kubernetes.dcos.io/dklb-config: |
frontends:
http:
mode: [disabled|enabled|redirect]
port: <frontend-http-bind-port>
https:
port: <frontend-https-bind-port>
The .frontends.http.mode
field has the following semantics:
Value | Description |
---|---|
disabled |
Plain HTTP serving will be disabled altogether (i.e. the <cluster-name>:<namespace>:<name>:http EdgeLB frontend will be removed from the target EdgeLB pool). |
enabled |
Default. Plain HTTP serving will be enabled, and traffic will be sent to the intended backends. |
redirect |
The plain HTTP frontend will respond with 307 TEMPORARY REDIRECT to all requests. |
|
Changing the value of this field after the Ingress resource is created is supported, but may cause disruption (as the target EdgeLB pool will most likely be re-deployed).
|
Create an HTTP "echo" application and a service of type NodePort
$ kubectl run --restart=Never --image hashicorp/http-echo --labels app=http-echo-1,owner=dklb --port 80 http-echo-1 -- -listen=:80 --text='Hello from http-echo-1!'
$ kubectl expose pod http-echo-1 --port 80 --target-port 80 --type NodePort --name "http-echo-1"
Create a self-signed certificate for dummy domain foo.bar.com and store it in a
Kubernetes secret. The Kubernetes secret is called foo-secret
.
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=foo.bar.com"
$ kubectl create secret tls foo-secret --key tls.key --cert tls.crt
Create a Kubernetes ingress with TLS enabled. The TLS Secret was stored in
foo-secret
in the previous step. The EdgeLB pool is configured to disable HTTP
port and setup HTTPS on port 8443.
$ kubectl create -f - <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: foo
namespace: default
annotations:
kubernetes.io/ingress.class: edgelb
kubernetes.dcos.io/dklb-config: |
name: foo
frontends:
http:
mode: disabled
https:
port: 8443
labels:
owner: dklb
spec:
tls:
- hosts:
- foo.bar.com
secretName: foo-secret
rules:
- host: "foo.bar.com"
http:
paths:
- backend:
serviceName: http-echo-1
servicePort: 80
EOF
Wait for ingress to have an IP address assigned.
$ kubectl get ingress foo
NAME HOSTS ADDRESS PORTS AGE
foo foo.bar.com <AWS PRIVATE IP>,<AWS PUBLIC IP> 80, 443 57s
Confirm EdgeLB created the pool and that it’s running.
$ dcos edgelb list
NAME APIVERSION COUNT ROLE PORTS
foo V2 1 slave_public
$ dcos edgelb status foo
NAME TASK ID STATE
edgelb-pool-0-server dcos-edgelb.pools.foo__edgelb-pool-0-server__<RANDOM UUID> TASK_RUNNING
Check EdgeLB is using the self-signed certificate to serve on port 8443. Notice
the CN is foo.bar.com
.
$ openssl s_client -showcerts -servername server -connect <AWS PUBLIC IP ADDRESS>:8443
CONNECTED(00000003)
depth=0 CN = foo.bar.com
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = foo.bar.com
verify return:1
---
Certificate chain
0 s:/CN=foo.bar.com
i:/CN=foo.bar.com
Check you can access the Kubernetes service via the EdgeLB pool with TLS enabled and validate the self-signed certificate.
$ curl --cacert tls.crt --resolve foo.bar.com:8443:<AWS_PUBLIC_IP_ADDRESS> https://foo.bar.com:8443/
Hello from http-echo-1!
Cleanup of the Kubernetes pods, services and ingresses and of the target EdgeLB pool can be done by running the following commands:
$ kubectl delete ingress --selector "owner=dklb"
$ kubectl delete svc --selector "owner=dklb"
$ kubectl delete pod --selector "owner=dklb"
$ kubectl delete secret foo-secret
The dklb-foo
EdgeLB pool will be automatically deleted.