# Ingress: Routing

Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.

![Ingress - Kubernetes Official Docs](https://kubernetes.io/docs/images/ingress.svg)

\**Kubernetes Official Docs*

Ingress provides a single entry point that routes requests to different services based on:

* **Hostnames** (e.g., app.example.com)
* **Paths** (e.g., /api, /web)
* **TLS Settings** (for HTTPS)
* **Annotations** (for additional behavior like rewrites, redirects, etc.)

There are many use cases that utilize ingress such as TLS, Force HTTPS, Force Redirect, Basic Authentication, Rate Limiting, IP Whitelisting, etc. But for now lets focus on basic implementation that is for traffic routing.

## Enable Minikube Ingress Addons

To enable ingress in minikube we need to enable the addons first.

```bash
➜ minikube addons enable ingress
💡  ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS
💡  After the addon is enabled, please run "minikube tunnel" and your ingress resources would be available at "127.0.0.1"
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3
    ▪ Using image registry.k8s.io/ingress-nginx/controller:v1.11.2
🔎  Verifying ingress addon...
🌟  The 'ingress' addon is enabled
```

To validate if ingress controller already running we can use command `kubectl get pods -n ingress-nginx`. It can take up to a minute before you see these pods running.

```bash
➜ kubectl get pods -n ingress-nginx
NAME                                       READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-fmhdk       0/1     Completed   0          2m40s
ingress-nginx-admission-patch-zxmgn        0/1     Completed   0          2m40s
ingress-nginx-controller-bc57996ff-rz4wd   1/1     Running     0          2m40s
```

## Create Ingress

Lets expose our `simple-go` service to outside using ingress we defined below. Create new file `ingress.yaml` and put the ingress definition there.

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: simple-go.mine
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: simple-go
                port:
                  number: 8080
```

This will create ingress object with name `simple-ingress` using `nginx`. There are others `ingressClassName` such as Traefik, HAProxy, Istio, etc. But in this case we will use nginx.

In the `rules` section we can define rules for this ingress. An Ingress rule defines how incoming HTTP(S) traffic is routed inside a Kubernetes cluster.

* `host`: Specifies which domain should match (optional).
* `paths.path`: Defines the URL path that should be routed.
* `paths.pathType`: Type of path matching (more details below). For full list of path type you can read further here: [Path Type Example](https://kubernetes.io/docs/concepts/services-networking/ingress/#examples).
* `backend.service.name`: The name of the Kubernetes service to route traffic to.
* `backend.service.port.number`: The service port to forward traffic to.

So in our ingress definition we want to match all traffic for domain `simple-go.mine` to service with name `simple-go` and port `8080`.

Lets apply our ingress definition and validate if on the list.

```bash
➜ kubectl apply -f ingress.yaml 
ingress.networking.k8s.io/simple-ingress created
```

```bash
➜ kubectl get ingress
NAME             CLASS   HOSTS            ADDRESS        PORTS   AGE
simple-ingress   nginx   simple-go.mine   192.168.49.2   80      15s
```

## Test Ingress

Because I'm using MacOS (Minikube with Docker Driver) I need to do tunneling first using command `minikube tunnel`. It will tunnel all localhost traffic for port `80` and `443` to the minikube.

```
➜ minikube tunnel
✅  Tunnel successfully started

📌  NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...

❗  The service/ingress simple-ingress requires privileged ports to be exposed: [80 443]
🔑  sudo permission will be asked for it.
🏃  Starting tunnel for service simple-ingress.
```

After tunneling started we then can access is using the curl command below.

```bash
➜ curl --resolve "simple-go.mine:80:127.0.0.1" -i http://simple-go.mine
HTTP/1.1 200 OK
Date: Fri, 31 Jan 2025 03:37:49 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 65
Connection: keep-alive

[{"id":1,"content":"Hello!"},{"id":2,"content":"Good Morning!"}]
```

You can try to change the path and domain to see what changes does it makes.

## References

* <https://kubernetes.io/docs/concepts/services-networking/ingress/>
* <https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bagus-cahyono.gitbook.io/programming-notes/cka/10_ingress_routing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
