Setup Nginx Ingress Controller on Kubernetes Cluster.
When would you use this?
Ingress is probably the most powerful way to expose your services, but can also be the most complicated. There are many types of Ingress controllers, from the Google Cloud Load Balancer, Nginx, Contour, Istio, and more. There are also plugins for Ingress controllers, like the cert-manager, that can automatically provision SSL certificates for your services.
Ingress is the most useful if you want to expose multiple services under the same IP address, and these services all use the same L7 protocol (typically HTTP). You only pay for one load balancer if you are using the native GCP integration, and because Ingress is “smart” you can get a lot of features out of the box (like SSL, Auth, Routing, etc)
Ingress is split into two main parts — Ingress resources and ingress controller
Ingress Resources:
Ingress Resources defines how you want the requests to the services to be routed. It contains the main routing rules.
Ingress controller:
The Ingress Controller is responsible for routing requests to the appropriate services within the Kubernetes cluster. How an Ingress Controller executes this task, is not explicitly defined by Kubernetes. Thus an Ingress Controller can handle requests in a way that works best for the cluster.
The Ingress Controller is responsible to monitor the Kubernetes cluster for any new Ingress resources. Based on the Ingress resource, the Ingress Controller will set up the required infrastructure to route requests accordingly.
Deploy the NGINX Ingress Controller for Kubernetes
1. To download the NGINX Ingress Controller for Kubernetes, run the following command:
git clone https://github.com/nginxinc/kubernetes-ingress.git
2. To choose the directory for deploying the Ingress Controller, run the following command:
cd kubernetes-ingress/deployments/
3. To create a dedicated namespace, service account, and TLS certificates (with a key) for the default server, run the following commands:
kubectl apply -f common/ns-and-sa.yaml
kubectl apply -f common/default-server-secret.yaml
4. To create a ConfigMap for customizing your NGINX configuration, run the following command:
kubectl apply -f common/nginx-config.yaml
5. To configure role-based access control (RBAC), create a ClusterRole, and then bind the ClusterRole to the service account from step 3. For example:
kubectl apply -f rbac/rbac.yaml
6. To deploy the Ingress Controller, run the following commands.
kubectl apply -f deployment/nginx-ingress.yaml
kubectl get pods --namespace=nginx-ingress
You receive output similar to the following:
NAME READY STATUS RESTARTS AGE
nginx-ingress-fb4f4b44c-xmq6z 1/1 Running 0 3d7h
Access the Ingress Controller and run your application.
1. To apply your configuration, run the following commands:
kubectl apply -f service/loadbalancer-aws-elb.yamlkubectl get svc --namespace=nginx-ingress
You receive output similar to the following:
2. To configure NGINX to use the PROXY protocol so that you can pass proxy information to the Ingress Controller, add the following keys to the Nginx-config.yaml file from step 4. For example:
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
namespace: nginx-ingress
data:
proxy-protocol: "True"
real-ip-header: "proxy_protocol"
set-real-ip-from: "0.0.0.0/0"
Note: The proxy information is passed to the Ingress Controller through the ConfigMap that you created earlier.
3. To update the ConfigMap, run the following command:
kubectl apply -f common/nginx-config.yaml
4. Set up your deployments or microservices (for example, Bollywood, Hollywood, and Tollywood). See the following examples.
Note: This step assumes that you’re running three microservices (for demo purposes). The microservices are exposed internally with Kubernetes as the default type.
Example:
Here we deploy our 3 sample microservice application using k8s deployment.
Bollywood microservice deployment and svc YAML
bollywoodmicroservice.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: bollywood
spec:
replicas: 2
selector:
matchLabels:
app: bollywood
template:
metadata:
labels:
app: bollywood
spec:
containers:
- name: bollywood
image: harshal1098/ingressimages:bollywood---
apiVersion: v1
kind: Service
metadata:
name: bollywood-svc
spec:
ports:
- port: 80
targetPort: 10010
protocol: TCP
selector:
app: bollywood
2. To apply your configurations, run the following commands:
kubectl apply -f bollywoodmicroservice.yaml
Hollywood microservice deployment and svc YAML
hollywoodmicroservice.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hollywood
spec:
replicas: 2
selector:
matchLabels:
app: hollywood
template:
metadata:
labels:
app: hollywood
spec:
containers:
- name: hollywood
image: harshal1098/ingressimages:hollywood---
apiVersion: v1
kind: Service
metadata:
name: hollywood-svc
spec:
ports:
- port: 80
targetPort: 10011
protocol: TCP
selector:
app: hollywood
2. To apply your configurations, run the following commands:
kubectl apply -f hollywoodmicroservice.yaml
Tollywood microservice deployment and svc YAML
tollywoodmicroservice.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tollywood
spec:
replicas: 2
selector:
matchLabels:
app: tollywood
template:
metadata:
labels:
app: tollywood
spec:
containers:
- name: tollywood
image: harshal1098/ingressimages:tollywood---
apiVersion: v1
kind: Service
metadata:
name: tollywood-svc
spec:
ports:
- port: 80
targetPort: 10012
protocol: TCP
selector:
app: tollywood
2. To apply your configurations, run the following commands:
kubectl apply -f tollywoodmicroservice.yaml
After all 3 microservice deployments we can check output using
kubectl get all
Now let's go ahead and try to create the ingress that will expose this Service that we have created, to the outside world.
Host-based routing ingress:
we are using multiple domain names to route the request.
In this example, we route the request based upon the hostname.
e.x: if the user hits the hostname bollywood.movies.com then Nginx ingress controller route this request to Bollywood microservice and the user only see the bollywood movie names.
Testing host-based routing:
- create a host-based routing ingress “host-based.yaml”
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: movie-ingress
namespace: default
spec:
rules:
- host: bollywood.movies.com
http:
paths:
- backend:
serviceName: bollywood-svc
servicePort: 80
- host: hollywood.movies.com
http:
paths:
- backend:
serviceName: hollywood-svc
servicePort: 80
- host: tollywood.movies.com
http:
paths:
- backend:
serviceName: tollywood-svc
servicePort: 80
2. To apply your configurations, run the following commands:
kubectl apply -f host-based.yaml
Output:
To see the host-based routing work properly or not, curl the hostname(domain name).
Below the image you see, when we try to curl on the bollywood.movies.com it’s given us only Bollywood movie's names, and when we try to hit hollywood.movies.com it gives us only Hollywood movie names.
so here routing is happened based upon the hostname hit by the user.
Path-based routing:
Path-based routing differ from host-based routing in the sense, we don’t have multiple domain names, all the URI is distinguished and routed from the PATH prefix under a single domain, for example, the above movies application can be access through the single URI.
- create a path-based routing ingress “path-based.yaml”
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: movies
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: newmovies.com
http:
paths:
- path: /bollywood
backend:
serviceName: bollywood-svc
servicePort: 80
- path: /hollywood
backend:
serviceName: hollywood-svc
servicePort: 80
- path: /tollywood
backend:
serviceName: tollywood-svc
servicePort: 80
2. To apply your configurations, run the following commands:
kubectl apply -f path-based.yaml
Output:
- when the user hits the newmovies.com/</path> hostname then the ingress controller routes the request based on the path given by the user to the specific microservices.
e.x: path’s /bollywood, /hollywood, /tollywood
2.if the user hits only newmovies.com or path other than define in the ingress.yaml then it gives an error message 404 not found.
Thank you, if you have any doubt reach out to me
LinkedIn : linkedin.com/in/harshal-kathar-b2a19b118