Ingress rules in different Kubernetes namespaces
Solution ·In this article I want to show how an ingress controller in Kubernetes can be used to route traffic to workloads deployed in multiple namespaces.
The online doc for AKS deploys everything in the same namespace. Hence this article is a thin extension to the online doc.
The basic trick is to deploy the ingress rules in the same namespace the service they point to is.
This isn’t Azure / AKS specific, although this is what I use to demonstrate it, it is generic Kubernetes.
As usual, the code is in GitHub.
Installing NGinx
Assuming we are starting from a vanilla cluster, we first need to install an Ingress Controller.
Here we are going to use NGinx, but any Ingress Controller could support the rest of the code.
Details of this installation can be found in the AKS online documentation. The basic steps are:
# Create a namespace for your ingress resources
kubectl create namespace ingress-basic
# Add the official stable repository
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
# Use Helm to deploy an NGINX ingress controller
helm install nginx-ingress stable/nginx-ingress \
--namespace ingress-basic \
--set controller.replicaCount=2 \
--set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
--set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux
This installs the Ingress Controller in the namespace ingress-basic.
We can validate the Ingress Controller is installed:
kubectl get svc -ningress-basic
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-controller LoadBalancer 10.0.211.140 52.228.111.215 80:30725/TCP,443:30354/TCP 34m
nginx-ingress-default-backend ClusterIP 10.0.82.178 <none> 80/TCP 34m
Remember, an Ingress Controller is itself a Kubernetes service.
Installing services in different namespaces
We’re going to use one of the Azure samples charts to deploy services. Let’s add the charts to Helm Repo:
helm repo add azure-samples https://azure-samples.github.io/helm-charts/
Let’s create two namespaces:
kubectl create ns hello1
kubectl create ns hello2
Now let’s deploy the same chart twice in those two namespaces. We’ll pass different parameters in order to distinguish the deployment (the title is shown in the HTML):
helm install aks-helloworld azure-samples/aks-helloworld \
--namespace hello1 \
--set title="AKS Ingress Demo - 1" \
--set serviceName="aks-helloworld-one"
helm install aks-helloworld azure-samples/aks-helloworld \
--namespace hello2 \
--set title="AKS Ingress Demo - 2" \
--set serviceName="aks-helloworld-two"
We can validate services have been deployed in respective namespaces:
kubectl get svc -nhello1
kubectl get svc -nhello2
We can notice those services do not have external IPs.
Ingress Rules
We are going to expose the services through ingress rules:
kubectl apply -f ingress1.yaml
kubectl apply -f ingress2.yaml
The yaml files are on GitHub: ingress1.yaml & ingress2.yaml
A couple of things to notice about those ingress rules:
- They are deployed in the same namespace as the service they point to
- They use URL-based routing
The first observation makes the ingress rule work. The second is simply incidental. We could have used different routing mechanism ; this simply was the simplest to implement.
To put the rule in a namespace, we simply specified the namespace in the metadata section. For example, in ingress1.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-hello-world-1
namespace: hello1
Testing the solution
We can test those rules. First, let’s find the Public IP of the Ingress Controller. We have already seen it when we validated the deployment of the ingress controller:
kubectl get svc -ningress-basic
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-controller LoadBalancer 10.0.211.140 52.228.111.215 80:30725/TCP,443:30354/TCP 34m
nginx-ingress-default-backend ClusterIP 10.0.82.178 <none> 80/TCP 34m
In our case, the public IP is 52.228.111.215. We can find that public IP in the managed resource group (i.e. MC_… resource group).
If we browse to http://52.228.111.215 we should have a default backend - 404
message at the root. That is because there is no Ingress rule routing from the root.
If we browse at http://52.228.111.215/hello-world-1, we should see AKS Ingress Demo - 1
.
If we browse to http://52.228.111.215/hello-world-2, we should see AKS Ingress Demo - 2
.
There we have it. 2 services, in separate namespaces, exposed through one Ingress Controller.
Broken images
We can notice the image link are broken.
This is because both sites point to /static/...
for their images.
This makes that site a very bad candidate to use URL routing as we did. But it’s simpler to demo…
Summary
Simple demo for a simple concept.
As we mentioned in the introduction, the trick simply to deploy the ingress rules in the same namespace as the services they point to.
As we explored in a past article, we could also have multiple Ingress Controller within a cluster.
5 responses