Enable ingress with TLS for a service in K8s
If you can remember, in our last blog post, we have access a simple service deployed inside a Kubernetes environment. But we did it using a LoadBalancer service type. Since we have tested on Docker Desktop, we were able to reach it using localhost with a specified port `http://localhost:8081/hi`. Today what we are going to do is, access with a given FQDN without specifying port but with a trusted certificate.
To start with, let me explain about my development environment that I used for this post.
- Docker Desktop for Mac : Version 4.9.0
- Kubernetes version (Client & Server) : v1.24.0
- Helm version : v3.9.0
- Openssl version : LibreSSL 2.8.3
I’m using the same hello-go Helm chart and following are the changes that I’ve done in values.yaml
service:
type: ClusterIPingress:
enabled: true
className: "nginx"
annotations: {}
hosts:
- host: anujarosha.local
paths:
- path: /
pathType: ImplementationSpecific
Make sure you have an entry for your host mentioned above in your /etc/hosts file.
▶ cat /etc/hosts | tail -2
127.0.0.1 anujarosha.local
Once you try to load the web service with your browser, you will get something like below.
Depending on your browser, you may not able to proceed at all (Ex. Google chrome on my Mac) or may able to proceed after accepting warning (Ex. Firefox on my Mac). Even though you bypass the warning with the Firefox, it will show that your connection is not secure.
One thing sorted out at this point is, we no longer need to type the port in the web URL. That tell us ingress is in action but not the TLS part. Lets add the TLS configuration as well. In order to do that, you should have a Self Signed Certificate.
Creating a Self Signed Certificate
Creating a self signed certificate is not part of this post, but I’ll give you the commands that I used to create necessary certificates. First you need to create rootCA.key and rootCA.crt. You can change the parameters appropriately, specially the FQDN.
openssl req -x509 \
-sha256 -days 356 \
-nodes \
-newkey rsa:2048 \
-subj "/CN=anujarosha.local/C=US/L=San Fransisco" \
-keyout rootCA.key -out rootCA.crt
Above rootCA.crt, you need to add to your Key Chain. For Mac, users, you can do it by double click on that file. Then in the Keychain Access app, make that certificated trusted.
Next, create the Server Private Key using OpenSSL.
openssl genrsa -out server.key 2048
Then, create Certificate Signing Request (CSR) configuration
cat > csr.conf <<EOF
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn[ dn ]
C = US
ST = California
L = San Fransisco
O = AnujAroshA
OU = AnujAroshA Backend
CN = anujarosha.local[ req_ext ]
subjectAltName = @alt_names[ alt_names ]
DNS.1 = anujarosha.local
DNS.2 = www.anujarosha.local
IP.1 = 192.168.1.5
IP.2 = 192.168.1.6EOF
As the next step, generate Certificate Signing Request (CSR) using server private key.
openssl req -new -key server.key -out server.csr -config csr.conf
After that, create an external file
cat > cert.conf <<EOFauthorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names[alt_names]
DNS.1 = anujarosha.localEOF
And then, generate SSL certificate with self signed CA
openssl x509 -req \
-in server.csr \
-CA rootCA.crt -CAkey rootCA.key \
-CAcreateserial -out server.crt \
-days 365 \
-sha256 -extfile cert.conf
Now, back to the Kubernetes, where we need to create a TLS secret with the self signed certificates that we have created.
kubectl create secret tls anujarosha-tls \
--namespace my-app \
--key server.key \
--cert server.crt
Then, we can enabled TLS in the values.yaml like below.
tls:
- secretName: anujarosha-tls
hosts:
- anujarosha.local
Then you can upgrade your Helm chart to apply the changes.
helm upgrade hello-go ./helm -n my-app --description "Enable TLS secret"
Now you should be able to see the very first screen shot that I’ve shared with you, which is accessing a service inside the Kubernetes cluster with ingress and valid TLS.
That’s all for this post and we will meet with another exciting post 👋