Deploying a Kubernetes App with Nginx Ingress and Cert-Manager/Let's Encrypt
Deploying a Web App in Azure Kubernetes Services (AKS) using Github CI/CD
Deploying applications in Kubernetes with proper networking and security is crucial in modern software development. In this tutorial, we’ll walk through deploying a sample “Hello World” application using Nginx Ingress for routing and Cert-Manager for automatic HTTPS certificates from Let’s Encrypt. Also, to deploy it we will use Github Actions.
Prerequisites
Before we start, make sure you have the following prerequisites:
- A Kubernetes cluster (you can use Azure Kubernetes Service (AKS) for this tutorial)
- A Docker Hub account (or any other Docker registry)
- A GitHub repository for your application
Step 1: Create a Simple “Hello World” Rust App
For this tutorial, we’ll use a basic “Hello World” application in Rust. Create a file named main.rs
with the following code:
use actix_web::{web, App, HttpServer, Responder};
async fn hello() -> impl Responder {
"Hello, Kubernetes!"
}
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().route("/", web::get().to(hello)))
.bind("0.0.0.0:8080")?
.run()
.await
}
Step 2: Dockerize and Push the Rust App to Docker Hub
To deploy our Rust app in Kubernetes, we need to containerize it and push it to a container registry. Follow these steps: 1 - Create the Dockerfile
FROM rust:1.55 AS builder
WORKDIR /app
COPY main.rs .
RUN cargo build --release
FROM debian:buster-slim
COPY --from=builder /app/target/release/app /app
CMD ["/app"]
2 - Build a Docker image for your Rust app:
docker build -t your-dockerhub-username/hello-kubernetes-rust:latest .
3 - Push the image to Docker Hub:
docker push your-dockerhub-username/hello-kubernetes-rust:latest
Step 3: Install the Ingress Controller:
Run the following command to install the Nginx Ingress controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/cloud/deploy.yaml
Create an ingress.yaml file with the following content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-world-ingress
spec:
rules:
- host: your-app-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-world-service
port:
number: 80
Step 4: Install Cert-Manager
Cert-Manager is a Kubernetes addon that automates the management and issuance of TLS certificates. To install it, follow these steps:
Run the following commands to install Cert-Manager:
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml
Create an issuer.yaml file with the following content:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: your-email@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
Here we are using the prod server of letsencrypt, you can use the staging one.
Step 5: Set Up Azure Service Principal
For secure deployments, we’ll use an Azure Service Principal to authenticate with AKS. 1 - Create a new Service Principal:
az ad sp create-for-rbac --name "YourAppServicePrincipal" --skip-assignment
2 - Note down the appId (Client ID) and password (Client Secret) from the output.
Step 6: Configure Secrets in GitHub
In your GitHub repository, navigate to “Settings” > “Secrets” and add the following secrets:
AZURE_SP_CLIENT_ID:
The appId (Client ID) of your Service Principal.AZURE_SP_CLIENT_SECRET:
The password (Client Secret) of your Service Principal.
Step 7: Set Up GitHub CI/CD
Create a .github/workflows/deploy.yml file with the following content to set up the CI/CD pipeline
name: Deploy Kubernetes App
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Azure CLI
uses: azure/setup-az-cli@v1
with:
install-zsh: true # Install Azure CLI in the Zsh shell
- name: Authenticate to Azure using Service Principal
run: az login --service-principal -u $ -p $ --tenant $
- name: Get AKS credentials
run: az aks get-credentials --resource-group your-aks-resource-group --name your-aks-cluster-name
- name: Configure kubectl
run: echo "$KUBECONFIG" > $HOME/.kube/config
- name: Deploy to Kubernetes
run: |
kubectl apply -f kubernetes/deployment.yaml
kubectl apply -f kubernetes/service.yaml
kubectl apply -f kubernetes/ingress.yaml
Here is the example of deployment.yaml :
# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world-deployment
spec:
replicas: 3
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: your-dockerhub-username/hello-kubernetes-rust:latest
ports:
- containerPort: 8080
Your app should be now deserved in HTTPS using letsencrypt certificate. More configuration is needed for an environment prod-ready of course.
Conclusion
By combining Nginx Ingress, Cert-Manager, and GitHub Actions, you’ve successfully set up a CI/CD pipeline for deploying your Kubernetes application written in Rust. This approach enhances security and automates deployment.