# Elastic Kubernetes Service (EKS) Ingress routing with Nginx for Grafana and Prometheus.

In this article, you will learn how to use Ingress-NGINX Controller for Kubernetes to route traffic to Grafana and Prometheus respectively.

## What is an Ingress?

In Kubernetes, an Ingress is an API object that manages external access to services within a cluster. It provides a way to route incoming traffic to different services based on the requested host or path. Essentially, an Ingress acts as a traffic controller for incoming requests.

An Ingress resource defines a set of rules that determine how inbound connections should be routed to the appropriate backend services. It allows you to configure rules for HTTP and HTTPS traffic, including specifying hostnames, paths, and backend services.

## Ingress vs Load Balancer

A Load Balancer is responsible for distributing traffic at the network or transport layer, while Ingress provides routing and load balancing capabilities at the application layer. Load Balancer is typically provided as an external service by cloud providers, while Ingress is an API object in Kubernetes that requires an Ingress controller to function. Both are important for managing external access to services in a Kubernetes cluster, but they serve different purposes and operate at different layers of the network stack.

### Pre-requisites

* AWS Account.
    
* An EKS(Elastic Kubernetes Service) cluster.
    
* A Kubectl installation with your Kubernetes cluster from the step above is configured as the primary cluster.
    
* The Helm CLI.
    

## 1\. Install **and Configure Nginx Ingress Controller**

Install Nginx Ingress in your cluster using Helm, add the `ingress-nginx` repository to Helm, then run `helm repo update` . After we have added the repository we can deploy using the chart `ingress-nginx/ingress-nginx` .

```bash
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
```

Override helm chart default values, and create a file called `nginx-values.yaml` in a directory called `nginx` with the following.

```yaml
controller:
  setAsDefaultIngress: true
  service:
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
      service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'
      service.beta.kubernetes.io/aws-load-balancer-type: nlb
```

* [`service.beta.kubernetes.io/aws-load-balancer-backend-protocol`](http://service.beta.kubernetes.io/aws-load-balancer-backend-protocol)`: tcp` This annotation specifies the backend protocol for the NLB. In this case, it is set to TCP, indicating that the traffic between the NLB and the pods behind it should use the TCP protocol.
    
* [`service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled`](http://service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled)`: 'true'` This annotation enables cross-zone load balancing for the NLB. When set to `true`, the NLB can distribute traffic evenly across all available zones in the specified target group, even if the pods or instances are located in different availability zones.
    
* [`service.beta.kubernetes.io/aws-load-balancer-type`](http://service.beta.kubernetes.io/aws-load-balancer-type)`: nlb` This annotation sets the type of load balancer to be created as an NLB. An NLB is a Layer 4 (TCP/UDP) load balancer provided by AWS that operates at the network level and can handle large-scale traffic.  
      
      
    The following command installs the nginx chart with the release name `ingress-nginx`:
    

```bash
helm install ingress-nginx ingress-nginx/ingress-nginx -f nginx/nginx-values.yaml
```

### 1a. Validate NGINX is running

```yaml
kubectl get pods
```

Output:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685236813095/3a85c0d7-2f01-4f18-bc22-f7e3413c7183.png align="center")

```yaml
kubectl get services
```

Output:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685237216532/1e4ef366-8706-4d7d-8953-56c19db95a0f.png align="center")

## 2\. Install and Configure Kube-Prometheus-Stack

kube-Prometheus-stack collects Kubernetes manifests, Grafana dashboards, and Prometheus rules combined with documentation and scripts to provide easy-to-operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus Operator.

Install kube-prometheus-stack in your cluster using Helm, add the `prometheus-community` repository to Helm, then run `helm repo update` . After we have added the repository we can deploy using the chart `prometheus-community/kube-prometheus-stack` .

```yaml
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
```

The following command installs the kube-prometheus-stack chart with the release name `kube`:

```yaml
helm install kube prometheus-community/kube-prometheus-stack
```

### 2a. Validate kube-prometheus-stack is running

```yaml
kubectl get pods -l release=kube
```

Output:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685245423731/01ba1048-b482-4b25-9f10-bdb7c6177c5a.png align="center")

```yaml
kubectl get services -l release=kube
```

Output:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685245647747/308c0bb6-0479-447d-95aa-42bc503f3177.png align="center")

## 3\. Creating a Kubernetes Ingress

Now that the ingress controller and kube-prometheus-stack are running in the cluster, we can expose the services using ingress.

The annotation [`kubernetes.io/ingress.class`](http://kubernetes.io/ingress.class)`: nginx` is used to specify the Ingress controller class to be used for a Kubernetes Ingress resource.

Create an ingress named `ingress.yaml` with the following:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: default
  annotations: 
  kubernetes.io/ingress.class: nginx
  name: kube-stack-ingress
  labels:
    name: kube-stack-ingress
   
spec:
  rules:
  - host: grafana.tafaribeckford.com #Use your own domain
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: kube-grafana 
            port: 
              number: 80

  - host: prom.tafaribeckford.com #Use your own domain
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: kube-kube-prometheus-stack-prometheus 
            port: 
              number: 9090
```

Create the resource

```yaml
kubectl apply -f ingress.yaml
```

Perfect! Let’s check that it’s working

Grafana Dashboard:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685305171965/a5d0d1d3-e39c-4ca5-b865-92789c911e4b.png align="center")

Prometheus Dashboard:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1685305352577/7a59229a-73a1-4903-b695-b9f69c50e3c0.png align="center")

## Summary

A Kubernetes Ingress provides a reliable method for making your services accessible from outside the cluster. It simplifies the management of routing rules by consolidating them into a single resource and offers flexible configuration options for these rules.
