Ingress: TLS (Transport Layer Security)
To secure an Ingress (HTTPS) we can do it by specifying a Secret that contains a TLS private key and certificate.
For production server we should use valid TLS certificates from Certificate Authority like letsencrypt.org, Cloudflare, and many others.
Generate Self-Signed Certificate
For local setup we can generate self-signed certificate.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=simple-go.mine/O=simple-org"
Create kubernetes secret
There are two ways to create a TLS secret. First is by using yaml file like this.
apiVersion: v1
kind: Secret
metadata:
name: secret-tls
type: kubernetes.io/tls
data:
tls.crt: <base64-encoded certificate>
tls.key: <base64-encoded key>
Or by using kubectl
, and I prefer the later because it's more convenient. So lets create a tls secret.
➜ kubectl create secret tls simple-tls --cert=tls.crt --key=tls.key
secret/simple-tls created
As usual check it using kubectl get
command.
➜ kubectl get secret
NAME TYPE DATA AGE
postgres-secret Opaque 2 42h
simple-tls kubernetes.io/tls 2 7s
Setup Ingress TLS
Now that we already have our tls secret ready. We can update the previous ingress definition to use the TLS secret we just created. Add the following tls configuration inside the spec
section.
tls:
- hosts:
- simple-go.mine
secretName: simple-tls
Lets apply and validate.
➜ kubectl apply -f ingress.yaml
ingress.networking.k8s.io/simple-ingress configured
➜ kubectl describe ingress simple-ingress
Name: simple-ingress
Labels: <none>
Namespace: default
Address: 192.168.49.2
Ingress Class: nginx
Default backend: <default>
TLS:
simple-tls terminates simple-go.mine
Rules:
Host Path Backends
---- ---- --------
simple-go.mine
/ simple-go:8080 (10.244.0.88:8080,10.244.0.89:8080,10.244.0.90:8080)
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 15s (x3 over 7h1m) nginx-ingress-controller Scheduled for sync
After our ingress updated we can test it using same curl in previous page.
➜ curl --resolve "simple-go.mine:80:127.0.0.1" -i http://simple-go.mine
HTTP/1.1 308 Permanent Redirect
Date: Fri, 31 Jan 2025 10:39:16 GMT
Content-Type: text/html
Content-Length: 164
Connection: keep-alive
Location: https://simple-go.mine
<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx</center>
</body>
</html>
As you can see above the request is being redirected to https which is port 443
.
Now lets try to curl using https
to port 443
. This time we add -k
or --insecure
to allow insecure connection because we are using self-signed certificate. If not we will get failed to verify certificate error.
➜ curl --resolve "simple-go.mine:443:127.0.0.1" -i -k https://simple-go.mine
HTTP/2 200
date: Fri, 31 Jan 2025 10:42:35 GMT
content-type: text/plain; charset=utf-8
content-length: 65
[{"id":1,"content":"Hello!"},{"id":2,"content":"Good Morning!"}]