Installing Cert-Manager and NGINX Ingress with Let’s Encrypt on Kubernetes

Hakan Bayraktar
4 min readSep 18, 2024

--

In this guide, we’ll walk through setting up Cert-Manager and NGINX Ingress on Kubernetes with Let’s Encrypt to enable automated TLS certificate management. This tutorial is tested on DigitalOcean and will help you ensure secure HTTPS connections for your applications.

What is Ingress and Why Use It?

Ingress is a Kubernetes resource that manages external access to services within a cluster, typically HTTP and HTTPS traffic. Using Ingress, you can:

  • Manage complex routing rules.
  • Secure your applications with SSL/TLS.
  • Consolidate access to multiple services behind a single external IP address.

Cert-Manager automates the process of obtaining and renewing TLS certificates from providers like Let’s Encrypt. It integrates seamlessly with Ingress controllers (e.g., NGINX) to handle certificate management automatically.

1. Installing Helm

Helm is a package manager for Kubernetes that simplifies the deployment and management of applications. First, we’ll install Helm.

curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

Verify the installation:

helm version

2. Installing NGINX Ingress Controller

The NGINX Ingress Controller manages HTTP and HTTPS traffic within Kubernetes. We’ll install it using Helm.

Add the Helm repository:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

Install the NGINX Ingress Controller:

helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace

Check the status of the Ingress Controller:

kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx

3. Deploying a Test Application

We’ll create a simple application and service within Kubernetes to test the Ingress setup.

Create the deployment:

# base-app-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
labels:
app: example
spec:
replicas: 2
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: example-app
image: hashicorp/http-echo
args:
- "-text=Hello from Kubernetes"
ports:
- containerPort: 5678

Save this file as base-app-deploy.yaml and apply it:

kubectl apply -f base-app-deploy.yaml

Create the service:

# base-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP

Save this file as base-svc.yaml and apply it:

kubectl apply -f base-svc.yaml

4. Creating an HTTP Ingress

We’ll configure an Ingress resource to route traffic to our application.

Create the Ingress resource:

# base-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: test.devopslearnwith.us
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80

Save this file as base-ingress.yaml and apply it:

kubectl apply -f base-ingress.yaml

Configure DNS:

To get the external IP address of the Ingress, run:

kubectl get svc -n ingress-nginx

Add the EXTERNAL-IP address to your domain’s DNS records as an A record.

Test HTTP Access:

Visit http://test.devopslearnwith.us to ensure your application is accessible.

5. Installing Cert-Manager

Cert-Manager handles the automatic issuance and renewal of TLS certificates.

Add and update the Helm repository:

helm repo add jetstack https://charts.jetstack.io
helm repo update

Install Cert-Manager:

helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--version v1.12.0 \
--set installCRDs=true

Verify Cert-Manager is running:

kubectl get pods -n cert-manager

6. Setting Up Let’s Encrypt ClusterIssuer

Define a ClusterIssuer to obtain certificates from Let’s Encrypt.

Create the ClusterIssuer resource:

# cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx

Save this file as cluster-issuer.yaml and apply it:

kubectl apply -f cluster-issuer.yaml

7. Setting Up HTTPS Ingress

Update the Ingress resource to support HTTPS.

Create the updated Ingress resource:

# tls-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- test.devopslearnwith.us
secretName: example-tls
rules:
- host: test.devopslearnwith.us
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80

Save this file as tls-ingress.yaml and apply it:

kubectl apply -f tls-ingress.yaml

Verify ingress:

Verify Cert-Manager is issuing certificates:

kubectl describe certificate example-tls
kubectl get cert

Test HTTPS Access:

Visit https://test.devopslearnwith.us to confirm that the SSL certificate is successfully installed.

With this guide, you can confidently set up Cert-Manager and NGINX Ingress on Kubernetes with automated TLS certificates using Let’s Encrypt. This configuration ensures secure HTTPS connections and simplifies certificate management for your applications.

--

--