Deploying HTTPS with Kubernetes Nginx Ingress and Cert Manager

Introduction

This article will guide you through using Nginx Ingress Controller and Cert Manager on Kubernetes (K8s) to automatically issue TLS (Transport Layer Security) certificate. To follow along, you'll need:

Ingress

Ingress is a Kubernetes resource used to manage external access to Services within a cluster. It acts like a traffic router, allowing you to define routing configurations to efficiently manage incoming traffic to Services.

Ingress Controller

An Ingress Controller is a distinct component from Ingress itself. There are various types of Ingress Controllers, each capable of different deployments. However, their main function is to manage and deploy according to Ingress rules. When requests reach Ingress, the Ingress Controller uses these defined rules to route traffic to the respective Services. In this article, I'll demonstrate using the Nginx Ingress Controller.

Cert-Manager

Cert-Manager is a tool used to secure Ingress by automatically creating and renewing SSL/TLS certificates before they expire, at no cost.


Implementation Steps

Firstly, you need to initialize a K8s cluster. Here, I'm using GCP, so execute the following command:

gcloud container clusters create {cluster name}

# ex:
gcloud container clusters create k8s-cluster

Note that the above command works if you have already set the default project ID and region. Check out this article for more specific options to initialize GKE.


Next, use Helm to install the Nginx Ingress Controller and cert-manager along with the necessary configurations.

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade --install nginx-ingress ingress-nginx/ingress-nginx -n ingress-nginx --create-namespace --set controller.publishService.enabled=true

helm repo add jetstack https://charts.jetstack.io
helm upgrade --install cert-manager jetstack/cert-manager -n cert-manager --create-namespace --set crds.enabled=true --set global.leaderElection.namespace=cert-manager


Check if the resources were successfully installed as follows:



Next, create a deployment.yml file to define the main resources for the application.

apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-name
spec:
replicas: 1
selector:
matchLabels:
app: label-name
template:
metadata:
labels:
app: label-name
spec:
restartPolicy: Always
containers:
- name: express-ts
image: express-ts # replace with your image
ports:
- containerPort: 3000
name: deployment-port
---
apiVersion: v1
kind: Service
metadata:
name: service-name
spec:
selector:
app: label-name
ports:
- protocol: TCP
port: 80 # port service
targetPort: deployment-port # port pod
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: any-email@gmail.com # could be use any email
privateKeySecretRef:
name: letsencrypt-production
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-name
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
spec:
ingressClassName: nginx
tls:
- hosts:
- your-domain.com # replace with your domain
secretName: secret-name
rules:
- host: your-domain.com # replace with your domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-name
port:
number: 80
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: certificate-name
namespace: default
spec:
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
secretName: secret-name
dnsNames:
- your.ddns.com

Explain:

  • Deployment is used to deploy the application. You can replace the Docker image in the image field with the one you want to use, or follow this guide to build the Docker image I used in this example.
  • The Service is set to the default type, ClusterIP. I didn’t use LoadBalancer because the Nginx Ingress Controller already has a LoadBalancer service.
  • ClusterIssuer contains the configuration info for cert-manager to create HTTPS certificates. In this case, it uses the Let's Encrypt server and the Nginx Ingress Controller to create the private key secret.
  • Ingress registers the TLS certificate with your domain and sets up rules to direct traffic to the Service.
  • For the Certificate, make sure to specify the correct namespace (here, it’s the default namespace) and set the DNS names according to your domain provider.


Apply the configurations to create the resources.

kubectl apply -f deployment.yml

Note: I've defined all resources in a single file for simplicity, but in practice, you should separate each resource into individual YAML files for better management.


When resources are successfully created:



Next, to see the IP address information from Ingress, do the following:


Then, access the domain management dashboard according to your service provider to point your domain to that IP address.

To check if the certificate has been successfully issued:


The application is deployed with an HTTPS TLS certificate.



See you in the next articles!

Comments

Popular posts from this blog

Kubernetes Practice Series

NodeJS Practice Series

Docker Practice Series

React Practice Series

Sitemap

Setting up Kubernetes Dashboard with Kind

Deploying a NodeJS Server on Google Kubernetes Engine

DevOps Practice Series

Create API Gateway with fast-gateway

A Handy Guide to Using Dynamic Import in JavaScript