Question 15 | Configure TLS on Ingress
Use context: kubectl config use-context workload-prod
In Namespace team-pink there is an existing Nginx Ingress resources named secure which accepts two paths /app and /api which point to different ClusterIP Services.
From your main terminal you can connect to it using for example:
HTTP: curl -v http://secure-ingress.test:31080/app
HTTPS: curl -kv https://secure-ingress.test:31443/app
Right now it uses a default generated TLS certificate by the Nginx Ingress Controller.
You're asked to instead use the key and certificate provided at /opt/course/15/tls.key and /opt/course/15/tls.crt. As it's a self-signed certificate you need to use curl -k when connecting to it.
Answer:
Investigate We can get the IP address of the Ingress and we see it's the same one to which secure-ingress.test is pointing to:
➜ k -n team-pink get ing secure
NAME CLASS HOSTS ADDRESS PORTS AGE
secure <none> secure-ingress.test 192.168.100.12 80 7m11s
➜ ping secure-ingress.test
PING cluster1-node1 (192.168.100.12) 56(84) bytes of data.
64 bytes from cluster1-node1 (192.168.100.12): icmp_seq=1 ttl=64 time=0.316 ms
# Now, let's try to access the paths /app and /api via HTTP:
➜ curl http://secure-ingress.test:31080/app
This is the backend APP!
➜ curl http://secure-ingress.test:31080/api
This is the API Server!
#What about HTTPS?
➜ curl https://secure-ingress.test:31443/api
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
➜ curl -k https://secure-ingress.test:31443/api
This is the API Server!
HTTPS seems to be already working if we accept self-signed certificated using -k. But what kind of certificate is used by the server?
➜ curl -kv https://secure-ingress.test:31443/api
...
* Server certificate:
* subject: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
* start date: Sep 28 12:28:35 2020 GMT
* expire date: Sep 28 12:28:35 2021 GMT
* issuer: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
...
It seems to be "Kubernetes Ingress Controller Fake Certificate".
Implement own TLS certificate First, let us generate a Secret using the provided key and certificate:
➜ cd /opt/course/15
➜ :/opt/course/15$ ls
tls.crt tls.key
➜ :/opt/course/15$ k -n team-pink create secret tls tls-secret --key tls.key --cert tls.crt
secret/tls-secret created
# Now, we configure the Ingress to make use of this Secret:
➜ k -n team-pink get ing secure -oyaml > 15_ing_bak.yaml
➜ k -n team-pink edit ing secure
# kubectl -n team-pink edit ing secure
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
...
generation: 1
name: secure
namespace: team-pink
...
spec:
tls: # add
- hosts: # add
- secure-ingress.test # add
secretName: tls-secret # add
rules:
- host: secure-ingress.test
http:
paths:
- backend:
service:
name: secure-app
port: 80
path: /app
pathType: ImplementationSpecific
- backend:
service:
name: secure-api
port: 80
path: /api
pathType: ImplementationSpecific
...
After adding the changes we check the Ingress resource again:
➜ k -n team-pink get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
secure <none> secure-ingress.test 192.168.100.12 80, 443 25m
#It now actually lists port 443 for HTTPS. To verify:
➜ curl -k https://secure-ingress.test:31443/api
This is the API Server!
➜ curl -kv https://secure-ingress.test:31443/api
...
* Server certificate:
* subject: CN=secure-ingress.test; O=secure-ingress.test
* start date: Sep 25 18:22:10 2020 GMT
* expire date: Sep 20 18:22:10 2040 GMT
* issuer: CN=secure-ingress.test; O=secure-ingress.test
* SSL certificate verify result: self signed certificate (18), continuing anyway.
...
We can see that the provided certificate is now being used by the Ingress for TLS termination.