Step 6: Deploy a sample application
In one of our previous Labs, we containerized a simple application (learning-tracker) and deployed it first via Docker and then via Kubernetes. We will use the same application here to demonstrate how to use cert-manager to request a TLS certificate for it.
Therefore, let's create a new namespace for our application, deploy the application in it and create a Service for it:
kubectl create namespace learning-tracker
kubectl create deployment learning-tracker -n learning-tracker --image ghcr.io/tsclabs-eu/learning-tracker:v1.0.5
kubectl expose -n learning-tracker deployment learning-tracker --port 3000
Take a second to verify that the pod is running and the service is created:
kubectl get all -n learning-tracker
kubectl get ep -n learning-tracker
These two commands should show you that the pod is running and the service has an endpoint. In the next step, we will create an Ingress resource for our application.
Create an Ingress resource
To create an Ingress resource for our application, we will create a new manifest file called learning-tracker-ingress.yaml with the following content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: learning-tracker
annotations:
cert-manager.io/cluster-issuer: <your-cluster-issuer>
spec:
ingressClassName: nginx
rules:
- host: <your-dns-name>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: learning-tracker
port:
number: 3000
tls:
- hosts:
- <your-dns-name>
secretName: learning-tracker-cert
There are lots of things going on in this manifest, so let's go through it step by step. First, we define the Ingress resource and give it a name. Then, we add some annotations to configure the Ingress Controller and cert-manager. The cert-manager.io/(cluster-)issuer annotation is used to specify which Issuer or ClusterIssuer should be used to request the TLS certificate. Please replace <your-cluster-issuer> with the name of the Issuer or ClusterIssuer you created before. The host field specifies the domain name for the Ingress resource. Please replace <your-dns-name> with the domain name you want to use for your application. The tls section is used to specify that we want to use TLS for this Ingress resource and the name of the secret where the certificate will be stored.
External DNS will automatically create the necessary DNS records for the Ingress resource if you are using the domain we configured before. Therefore, make sure to use the same domain name in the Ingress resource.
Now, we can apply this manifest to our cluster:
kubectl apply -n learning-tracker -f learning-tracker-ingress.yaml
Verification
To verify that everything is working as expected, you can check the Ingress resource:
kubectl get ingress -n learning-tracker
You should see the Ingress resource with the address of your Ingress Controller, nginx as the class and the domain name you specified. After some time, you should also see the DNS record created in your DNS provider.
After the DNS record is created, let's check if the TLS certificate is issued. You can check the status of the Certificate resource using the following command:
kubectl describe certificate -n learning-tracker
When you see that the certificate is ready, you can access your application using the domain name you specified in the Ingress resource. You should see that the connection is secure and a valid TLS certificate is used.
Please note that in this lab we used the Let's Encrypt staging environment to avoid hitting rate limits during testing. Certificates issued by the staging environment are not trusted by browsers. For production use, make sure to switch to the production environment by changing the server field in the ClusterIssuer manifest to https://acme-v02.api.letsencrypt.org/directory.
