-
Request Certificate: When the Ingress resource is applied and includes the appropriate annotations for Cert-Manager, Cert-Manager notices the request for a certificate and creates a Certificate resource in Kubernetes to manage it.
-
ACME Protocol: Cert-Manager then uses the ACME (Automated Certificate Management Environment) protocol to communicate with Let's Encrypt, requesting a certificate for the specified domain name.
-
Domain Validation: Let's Encrypt requires proof that you control the domain for which you're requesting a certificate. Cert-Manager automates this by creating a temporary Pod or configuring the Ingress (via a challenge, such as HTTP-01) to prove ownership of the domain to Let's Encrypt.
-
Certificate Issuance: Once domain validation is successful, Let's Encrypt issues the certificate to Cert-Manager, which then stores it in a Kubernetes Secret.
-
Certificate Injection: The Nginx Ingress controller is configured to use this Secret for TLS termination, meaning it decrypts incoming HTTPS traffic and forwards it to the appropriate backend service as HTTP.
- A record DNS name
- Ports open: 80 for HTTP and 443 for HTTPS
- Helm v3.12.1 or above
- Nginx Ingress controller
- Cert-Manager
Install Helm if it's not already installed in your Kubernetes cluster: Helm Installation Guide
Nginx Ingress Controller:
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespaceCert-Manager:
helm repo add jetstack https://charts.jetstack.io --force-update
helm repo update
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.14.2 \
--set installCRDs=trueAfter deploying the Nginx Ingress controller, it automatically receives an external IP address because its service is configured as a LoadBalancer by default. If the cluster uses MetalLB for its bare metal infrastructure, MetalLB assigns an external IP from its pool. Alternatively, in cloud-based environments, the external IP is provided by the cloud provider's load-balancing service. This external IP, allocated to the Ingress controller, becomes the destination for all incoming traffic, directing it to the appropriate services within the cluster.
kubectl get svc -n ingress-nginxOutput:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.96.56.90 10.220.2.210 80:31578/TCP,443:31600/TCP 20h
To verify ownership with Let's Encrypt, it's necessary to deploy a simple Pod running a small HTTP server to respond to the HTTP-01 challenge. In the example provided, we use a demo application named kuard (Kubernetes Up and Running) to fulfill this challenge. This involves deploying both a simple Pod and a corresponding service within the cluster.
Deployment:
kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/deployment.yamlService:
kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/service.yamlLet's Encrypt issues a token to your ACME client (Cert-Manager), which then places a file containing the token and a thumbprint of your account key on your web server at http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN>. After informing Let's Encrypt that the file is in place, Let's Encrypt attempts to retrieve it. To facilitate this retrieval, proper routing must be configured to allow Let's Encrypt access to the web server. Routing passes through Nginx and Krakend before reaching the kuard web server. Therefore, configuring the Krakend API gateway to direct traffic to the web server is a crucial first step.
To ensure the incoming request http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN> reaches the web server, add a path in Krakend as shown below.
Note: The kuard application is deployed in the default namespace http://kuard.default.svc.cluster.local. If deployed in a different namespace, adjust the FQDN accordingly, for example, http://kuard.<yournamespace>.svc.cluster.local.
To expose the Krakend service outside of the cluster, we define a rule in the Ingress resource to route all the incoming traffic to the Krakend service.
kubectl apply -f krakend-ingress.yamlVerify it was deployed:
kubectl get ingAn Issuer in Cert-Manager defines the method by which TLS certificates are requested. In Kubernetes, Issuers are scoped to a single namespace, allowing for namespace-specific certificate management. Alternatively, ClusterIssuer offers a cluster-wide solution, applicable across all namespaces.
In ncsrd Domain, we utilized an Issuer within the default namespace, as demonstrated in the example below:
Note: If opting to use a ClusterIssuer for cluster-wide certificate management, remember to annotate your Ingress resources with cert-manager.io/cluster-issuer to specify the ClusterIssuer to be used.
Creating the Issuer:
Execute the following command to apply the Issuer configuration:
kubectl apply -f issuer.yamlVerifying the Issuer Status:
To check the status and ensure the Issuer has been correctly set up, use:
kubectl describe issuer letsencrypt-prodCert-Manager will interpret the annotation (cert-manager.io/issuer: "letsencrypt-prod") from the Ingress resource and proceed to create a TLS certificate accordingly. You can verify the existence and status of requested certificates by:
kubectl get certificatesImportant Note on Secrets:
The Kubernetes Secret used in the Ingress must match the name of the secret defined in the certificate configuration. This ensures the Ingress controller can successfully retrieve and use the certificate for TLS.
Upon successful certificate issuance, Cert-Manager creates a Secret containing the certificate details, matching the secret name specified in the Ingress resource configuration.
To view the created Secret:
kubectl get secret ingress-tlsFollowing the steps outlined above, your domain name is now secured with TLS. This encryption ensures that the data transmitted to and from your domain is protected. You can verify the successful implementation of TLS in two ways:
From the Terminal:
Verify the TLS setup by executing a curl command that makes a verbose request to your domain, specifically requesting to use TLS version 1.2:
curl https://your-domain.example.com --verbose --tlsv1.2 --tls-max 1.2For example, to check the TLS configuration for the ncsrd domain ncsrd-mvp-domain.aeros-project.eu, use the following command:
curl https://ncsrd-mvp-domain.aeros-project.eu/types?details=true --verbose --tlsv1.2 --tls-max 1.2From the Browser:
https://ncsrd-mvp-domain.aeros-project.eu/types?details=true







