Ingress 无法暴露服务

Ingress cannot expose the service

我正在使用带有默认入口插件的 microk8s。

$ 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

在没有入口路由的情况下访问我的服务运行很顺利。

$ 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>

但是我无法让入口在本地主机和远程主机上正常工作,它总是 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> 

我确认 DNS 记录 (projects.xtech1999.com) 正确指向 IP 地址,我的配置如下:

$ 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)

这是怎么回事?我猜是入口无法正确路由。

根据你的 Ingress 定义,我看到你设置为 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

现在,不幸的是,文档的 microk8s Ingress 附加组件页面上没有很好的记录,但是当您启用 Ingress 附加组件时,它会创建一个具有默认 class 的 Ingress Controller称为 public (您可以在此处查看默认定义 https://github.com/ubuntu/microk8s/blob/master/microk8s-resources/actions/ingress.yaml

您可以确认您的入口 class 被称为 public,带有 k get IngressClass

修改您的入口定义以使用默认入口 class 并且您的设置 应该 有效:

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

如果您对 Ingress 的用途感到好奇 Class,它主要用于将 Ingress 资源定义与入口控制器相关联。在一个 Kubernetes 集群上,可能有多个 Ingress Controller,每个都有自己的 Ingress class 并且 Ingress 资源通过匹配请求的 Ingress class.

关联到其中一个。

如果不指定ingressclass,则Ingress使用默认的,即自动使用集群中标注为默认的IngressClass

有关详细信息,请在此处查看文档 (https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class)