首页 > 解决方案 > 使用主机的入口规则

问题描述

有人可以帮助发现ingress-2入口规则的问题吗?为什么ingress-1工作与ingress-2不工作。

我的设置描述,我有两个部署:

第一次部署是nginx
第二次部署是httpd

这两个部署都分别通过ClusterIP名为nginx-svc和的服务公开httpd-svc。所有这些endpoints都适合服务。但是,在为这些服务设置入口时,我无法使用host(如 中所述ingress-2)设置入口。但是,当我使用 时ingress-1,一切正常。

// 我用于名称解析的主机文件

grep myapp.com /etc/hosts
127.0.0.1        myapp.com

// 部署细节

kubectl get deployments.apps
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   3/3     3            3           29m
httpd   3/3     3            3           29m

// 服务细节

kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.152.183.1     <none>        443/TCP   7h48m
nginx-svc    ClusterIP   10.152.183.233   <none>        80/TCP    28m
httpd-svc    ClusterIP   10.152.183.58    <none>        80/TCP    27m

// 端点详细信息

kubectl get ep
NAME         ENDPOINTS                                      AGE
kubernetes   10.0.2.15:16443                                7h51m
nginx-svc    10.1.198.86:80,10.1.198.87:80,10.1.198.88:80   31m
httpd-svc    10.1.198.89:80,10.1.198.90:80,10.1.198.91:80   31m

尝试1:ingress-1

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-1
spec:
  rules:
  - http:
      paths:
      - path: /nginx
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80

      - path: /httpd
        pathType: Prefix
        backend:
          service:
            name: httpd-svc
            port:
              number: 80

// 显示入口路由在ingress-1使用时工作正常的示例:

 curl myapp.com/nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>


 curl myapp.com/httpd
<html><body><h1>It works!</h1></body></html>

// 遵循入口规则没有像我预期的那样工作

尝试2:ingress-2

kind: Ingress
metadata:
  name: ingress-2
spec:
  rules:
  - host: "myapp.com"
    http:
      paths:
      - pathType: Prefix
        path: "/nginx"
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
      - pathType: Prefix
        path: "/httpd"
        backend:
          service:
            name: httpd-svc
            port:
              number: 80

// 我在 ing describe 中找不到任何问题

kubectl describe  ingress ingress-2
Name:             ingress-2
Namespace:        default
Address:          127.0.0.1
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host          Path  Backends
  ----          ----  --------
  myapp.com
                /nginx   nginx-svc:80 (10.1.198.86:80,10.1.198.87:80,10.1.198.88:80)
                /httpd   httpd-svc:80 (10.1.198.89:80,10.1.198.90:80,10.1.198.91:80)
Annotations:    <none>
Events:
  Type    Reason  Age                  From                      Message
  ----    ------  ----                 ----                      -------
  Normal  Sync    9m15s (x2 over 10m)  nginx-ingress-controller  Scheduled for sync

// 显示入口路由的示例不适用于此入口资源

curl myapp.com/nginx
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.21.1</center>
</body>
</html>

curl myapp.com/httpd
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>

标签: kubernetesnginx-ingressmicrok8s

解决方案


入口之间的差异

我按照官方文档创建了一个单节点microk8s集群,但我无法重现您描述的正确行为。为每个pod 添加了两个带有图像的 pod(强烈推荐:非常方便对 ingress 进行故障排除或了解 ingress 的工作原理)和两个服务。mendhak/http-https-echo

两个入口规则之间的区别是首先入口规则侦听所有域(HOSTS):

$ mkctl get ing -o wide
NAME        CLASS    HOSTS   ADDRESS     PORTS   AGE
ingress-1   public   *       127.0.0.1   80      2m53s

$ curl -I --header "Host: myapp.com" http://127.0.0.1/httpd
HTTP/1.1 200 OK

$ curl -I --header "Host: example.com" http://127.0.0.1/httpd
HTTP/1.1 200 OK

$ curl -I --header "Host: myapp.com" http://127.0.0.1/missing_url
HTTP/1.1 404 Not Found

而第二个入口规则将只服务于myapp.com域(HOST):

$ mkctl get ing
NAME        CLASS    HOSTS       ADDRESS     PORTS   AGE
ingress-2   public   myapp.com   127.0.0.1   80      60s

$ curl -I --header "Host: myapp.com" http://127.0.0.1/httpd
HTTP/1.1 200 OK

$ curl -I --header "Host: example.com" http://127.0.0.1/httpd
HTTP/1.1 404 Not Found

究竟会发生什么

您问题的最后结果实际上表明入口正在按预期工作。您收到的响应不是来自kubernetes ingress集群中的 Pod,而是来自集群中的 Pod。第一个响应404来自nginx 1.21.0,第二个响应404来自apache

发生这种情况是因为 ingress 将请求发送到具有相同path来自 URL 的 Pod 而不进行任何转换。例如(我使用上面提到的图像得到的这个输出):

$ curl myapp.com/httpd
{
  "path": "/httpd"
...

虽然两者nginxapache在服务/

如何解决

Nginx ingress 有很多特性,其中之一是重写,这有助于将pathsingress 的内容转换为 pod 的内容。

例如,如果请求转到http://myapp.com/nginxthen 它将被定向到nginx带有/nginx路径的服务,这将导致nginx抛出404,因为 this 上没有任何内容path

下面的入口规则通过添加我们需要传递给的服务rewrite-target来解决这个问题:/nginxapache

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-2
  annotations:
#    kubernetes.io/ingress.class: nginx # this should be uncommented if ingress used in "regular" cluster
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.com
    http:
      paths:
      - path: /nginx
        pathType: Prefix
        backend:
          service:
            name: service-a
            port:
              number: 80
      - path: /httpd
        pathType: Prefix
        backend:
          service:
            name: service-b
            port:
              number: 80

快速测试它是如何工作的:

$ curl myapp.com/nginx
{
  "path": "/",
...

$ curl myapp.com/httpd
{
  "path": "/",
...

如您所见,现在path/.

将图像切换到nginx和:

$ curl myapp.com/nginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
...

推荐阅读