Ingress cannot expose the service

4/22/2021

I'm using the microk8s with default ingress addons.

$ microk8s enable ingress
Addon ingress is already enabled.
$ microk8s status
microk8s is running
high-availability: no
  datastore master nodes: 127.0.0.1:19001
  datastore standby nodes: none
addons:
  enabled:
    dashboard            # The Kubernetes dashboard
    dns                  # CoreDNS
    ha-cluster           # Configure high availability on the current node
    ingress              # Ingress controller for external access
    metrics-server       # K8s Metrics Server for API access to service metrics
    registry             # Private image registry exposed on localhost:32000
    storage              # Storage class; allocates storage from host directory

My service is running smoothly when access it without ingress routing.

$ curl 10.152.183.197 #the service binded to 10.152.183.197
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="robots" content="NONE,NOARCHIVE">
  ....
</head>
</html>

But I cannot get the ingress working properly in both localhost and remote-host, it always return 404.

$ curl 127.0.0.1 -H  "Host: projects.xtech1999.com" #executed in microk8s host node
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.19.2</center>
</body>
</html> 

$ curl projects.xtech1999.com #executed in remote machine
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.19.2</center>
</body>
</html> 

I confirmed that the DNS record (projects.xtech1999.com) is pointed to IP Address correctly, My configuration are below:

$ kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes     ClusterIP   10.152.183.1     <none>        443/TCP          10h
pgsql-srv      NodePort    10.152.183.239   <none>        5432:32157/TCP   9h
projects-srv   NodePort    10.152.183.197   <none>        80:31436/TCP     9h

$ kubectl get ing
NAME      CLASS    HOSTS                    ADDRESS   PORTS   AGE
ingress   <none>   projects.xtech1999.com             80      12m

$ kubectl describe ing ingress
Name:             ingress
Namespace:        default
Address:
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host                    Path  Backends
  ----                    ----  --------
  projects.xtech1999.com
                          /   projects-srv:80 (10.1.166.145:80)
Annotations:              kubernetes.io/ingress.class: nginx
Events:                   <none>

$ cat 9999-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: projects.xtech1999.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: projects-srv
            port:
               number: 80

$ netstat -lnp | grep 80
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
unix  2      [ ACC ]     STREAM     LISTENING     28036    -                    /var/snap/microk8s/2094/var/kubernetes/backend/kine.sock
unix  2      [ ACC ]     STREAM     LISTENING     48509    -                    @/containerd-shim/86b04e625b27cda8731daf9c4b25b8a301cc659f41bb0957a0124780fd428557.sock@
unix  2      [ ACC ]     STREAM     LISTENING     52619    -                    @/containerd-shim/a53801f4268bd9e9a2bd1f0a2e7076ead63759ba23d1baaa193347f2abff54ea.sock@
unix  2      [ ACC ]     STREAM     LISTENING     36064    -                    @/containerd-shim/d805d091f24793a8452aa1699a67cf733884e51a6b8602290e522e088deb7fec.sock@
unix  2      [ ACC ]     STREAM     LISTENING     34750    -                    @/containerd-shim/849069ea6f0aac1707e1046f6b2ed65ba8d804b19ca157f538c279f323f8ad27.sock@
unix  2      [ ACC ]     STREAM     LISTENING     206657   -                    @/containerd-shim/a26df014b6fc6001235480215ec743c82b83aabe3c1e69442c37106dd097a12d.sock@
unix  2      [ ACC ]     STREAM     LISTENING     39444    -                    @/containerd-shim/97743748a84e4cbbda28e93b4d215b3adf514fa0fb4801790f567b1a63e6d92a.sock@
unix  2      [ ACC ]     STREAM     LISTENING     47838    -                    @/containerd-shim/e142dd0724d17d6da61c580bbd599dc246ef806d7d3b09d5791484c8fb6f6f93.sock@
unix  2      [ ACC ]     STREAM     LISTENING     38340    -                    @/containerd-shim/1fcc48ca77e6d7b138008c2a215ff2845e4e48d63e50be16285ae1daa003ea55.sock@

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)
443/tcp (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)

what's going on? I guess is the ingress cannot routing propertly.

-- KensonMan
kubernetes
microk8s
nginx

1 Answer

4/24/2021

From your Ingress definition, I see you set-up as ingress class nginx

$ cat 9999-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: projects.xtech1999.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: projects-srv
            port:
               number: 80

Now, it's unfortunately not well documented on microk8s Ingress add-on page of the documentation, but when you enable the Ingress add-on, it creates an Ingress Controller with the default class called public (you can see the default definition here https://github.com/ubuntu/microk8s/blob/master/microk8s-resources/actions/ingress.yaml )

You can confirm that your ingress class is called public with a k get IngressClass

Modify your ingress definition to use the default ingress class and your setup should work:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.class: public
spec:
  rules:
  - host: projects.xtech1999.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: projects-srv
            port:
               number: 80

If you are curious on what is the purpose of an Ingress Class, it can mostly be used to associate an Ingress resource definition, with an ingress controller. On a Kubernetes cluster, there may be more than one Ingress Controller, each one with its own ingress class and Ingress resources are associated to one of them by matching the requested ingress class.

If an ingress class is not specified, the Ingress uses the default one, which means that the IngressClass annotated to be the default one of the cluster is automatically used.

For more info, check the documentation here ( https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class )

-- AndD
Source: StackOverflow