🏷️ Know how to use Ingress controllers and Ingress resources#

Ingress

Ingress is an API object that provides routing rules to manage external access to services within a Kubernetes cluster, typically using HTTP or HTTPS protocols. It acts as a single entry point for routing traffic from outside the cluster to internal services, allowing administrators to consolidate routing rules into one resource rather than creating multiple load balancers or exposing each service individually..

Ingress enables features such as host-based routing (e.g., routing requests for foo.example.com to one service and bar.example.com to another) and path-based routing (e.g., directing requests starting with /serviceA to service A). It also supports advanced capabilities like SSL/TLS termination, content-based routing, rate limiting, timeouts, and authentication, all configured through rules defined in the Ingress resource. The Ingress itself does not handle traffic routing directly; instead, it relies on an external component called an Ingress Controller, which implements the routing rules by acting as a reverse proxy and load balancer.

An Ingress Controller listens for changes to Ingress resources and configures itself accordingly to route incoming traffic to the appropriate backend services based on the defined rules. While the Ingress resource is a Kubernetes abstraction, the actual implementation depends on third-party controllers such as NGINX, Traefik, or HAProxy, each offering additional features through annotations and custom configurations. Without an Ingress Controller, creating an Ingress resource has no effect, as the controller is responsible for executing the routing logic.

An Ingress Controller is a specialized load balancer and reverse proxy that implements the routing rules defined by Ingress resources, acting as a gateway for external traffic to reach services within the cluster. It receives traffic from outside the Kubernetes platform and load balances it to the appropriate pods based on the rules specified in the Ingress configuration. The controller monitors the state of pods and automatically updates routing rules when pods are added, removed, or scaled, ensuring dynamic and reliable traffic management. It abstracts the complexity of traffic routing, provides a bridge between internal Kubernetes services and external networks, and can also manage egress traffic from services within the cluster to external ones.

Install service Mesh Linkerd#

# Insall linkerd CLI curl -sL run.linkerd.io/install-edge | sh
# Ensure linkerd binary is in PATH echo "export PATH=$PATH:$HOME/.linkerd2/bin" >> $HOME/.zshrc \
&& source $HOME/.zshrc
ᐅ linkerd check --pre
# Install Gateway API CRDs kb apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard-install.yaml
# Instal Linkerd CRDs linkerd install --crds | kubectl apply -f -
# Install Linkerd linkerd install | kubectl apply -f -
ᐅ linkerd check | awk 'END{print}'
Status check results are √
ᐅ linkerd viz install | kubectl apply -f -
ᐅ linkerd viz check
ᐅ linkerd viz dashboard &
# comment `-enforced-host=` args option in web.linlekrd-viz deploy
# update web.linkerd-viz svc to NodePort 31500
# Mesh guisamweb deployments kb get deploy -A -l app=guisamweb -o yaml | linkerd inject - | kb apply -f -

Install Ingress NGINX Controller#

# Add IngressNginx charts repository helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
ᐅ helm repo update
# Check charts helm search repo ingress-nginx -l | awk 'NR<5'
NAME                            CHART VERSION   APP VERSION     DESCRIPTION
ingress-nginx/ingress-nginx     4.13.3          1.13.3          Ingress controller for Kubernetes using NGINX a...
ingress-nginx/ingress-nginx     4.13.2          1.13.2          Ingress controller for Kubernetes using NGINX a...
ingress-nginx/ingress-nginx     4.13.1          1.13.1          Ingress controller for Kubernetes using NGINX a...
ᐅ helm fetch ingress-nginx/ingress-nginx --untar --version 4.13.3
tree -L 1 --noreport ingress-nginx
ingress-nginx
├── Chart.yaml
├── OWNERS
├── README.md
├── README.md.gotmpl
├── changelog
├── ci
├── cloudbuild.yaml
├── templates
├── tests
└── values.yaml
ᐅ diff -u ingress-nginx/values.yaml{.before,}
--- ingress-nginx/values.yaml.before    2025-10-14 15:34:07.461285975 +0200
+++ ingress-nginx/values.yaml   2025-10-14 15:34:35.613255621 +0200
@@ -223,7 +223,7 @@
   #         name: secret-resource

   # -- Use a `DaemonSet` or `Deployment`
-  kind: Deployment
+  kind: DaemonSet
   # -- Annotations to be added to the controller Deployment or DaemonSet
   ##
   annotations: {}
