【问题标题】:Kubernetes multiple ingress objects with same configsKubernetes 具有相同配置的多个入口对象
【发布时间】:2020-06-15 11:58:48
【问题描述】:

假设我在 k8s 中创建了多个入口对象,它们指向相同的服务、相同的路径并且完全相同,只是它们具有不同的名称,例如-。 ingress-1ingress-2。在这种情况下如何处理请求?请求是否重复或任一入口处理请求?

PS;- 我知道这没有多大意义,但我正在测试一些东西。

【问题讨论】:

  • 你说的是控制器还是入口对象?你的集群是如何部署的,你在哪里操作它?
  • 同一个控制器的多个入口对象

标签: kubernetes kubectl kubernetes-ingress


【解决方案1】:

让我们看看它是如何工作的!

我有默认的 nginx 部署

# kubectl -n test get pods -o wide | grep nginx
nginx-65f88748fd-6w6fj           1/1     Running   0          26h     10.8.253.25    k8s-vm02   <none>           <none>
nginx-65f88748fd-8fp7p           1/1     Running   0          26h     10.8.252.205   k8s-vm01   <none>           <none>
nginx-65f88748fd-c7j29           1/1     Running   0          26h     10.8.253.24    k8s-vm02   <none>           <none>
nginx-65f88748fd-frsbq           1/1     Running   0          26h     10.8.252.201   k8s-vm01   <none>           <none>
nginx-65f88748fd-p4zvm           1/1     Running   0          26h     10.8.252.204   k8s-vm01   <none>           <none>
nginx-65f88748fd-pd8gv           1/1     Running   0          25h     10.8.253.27    k8s-vm02   <none>           <none>
nginx-65f88748fd-rkcjl           1/1     Running   0          26h     10.8.252.206   k8s-vm01   <none>           <none>
nginx-65f88748fd-rn49k           1/1     Running   0          26h     10.8.253.26    k8s-vm02   <none>           <none>
nginx-65f88748fd-w9dz8           1/1     Running   0          26h     10.8.252.203   k8s-vm01   <none>           <none>
nginx-65f88748fd-xh42v           1/1     Running   0          25h     10.8.253.28    k8s-vm02   <none>           <none>

服务

# kubectl -n test get svc
NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.8.254.218   <none>        80/TCP    12d

和同一个命名空间中的 2 个相似的 Ingress 资源

# kubectl -n test get ing
NAME             HOSTS            ADDRESS   PORTS   AGE
test-ingress-1   nginx.test.com             80      20m
test-ingress-2   nginx.test.com             80      20m

他们的 YAML:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  namespace: test
  name: test-ingress-1
  annotations:
    kubernetes.io/ingress.class: "service"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: nginx.test.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: nginx
          servicePort: 80

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  namespace: test
  name: test-ingress-2
  annotations:
    kubernetes.io/ingress.class: "service"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: nginx.test.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: nginx
          servicePort: 80

关于 ingress.class: "service" 的另一件事 - 我的环境中有超过 1 个入口控制器和这个特定的入口控制器

nginx-ingress-service-6gkhh                1/1     Running   0          4m20s   10.8.255.243   k8s-vm02   <none>           <none>

专为演示此示例而创建,因此无需付费 关注它

无论如何,Ingress 资源 nginx.test.com/foo 现在可以工作了吗?

# curl -H "Host: nginx.test.com" http://10.8.255.243:80/foo
<!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>

是的,是的。引擎盖下是什么? Ingress-controller 内的 Nginx 配置只有一个server_name nginx.test.com,不管我们有多少类似的 Ingress 资源

