Ingress
All right, it has been sometime since I last wrote my blog, and it has been disappointing not to have found enough time to collate and put my thoughts in a simple worded doc; better late then never. So, here I am trying to reignite the pursuit of writing at least once a week.
Topic for the day: Ingress
https://kubernetes.io/docs/concepts/services-networking/ingress/
An API object that manages external access to the services in a cluster, typically HTTP.
kubernetes.io
Till now I had only exposed services (HTTP/HTTPS) using NodePort or ClusterIP but as the security tightens and K8S evolves (current version 1.22.1) I had to try out ingress, but that meant few things.
- Identifying the current version which in my case was 1.19 and after repeated attempts to 
kubeadm upgrade planfailed, I created a fresh cluster. - The fresh install was simple, I just had to reset and upgrade the binaries which were reporting the version skew.
 

Current Version: v1.22.1
> k version
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.1", GitCommit:"632ed300f2c34f6d6d15ca4cef3d3c7073412212", GitTreeState:"clean", BuildDate:"2021-08-19T15:45:37Z", GoVersion:"go1.16.7", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.0", GitCommit:"c2b5237ccd9c0f1d600d3072634ca66cefdf272f", GitTreeState:"clean", BuildDate:"2021-08-04T17:57:25Z", GoVersion:"go1.16.6", Compiler:"gc", Platform:"linux/amd64"}I will try to expose a simple echoservice : jmalloc/echo-server over ingress
GITHUB: echo-server
Docker: echo-server
k describe svc echo-service
Name:              echo-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          run=echo
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.106.39.121
IPs:               10.106.39.121
Port:              http  80/TCP
TargetPort:        8080/TCP
Endpoints:         172.16.217.198:80
Session Affinity:  None
Events:            <none>The code is references below
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: echo
  name: echo
spec:
  replicas: 1
  selector:
    matchLabels:
      run: echo
  template:
    metadata:
      labels:
        run: echo
    spec:
      containers:
      - name: echo
        image: jmalloc/echo-server
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
          successThreshold: 1
---
apiVersion: v1
kind: Service
metadata:
    name: echo-service
spec:
    selector:
      run: echo
    ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080What is Ingress?
Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster.
Rules are used to control the incoming traffic.
IngressRule represents the rules mapping the paths under a specified
hostto the relatedbackend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.
An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type
Before ingress can be created you need the cluster to have an ingress controller, in my case I deployed HAProxy as the controller
helm install kubernetes-ingress haproxytech/kubernetes-ingress --set controller.logging.level=debugI have enabled logging by using instructions available here
helm ls
NAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                           APP VERSION
kubernetes-ingress      default         1               2021-08-24 06:10:34.409376867 +0000 UTC deployed        kubernetes-ingress-1.16.2       1.6.5Pods currently running in my system have the ingress controller and the echo-service
NAME                                                      READY   STATUS    RESTARTS   AGE
pod/echo-67b86c4c99-8xt8t                                 1/1     Running   0          26h
pod/kubernetes-ingress-6f5b6f789c-5l56m                   1/1     Running   0          69m
pod/kubernetes-ingress-6f5b6f789c-66kpk                   1/1     Running   0          69m
pod/kubernetes-ingress-default-backend-759ccc6c98-2shlv   1/1     Running   0          69m
pod/kubernetes-ingress-default-backend-759ccc6c98-ddsnt   1/1     Running   0          69mServices exposed are aas under
NAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                     AGE
service/echo-service                         ClusterIP   10.106.39.121    <none>        80/TCP                                      26h
service/kubernetes                           ClusterIP   10.96.0.1        <none>        443/TCP                                     4d23h
service/kubernetes-ingress                   NodePort    10.109.251.254   <none>        80:30462/TCP,443:31125/TCP,1024:32696/TCP   69m
service/kubernetes-ingress-default-backend   ClusterIP   None             <none>        8080/TCP                                    69mYou can see the NodePort service for ingress exposed over 30462
Let’s write the ingress for the echo service
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    haproxy.org/path-rewrite: "/"
    haproxy.org/ingress.class: "haproxy"
spec:
  rules:
    - http:
        paths:
        - path: /echo
          pathType: Prefix
          backend:
            service:
              name: echo-service
              port:
                number: 80Once you save this file ingress.yaml and apply it using kubectl apply -f ingress.yaml you can see the resource created
NAME           CLASS    HOSTS   ADDRESS          PORTS   AGE
echo-ingress   <none>   *       10.109.251.254   80      69mYou can check the logs of the haproxy pod to see if the route has been updated
k logs kubernetes-ingress-6f5b6f789c-5l56m2021/08/24 06:13:46 DEBUG   service/service.go:121 Ingress 'default/echo-ingress': new backend 'default-echo-service-http', reload required
2021/08/24 06:13:46 DEBUG   service/service.go:148 Ingress 'default/echo-ingress': backend 'default-echo-service-http' updated, reload required
2021/08/24 06:13:46 DEBUG   service/endpoints.go:133 Server slots in backend 'default-echo-service-http' scaled to match scale-server-slots value: 42, reload required
2021/08/24 06:13:46 DEBUG   haproxy/rules.go:199 New HAProxy rule 'REQ_PATH_REWRITE' created, reload required
2021/08/24 06:13:46 DEBUG   haproxy/rules.go:199 New HAProxy rule 'REQ_PATH_REWRITE' created, reload required
2021/08/24 06:13:46 DEBUG   haproxy/maps.go:116 Map file 'path-exact' updated, reload required
2021/08/24 06:13:46 DEBUG   haproxy/maps.go:116 Map file 'path-prefix' updated, reload required
2021/08/24 06:13:46 DEBUG   haproxy/rules.go:199 New HAProxy rule 'REQ_PATH_REWRITE' created, reload required
2021/08/24 06:13:46 DEBUG   haproxy/rules.go:199 New HAProxy rule 'REQ_PATH_REWRITE' created, reload required
2021/08/24 06:13:46 INFO    controller.go:235 HAProxy reloadedSo the ingress is now working and available for incoming traffic, let’s give it a try
curl http://10.80.120.148:30462/echoRequest served by echo-67b86c4c99-8xt8t
HTTP/1.1 GET /
Host: 10.80.120.148:30462
User-Agent: curl/7.29.0
Accept: */*
X-Forwarded-For: 172.16.217.192Help
- You can refer to the official documentation
 kubectl create ing --helphttps://kubernetes.io/docs/concepts/services-networking/service/https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#service-v1-corehttps://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#ingress-v1-networking-k8s-iohttps://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#ingressrule-v1-networking-k8s-iohttps://www.haproxy.com/documentation/kuberneteshttps://www.haproxy.com/documentation/kubernetes/latest/usage/logging/
