Exposing Container Applications in AKS: Nginx Ingress Controller

Sijomon ND
5 min readFeb 17, 2024

--

PART-2

its only one-way traffic today

Introduction

Exposing an application container in Kubernetes is about making your application running in a container accessible and reachable to users or other services within and beyond the Kubernetes cluster. Configuring how you expose your application requires careful consideration. Kubernetes offers mechanisms like Services, Ingress and Load Balancers to guide incoming traffic to your containerized application securely and efficiently. This series will focus on a few methods of exposing applications in AKS clusters.

Part 1 of the series, we explored connecting to an application via The Azure Load Balancer. I showed you how to up service for ALB also, we discussed about some Pros and Cons of having a L4 Load-balancer.

In Part 2, I will provide an overview of the ingress controllers and how they can be leveraged for possible use cases and limitations in an AKS cluster. While there are many ingress controller options I will be using NGINX Ingress Controller.

Part 3 provides a similar walk-through on AGIC which helps AKS to utilize Azure’s own Application Gateway Layer& Load-balancer to expose your application to the Internet.

I have added all the artifacts that we are going to use below gist

https://gist.github.com/sijomon/5e34da8281610ddc2ca8ce097d2d9f22

Nginx Ingress Controller

An Ingress is an object that allows access to your Kubernetes services from outside the Kubernetes cluster. You configure access by creating a collection of rules that define which inbound connections reach which services.

This lets you consolidate your routing rules into a single resource. For example, you might want to send requests to example.com/api/v1/ to an api-v1 service, and requests to example.com/api/v2/ to the api-v2 service. With an Ingress, you can easily set this up without creating a bunch of LoadBalancers or exposing each service on the Node.

  1. Deploy the NGINX Ingress Controller to your AKS cluster. You can use Helm or Nginx to install it.

Nginx

kubectl apply -f   https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

If you are a Helm user, you can deploy the ingress controller using the community Helm chart. Deploy the helm chart. It will create the namespace ingress-nginx if not present.

helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace

Verify the helm release

helm list -n ingress-nginx

2. Check that Nginx is all set up correctly

kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-jzfwn 0/1 Completed 0 32s
ingress-nginx-admission-patch-jb4jh 0/1 Completed 0 31s
ingress-nginx-controller-79d66f886c-6bkk2 1/1 Running 0 32s

This has set up the Nginx Ingress Controller. Now, we can create Ingress resources in our Kubernetes cluster and route external requests to our services. Look for logs in your ingress controller with the command you will see

3. Check the NGINX Ingress controller has been assigned a public IP address

kubectl get service ingress-nginx-controller -n ingress-nginx
NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller LoadBalancer 10.0.215.232 20.227.161.25 80:31058/TCP,443:32169/TCP 5m1s

4. Browsing to this IP address will show you the NGINX 404 page. This is because we have not set up any routing rules for our services yet and no application is listening at the moment.

5. Now we will set up two web apps, and route traffic between them using NGINX.

demo-one.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-one
spec:
replicas: 1
selector:
matchLabels:
app: demo-one
template:
metadata:
labels:
app: demo-one
spec:
containers:
- name: demo-one
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "Welcome to APPLE"
---
apiVersion: v1
kind: Service
metadata:
name: demo-one
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: demo-one

demo-two.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-two
spec:
replicas: 1
selector:
matchLabels:
app: demo-two
template:
metadata:
labels:
app: demo-two
spec:
containers:
- name: demo-two
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "Welcome to Orange"
---
apiVersion: v1
kind: Service
metadata:
name: demo-two
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: demo-two

6. Apply the two configuration files to setup the apps

kubectl apply -f demo-one.yml -n nginx-ingress
deployment.apps/demo-one created
service/demo-one created
kubectl apply -f demo-two.yml -n nginx-ingress
deployment.apps/demo-two created
service/demo-two created

7. Check the new pods are running

kubectl get pods -n  nginx-ingress
NAME                        READY   STATUS    RESTARTS   AGE
demo-one-757c5f94b9-7grrk 1/1 Running 0 2m19s
demo-two-847cdc6695-cq5q7 1/1 Running 0 2m8s

8. Now let's Setup the Ingress to route traffic between the two apps

Create a file named nginx-ingress.yaml

please note the value spec.ingressClassName this makes sure your ingessclass is deployed nginx.

you can get the value by exploring

kubectl get ingressclass
kubecetl describe ingressclass ${ingressclassname
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /apple
pathType: Prefix
backend:
service:
name: demo-one
port:
number: 80
- path: /orange
pathType: Prefix
backend:
service:
name: demo-two
port:
number: 80

9. Create ingress

kubectl apply -f nginx-ingress.yml -n nginx-ingress
ingress.networking.k8s.io/demo-ingress created

10. Check the Public IP address

kubectl get service ingress-nginx-controller -n ingress-nginx
NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller LoadBalancer 10.0.215.232 20.227.161.25 80:31058/TCP,443:32169/TCP 8h

11. Browse to ${external-IP}/apple

12. Browse to ${external-IP}/orange

Cool It's working, we learnt to save some bucks. But I know what you are thinking now. Isn’t it?, still insecure.

Nginx ingress supports SSL/TLS termination but it is not inbuilt. We should be using another application to manage your certificates for example Letsencrypt with cert-manager is a good option.

Continue PART3

--

--