# Check helm template ingress-nginx ingress-nginx \
-n ingress-nginx --create-namespace
# Install in a separated namespace helm install ingress-nginx ingress-nginx \
-n ingress-nginx --create-namespace
# Check resources in ingress-nginx namespace kb get all -n ingress-nginx
NAME                                 READY   STATUS    RESTARTS   AGE
pod/ingress-nginx-controller-x86cm   1/1     Running   0          89s

NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.98.180.13    <pending>     80:30586/TCP,443:31989/TCP   89s
service/ingress-nginx-controller-admission   ClusterIP      10.97.110.104   <none>        443/TCP                      89s

NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/ingress-nginx-controller   1         1         1       1            1           kubernetes.io/os=linux   89s

Create an Ingress resource#

# Create two deployments and services kb create deploy web-one \
--dry-run=client \
--image=httpd:alpine \
--port=80 --replicas=2 \
-o yaml > web-one.yaml
ᐅ kb create deploy web-two \
--dry-run=client \
--image=nginx:alpine \
--port=80 --replicas=2 \
-o yaml > web-two.yaml
ᐅ kb apply -f web-one.yaml -f web-two.yaml
ᐅ kb expose deploy web-one --name=svc-web-one
ᐅ kb expose deploy web-two --name=svc-web-two
# Create an ingress with web-one service as backend kb create ingress web --dry-run=client \
  --default-backend=svc-web-one:80 --class="nginx" \
  --rule="www.guisam.lan/*=svc-web-one:80" -o yaml \
  > ingress.yaml
 kb create -f ingress.yaml
# Get the nginx controller ip address kb get svc -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.98.180.13    <pending>     80:30586/TCP,443:31989/TCP   39m
ingress-nginx-controller-admission   ClusterIP      10.97.110.104   <none>        443/TCP                      39m
# Check ingress rules curl 10.98.180.13
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
ᐅ curl -H "Host: www.guisam.lan" 10.98.180.13
<html><body><h1>It works!</h1></body></html>
# Mesh ingress-nginx daemaonset kb get -n ingress-nginx ds ingress-nginx-controller -o yaml \
| linkerd inject - | kb apply -f -
# Add a new rule diff -u ingress.yaml{.before,}
--- ingress.yaml.before 2025-10-14 16:41:40.540291154 +0200
+++ ingress.yaml        2025-10-14 16:47:46.605840842 +0200
@@ -1,7 +1,7 @@
 apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
-  name: web-one
+  name: web
 spec:
   defaultBackend:
     service:
@@ -19,6 +19,16 @@
             port:
               number: 80
         path: /
+        pathType: Prefix
+  - host: nginx.guisam.lan
+    http:
+      paths:
+      - backend:
+          service:
+            name: svc-web-two
+            port:
+              number: 80
+        path: /
         pathType: Prefix
 status:
   loadBalancer: {} kb apply -f ingress.yaml

Note

 k create ingress web --rule="n.guisam.lan/*=svc-web-1:80" \
--rule="h.guisam.lan/*=svc-web-2:80" --class=nginx
 curl -H "Host: www.guisam.lan" 10.98.180.13
<html><body><h1>It works!</h1></body></html>
ᐅ curl -H "Host: nginx.guisam.lan" 10.98.180.13
<html><body>
<h1>Welcome to nginx!</h1>
</body></html>
ᐅ curl 10.98.180.13
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

install nginx ingress controller#

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

kubectl -n ingress-nginx rollout status deploy/ingress-nginx-controller --timeout=300s

kubectl -n ingress-nginx get pods -l app.kubernetes.io/component=controller

kubectl -n ingress-nginx patch svc ingress-nginx-controller -p '{"spec":{"type":"NodePort","ports":[{"name":"http","port":80,"protocol":"TCP","targetPort":80,"nodePort":30000},{"name":"https","port":443,"protocol":"TCP","targetPort":443,"nodePort":30443}]}}'

install nginx ingress controller#

k create ns nginx-ingress

helm install my-nginx-ingress nginx-stable/nginx-ingress \
  --namespace nginx-ingress \
  --set controller.replicaCount=2 \
  --set controller.service.type=NodePort \
  --set controller.service.httpPort.nodePort=30080 \
  --set controller.service.httpsPort.nodePort=30443