> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lab Solution Ingress Networking 1 optional

> Guide demonstrating how to inspect and modify NGINX Ingress resources to add and change path-based routes, use rewrite annotations, and expose namespace-scoped services

This lesson walks through an existing NGINX Ingress controller and several deployed applications. You will inspect cluster resources, update an Ingress to change a route path, add new application routes, and create a namespace-scoped Ingress for a critical service. These steps illustrate common patterns for path-based routing and using the `nginx.ingress.kubernetes.io/rewrite-target` annotation to adapt backend expectations.

## Environment overview

Start by checking cluster nodes and deployments to locate the Ingress controller and application workloads.

```bash theme={null}
root@controlplane ~ ➜ kubectl get nodes
NAME           STATUS   ROLES                 AGE   VERSION
controlplane   Ready    control-plane,master  11m   v1.23.0
```

There are no deployments in the `default` namespace:

```bash theme={null}
root@controlplane ~ ➜ kubectl get deploy
No resources found in default namespace.
```

Show deployments across all namespaces to find the Ingress controller and app deployments:

```bash theme={null}
root@controlplane ~ ➜ kubectl get deploy -A
NAMESPACE       NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
app-space       default-backend              1/1     1            1           49s
app-space       webapp-video                 1/1     1            1           50s
app-space       webapp-wear                  1/1     1            1           50s
ingress-nginx   ingress-nginx-controller     0/1     1            0           47s
kube-system     coredns                      2/2     2            2           11m
```

(You may briefly see `ingress-nginx-controller` at `0/1` while it starts; it will transition to `1/1`.)

List pods across all namespaces to confirm which namespace hosts the controller and the application pods:

```bash theme={null}
root@controlplane ~ ➜ kubectl get pods -A
NAMESPACE       NAME                                              READY   STATUS      RESTARTS   AGE
app-space       default-backend-7f87f4c484-zw8kb                 1/1     Running     0          9m46s
app-space       webapp-food-6f8d48ffc6-jrjvr                     1/1     Running     0          2m13s
app-space       webapp-video-d54b764b6-d5rnd                     1/1     Running     0          9m46s
app-space       webapp-wear-5bb44cf565-9hjsm                     1/1     Running     0          9m47s
ingress-nginx   ingress-nginx-controller-546d8cf744-4h2z         1/1     Running     0          9m44s
kube-system     coredns-64897985d-fp6js                          1/1     Running     0          20m
...
```

From the outputs:

* The NGINX Ingress controller runs in the `ingress-nginx` namespace.
* Application workloads are deployed in the `app-space` namespace.

<Callout icon="lightbulb" color="#1CB2FE">
  Best practice: Keep Ingress resources in the same namespace as the application wherever possible so teams can manage access with namespace-scoped RBAC. This guide follows that approach for the new critical app.
</Callout>

***

## Inspect the Ingress resource

List all Ingress resources to locate the one currently routing traffic for `/wear` and `/watch`:

```bash theme={null}
root@controlplane ~ ➜ kubectl get ingress -A
NAMESPACE   NAME                 CLASS    HOSTS   ADDRESS         PORTS   AGE
app-space   ingress-wear-watch   <none>   *       10.96.152.118   80      3m
```

Describe the `ingress-wear-watch` Ingress in `app-space` to see paths, backends, and annotations:

```bash theme={null}
root@controlplane ~ ➜ kubectl describe ingress ingress-wear-watch -n app-space
Name:             ingress-wear-watch
Namespace:        app-space
Address:          10.96.152.118
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host  Path   Backends
  ----  ----   --------
  *     /wear  wear-service:8080 (10.244.0.4:8080)
        /watch video-service:8080 (10.244.0.6:8080)
Annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /
  nginx.ingress.kubernetes.io/ssl-redirect: false
Events:
  Type    Reason  Age    From                       Message
  Normal  Sync    3m3s   nginx-ingress-controller   Scheduled for sync
```

Key points:

* The Ingress exposes `/wear` and `/watch`, routing respectively to `wear-service:8080` and `video-service:8080`.
* The annotation `nginx.ingress.kubernetes.io/rewrite-target: /` is present — this will rewrite matched prefixes to `/` before forwarding to the backend.

To summarize the current mapping, here is a quick reference:

| Ingress path | Backend service | Service port |
| - | - | - |
| `/wear` | `wear-service` | `8080` |
| `/watch` | `video-service` | `8080` |

***

## Change `/watch` to `/stream`

Requirement: make the video application available at `/stream` instead of `/watch`.

Edit the existing `ingress-wear-watch` to replace the `/watch` path with `/stream`. Ensure you use `pathType: Prefix` so that prefixes are matched and the existing rewrite remains functional.

Example `spec.rules` excerpt after editing:

```yaml theme={null}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-wear-watch
  namespace: app-space
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /wear
        pathType: Prefix
        backend:
          service:
            name: wear-service
            port:
              number: 8080
      - path: /stream
        pathType: Prefix
        backend:
          service:
            name: video-service
            port:
              number: 8080
```

After saving the edit, verify the Ingress rules:

```bash theme={null}
root@controlplane ~ ➜ kubectl describe ingress ingress-wear-watch -n app-space
Rules:
  *  /wear   wear-service:8080 (10.244.0.4:8080)
     /stream video-service:8080 (10.244.0.6:8080)
```

Test the routes (replace IP with your Ingress IP if different):

```bash theme={null}
curl http://10.96.152.118/wear
curl http://10.96.152.118/stream
```

Both requests should return the respective application responses, with path prefixes rewritten to `/` by the annotation.

***

## Add food delivery app at `/eat`

A new food delivery application (`food-service`) was migrated into `app-space`. Inspect services to confirm service names and ports:

```bash theme={null}
root@controlplane ~ ➜ kubectl get svc -n app-space
NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
default-http-backend   ClusterIP   10.102.190.18    <none>        80/TCP      8m
food-service           ClusterIP   10.108.9.190     <none>        8080/TCP    49s
video-service          ClusterIP   10.107.118.120   <none>        8080/TCP    8m
wear-service           ClusterIP   10.110.195.79    <none>        8080/TCP    8m
```

Update the `ingress-wear-watch` Ingress to add `/eat` routing to `food-service:8080`. Example `spec` snippet after the change:

```yaml theme={null}
spec:
  rules:
  - http:
      paths:
      - path: /wear
        pathType: Prefix
        backend:
          service:
            name: wear-service
            port:
              number: 8080
      - path: /stream
        pathType: Prefix
        backend:
          service:
            name: video-service
            port:
              number: 8080
      - path: /eat
        pathType: Prefix
        backend:
          service:
            name: food-service
            port:
              number: 8080
```

Apply the change (for example with `kubectl edit` or `kubectl apply`) and verify:

```bash theme={null}
root@controlplane ~ ➜ kubectl edit ingress ingress-wear-watch -n app-space
# (edit applies)
root@controlplane ~ ➜ kubectl describe ingress ingress-wear-watch -n app-space
Rules:
  *  /wear   wear-service:8080
     /stream video-service:8080
     /eat    food-service:8080
```

Now the food app is reachable at `/eat`. Verify with:

```bash theme={null}
curl http://10.96.152.118/eat
```

***

## Expose a critical payment service in its own namespace

A critical payment application is deployed in `critical-space` and needs to be exposed at `/pay`. This demonstrates creating a namespace-scoped Ingress for a high-sensitivity app.

Inspect the new deployment and service:

```bash theme={null}
root@controlplane ~ ➜ kubectl get deploy -n critical-space
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
webapp-pay  1/1     1            1           22s

root@controlplane ~ ➜ kubectl get svc -n critical-space
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)     AGE
pay-service ClusterIP   10.107.31.180   <none>        8282/TCP    119s
```

Note: Service ports can differ from container ports. `pay-service` exposes service port `8282`; the pod may still serve on `8080`. `kubectl describe pod` and `kubectl describe svc` will show the mappings.

Create a namespace-scoped Ingress that maps `/pay` to `pay-service:8282`. A quick create command:

```bash theme={null}
root@controlplane ~ ➜ kubectl create ingress ingress-pay -n critical-space --rule="/pay=pay-service:8282"
ingress.networking.k8s.io/ingress-pay created
```

Describe the Ingress:

```bash theme={null}
root@controlplane ~ ➜ kubectl describe ingress ingress-pay -n critical-space
Name:             ingress-pay
Namespace:        critical-space
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  *           /pay  pay-service:8282 (10.244.0.11:8080)
Annotations:     <none>
Events:
  Normal  Sync   nginx-ingress-controller   Scheduled for sync
```

If you see 404 responses when curling `/pay`, check application logs:

```bash theme={null}
root@controlplane ~ ➜ kubectl logs -n critical-space deploy/webapp-pay
 * Running on http://10.244.0.11:8080/
10.244.0.9 - - [13/May/2022 05:28:15] "GET / HTTP/1.1" 200 -
10.244.0.9 - - [13/May/2022 05:30:30] "GET /pay HTTP/1.1" 404 -
```

Root cause:

* The Ingress forwards requests including the `/pay` prefix. The payment application expects requests at root `/` (it has no `/pay` route), so the backend returns 404.

Solution:

* Add the `nginx.ingress.kubernetes.io/rewrite-target: /` annotation to the `ingress-pay` metadata and ensure the path uses `pathType: Prefix`. This strips `/pay` before forwarding the request to the service, allowing the backend to receive `/`.

Example Ingress with the rewrite annotation:

```yaml theme={null}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-pay
  namespace: critical-space
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /pay
        pathType: Prefix
        backend:
          service:
            name: pay-service
            port:
              number: 8282
```

Apply the change (`kubectl edit` or `kubectl apply`) and verify:

```bash theme={null}
root@controlplane ~ ➜ kubectl describe ingress ingress-pay -n critical-space
Annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /
Rules:
  *  /pay  pay-service:8282 (10.244.0.11:8080)
```

Test the endpoint and confirm logs show the backend receiving `/`:

```bash theme={null}
curl http://10.96.152.118/pay

# Check logs to confirm rewrite behavior
root@controlplane ~ ➜ kubectl logs -n critical-space deploy/webapp-pay
10.244.0.9 - - [13/May/2022 05:31:12] "GET / HTTP/1.1" 200 -
```

After adding the rewrite annotation, the payment service should return 200 for `/pay`.

***

## Summary & best practices

* Always inspect namespaces, services, and ports (`kubectl get svc -n <ns>`) before editing Ingress resources.
* Keep Ingress resources scoped to the application namespace when possible to simplify RBAC and team ownership.
* Use `nginx.ingress.kubernetes.io/rewrite-target: /` to strip path prefixes if the backend expects root paths.
* Use `pathType: Prefix` for prefix-based routing and combine it with `rewrite-target` to ensure clean backend paths.
* For multi-namespace exposure, either create namespace-local Ingress resources or use a central gateway with appropriate RBAC and routing rules.

<Callout icon="lightbulb" color="#1CB2FE">
  When exposing apps from multiple namespaces, prefer namespace-local Ingress resources (or a central gateway with appropriate RBAC). Always verify annotations and `pathType` settings so requests are routed and rewritten as intended.
</Callout>

## Quick reference tables

Service list in `app-space`:

| Service name | Cluster IP | Port(s) |
| - | - | - |
| `wear-service` | `10.110.195.79` | `8080/TCP` |
| `video-service` | `10.107.118.120` | `8080/TCP` |
| `food-service` | `10.108.9.190` | `8080/TCP` |

Ingress path → backend mapping (final state):

| Ingress path | Backend service | Service port |
| - | - | - |
| `/wear` | `wear-service` | `8080` |
| `/stream` | `video-service` | `8080` |
| `/eat` | `food-service` | `8080` |
| `/pay` | `pay-service` | `8282` |

## Links and references

* [Kubernetes Ingress Concepts](https://kubernetes.io/docs/concepts/services-networking/ingress/)
* [NGINX Ingress Controller Annotations](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/)
* [Kubernetes Services](https://kubernetes.io/docs/concepts/services-networking/service/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/cka-certification-course-certified-kubernetes-administrator/module/44bc9a9f-319c-40ee-babd-0f7b53a70de7/lesson/e5b80056-93b7-4f11-97ee-5f7035d933fd" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/cka-certification-course-certified-kubernetes-administrator/module/44bc9a9f-319c-40ee-babd-0f7b53a70de7/lesson/c6c8e285-f25f-4d57-b641-030e6ab5a61c" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.