# kubectl -n kube-system exec nginx-ingress-service-6gkhh -- cat /etc/nginx/nginx.conf
...
## start server nginx.test.com
    server {
        server_name nginx.test.com ;

        listen 80;

        listen [::]:80;

        set $proxy_upstream_name "-";

        location ~* ^/foo\/?(?<baseuri>.*) {
...
            proxy_pass http://test-nginx-80;
...
    ## end server nginx.test.com

上游:

    upstream test-nginx-80 {

        keepalive 32;

        server 10.8.252.203:80 max_fails=0 fail_timeout=0;
        server 10.8.253.26:80 max_fails=0 fail_timeout=0;
        server 10.8.252.201:80 max_fails=0 fail_timeout=0;
        server 10.8.253.25:80 max_fails=0 fail_timeout=0;
        server 10.8.252.204:80 max_fails=0 fail_timeout=0;
        server 10.8.253.24:80 max_fails=0 fail_timeout=0;
        server 10.8.252.205:80 max_fails=0 fail_timeout=0;
        server 10.8.252.206:80 max_fails=0 fail_timeout=0;
        server 10.8.253.27:80 max_fails=0 fail_timeout=0;
        server 10.8.253.28:80 max_fails=0 fail_timeout=0;

    }

让我们删除test-ingress-1 Ingress 资源

# kubectl -n test delete ing test-ingress-1
ingress.extensions "test-ingress-1" deleted

Ingress 仍在工作:

# curl -H "Host: nginx.test.com" http://10.8.255.243:80/foo
<!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>

因此,您可以根据需要创建任意数量的类似 Ingress 资源(如果使用 nginx-ingress-controller)

统一更新: 让我们在同一个命名空间中再创建一个部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache
  namespace: test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: apache
  template:
    metadata:
      labels:
        app: apache
    spec:
      containers:
      - name: frontend
        image: httpd
        ports:
        - containerPort: 80

还有一项服务

apiVersion: v1
kind: Service
metadata:
  name: apache
  namespace: test
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: apache
  type: ClusterIP

接下来让我们更改 Ingress 资源test-ingress-2

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  namespace: test
  name: test-ingress-2
  annotations:
    kubernetes.io/ingress.class: "service"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: nginx.test.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: apache # <-------
          servicePort: 80

最后命名空间test 包含这个资源列表:

# kubectl -n test get all
NAME                                 READY   STATUS    RESTARTS   AGE
pod/apache-cfdf8d79c-2m666           1/1     Running   0          13m
pod/apache-cfdf8d79c-d995s           1/1     Running   0          13m
pod/apache-cfdf8d79c-tq8d7           1/1     Running   0          13m
pod/nginx-65f88748fd-6w6fj           1/1     Running   0          45h
pod/nginx-65f88748fd-8fp7p           1/1     Running   0          45h
pod/nginx-65f88748fd-c7j29           1/1     Running   0          45h
pod/nginx-65f88748fd-frsbq           1/1     Running   0          46h
pod/nginx-65f88748fd-p4zvm           1/1     Running   0          45h
pod/nginx-65f88748fd-pd8gv           1/1     Running   0          45h
pod/nginx-65f88748fd-rkcjl           1/1     Running   0          45h
pod/nginx-65f88748fd-rn49k           1/1     Running   0          45h
pod/nginx-65f88748fd-w9dz8           1/1     Running   0          45h
pod/nginx-65f88748fd-xh42v           1/1     Running   0          45h

NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/apache   ClusterIP   10.8.254.47    <none>        80/TCP    12m
service/nginx    ClusterIP   10.8.254.218   <none>        80/TCP    12d

# kubectl -n test get ing
NAME             HOSTS            ADDRESS   PORTS   AGE
test-ingress-1   nginx.test.com             80      9m15s
test-ingress-2   nginx.test.com             80      54s

入口控制器的nginx.conf 显示两个上游列表

    upstream test-apache-80 {

        keepalive 32;

        server 10.8.253.31:80 max_fails=0 fail_timeout=0;
        server 10.8.252.208:80 max_fails=0 fail_timeout=0;
        server 10.8.253.32:80 max_fails=0 fail_timeout=0;

    }

    upstream test-nginx-80 {

        keepalive 32;

        server 10.8.252.204:80 max_fails=0 fail_timeout=0;
        server 10.8.252.205:80 max_fails=0 fail_timeout=0;
        server 10.8.253.27:80 max_fails=0 fail_timeout=0;
        server 10.8.253.25:80 max_fails=0 fail_timeout=0;
        server 10.8.253.24:80 max_fails=0 fail_timeout=0;
        server 10.8.252.206:80 max_fails=0 fail_timeout=0;
        server 10.8.253.26:80 max_fails=0 fail_timeout=0;
        server 10.8.252.203:80 max_fails=0 fail_timeout=0;
        server 10.8.253.28:80 max_fails=0 fail_timeout=0;
        server 10.8.252.201:80 max_fails=0 fail_timeout=0;

    }

但它只代理其中一个的请求

    ## start server nginx.test.com
    server {
        server_name nginx.test.com ;

        listen 80;

        listen [::]:80;

        set $proxy_upstream_name "-";

        location ~* ^/foo\/?(?<baseuri>.*) {

            set $namespace      "test";
            set $ingress_name   "test-ingress-1"; <------
            set $service_name   "nginx";
            set $service_port   "80";
            set $location_path  "/foo";

...

            rewrite /foo/(.*) /$1 break;
            rewrite /foo / break;
            proxy_pass http://test-nginx-80;  <-------

            proxy_redirect                          off;
# curl -H "Host: nginx.test.com" http://10.8.255.243:80/foo
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

每个入口资源都按照创建时间出现在那里。删除 Ingress 资源

ingress.networking.k8s.io "test-ingress-1" deleted

使入口控制器代理流量到 Apache 上游

# curl -H "Host: nginx.test.com" http://10.8.255.243:80/foo
<html><body><h1>It works!</h1></body></html>

为了清楚起见,我们可以以相反的顺序重新创建 Ingress 资源:

# kubectl -n test delete ing test-ingress-1 test-ingress-2
ingress.extensions "test-ingress-1" deleted
ingress.extensions "test-ingress-2" deleted

# kubectl -n test create -f /tmp/ing2.yaml
ingress.networking.k8s.io/test-ingress-2 created # Apache
# kubectl -n test create -f /tmp/ing1.yaml
ingress.networking.k8s.io/test-ingress-1 created # Nginx

# curl -H "Host: nginx.test.com" http://10.8.255.243:80/foo
<html><body><h1>It works!</h1></body></html> # Apache

还有一点: 在某些情况下会重新加载入口控制器的配置,我的意思是它何时重新加载配置以及它实际上如何重新加载配置?但这是一个完全不同的问题......

【讨论】:

  • 感谢您抽出宝贵时间在 Konstantin 进行测试和更新。我想知道如果使用相同的主机/路径但使用不同的后端服务添加两个 Ingress 规则,它将如何表现。会被最新的覆盖吗?还是会失败?
  • @Amudhan 我已经更新了答案。希望现在清楚了!)
  • 感谢康斯坦丁。因此,创建/删除顺序决定了流量将被路由到哪个后端服务。我希望入口控制器中至少有一条警告日志消息。
  • 如果流量路由与您在 Ingress 资源中描述的一样,为什么会发出警告?
  • 我的意思是,当添加第二个定义相同规则(主机/路径)但后端服务不同的 Ingress 资源时,实际上是用户创建的冲突。创建/删除入口的顺序决定了哪个服务将接收流量。这是一个很好的 QA 测试用例,但不是理想的设置,对吧?所以,这就是我提到这一点的原因,如果 Ingress 控制器发出一个警告日志,上面写着“冲突 Ingress 资源”之类的东西,那就太好了。我说得通吗?
【解决方案2】:

如果您的意思是具有相同控制器的 Ingress 对象:通常没有什么有趣的,大多数去重冗余路由。

如果您的意思是两个控制器各自指向一个不同(但相同)的入口:两个控制器都使用请求的路由设置自己。他们完全独立,对彼此一无所知。

【讨论】:

  • 抱歉含糊不清,我的意思是具有相同配置的多个入口对象,你能详细说明重复冗余路由的含义吗?这是否意味着请求由两个对象复制和处理,或由任何一个对象处理。
  • 实际上,在多个入口控制器的情况下,所有入口控制器都会为创建的对象而战。他们不会和谐地工作。这就是为什么你要在注释中写下要使用的 IC。
  • @suren 他们并没有真正为它争吵(除了在状态中晃动地址字段),他们只是实现了路由。除了一个状态字段之外,他们没有可以争论的外部状态。通常这是不需要的,但两个代理都是完全独立的。
  • @coderanger 对。但我的观点是,它会导致不一致的行为。
【解决方案3】:

入口控制器(无论是 nginx 还是 haproxy 或任何其他控制器)或多或少都以相同的方式工作。如果创建或修改了 Ingress 对象,它们会侦听该对象,并且对于 ingress 中的每个主机/路径,它们会创建一条规则,说明如果请求到达具有该特定主机/路径的 Ingress 控制器,它应该将流量转发到为该路径配置的服务。

因此,在您的示例中,您是说要添加多个具有相同主机/路径配置的 Ingress 对象,这些对象指向同一服务。我认为这取决于 Ingress 控制器的实现;他们想如何处理重复的 Ingress 规则。为同一个主机名添加重复的规则是没有意义的(不管它是指向同一个服务还是不同的服务,但如果后端服务不同,这是一个更大的问题/歧义)。

但我会假设,即使 Ingress 控制器允许此类配置并为同一主机/路径编写多个规则,它也不会进行多路复用。可能它会匹配第一条规则并转发到它后面的服务。

它如何确定路由到哪个服务?它基于流量到达 Ingress 控制器的主机名。

您可以轻松检查行为。执行到控制器并查看其 conf 文件。对于 nginx 入口控制器,conf 文件将在 /etc/nginx/nginx.conf 中,它将定义规则和操作。

【讨论】:

    【解决方案4】:

    我们曾遇到过生产中需要这种配置的情况。这就是我看到它起作用的方式。当您创建第二个入口时,除了入口名称之外的所有内容都相同,它不会影响任何东西。只有在我删除了第一个入口后,我创建的第二个入口才接管了控制权。因此,如果设置是相同的,它不会覆盖或重复,看起来第一个创建的总是具有优先权。

    【讨论】:

      猜你喜欢
      • 2021-11-20
      • 1970-01-01
      • 1970-01-01
      • 2016-01-18
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 2020-05-09
      • 2011-11-25
      相关资源
      最近更新 更多