最近需要再k8s环境中使用ingress来将不同的域名路由到不同的服务上面, 同时还有泛域名路由和IP路由。  在添加ingress 的时候就遇到了解析顺序和优先级的问题。

ingress路由IP: 直接添加一个没有Host的ing规则即可;

泛域名(主机名通配符):解析直接添加一个主机名为 *.domain.com的即可。

问题: 在ingress规则中同时添加了 aaa.domain.com  和 *.domain.com 之后 所有的aaa.domain.com 流量都会被路由到 *.domain.com 即 aaa对应的ing配置无效。 不管你的*.domain.com的顺序在前面还是后面aaa都无效,

代码如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: default-ing
  labels:
    app: ingress
    name: default-ing
  namespace: default
spec:
  defaultBackend:
    service:
      name: nginx
      port:
        number: 80
  ingressClassName: traefik
  rules:
    - host: domain.com
      http:
        paths:
          - backend:
              service:
                name: nginx
                port:
                  number: 80
            pathType: ImplementationSpecific
            path: ''
    - host: '*.domain.com'
      http:
        paths:
            backend:
              service:
                port:
                  number: 80
                name: nginx
            path: ''
            pathType: ImplementationSpecific
    - host: php82.domain.com
      http:
        paths:
            backend:
              service:
                port:
                  number: 9000
                name: php82
            path: ''
            pathType: ImplementationSpecific

解决方法:

将 *.domain.com的规则 pathType更改为 Exact , 更改后即可正常解析 aaa.domain.com 和 *.domain.com

更改后如下:

    - host: '*.domain.com'
      http:
        paths:
            backend:
              service:
                port:
                  number: 80
                name: nginx
            path: /
            pathType: Exact

相关官方文档说明:

Ingress | Kubernetes使用一种能感知协议配置的机制来理解 URI、主机名称、路径和更多 Web 概念,使得 HTTP(或 HTTPS)网络服务可用。 Ingress 概念允许你通过 Kubernetes API 定义的规则将流量映射到不同的后端。https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/

Ingress 规则

每个 HTTP 规则都包含以下信息:

  • 可选的 host。在此示例中,未指定 host,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 通信。 如果提供了 host(例如 foo.bar.com),则 rules 适用于该 host
  • 路径列表(例如 /testpath),每个路径都有一个由 service.name 和 service.port.name 或 service.port.number 定义的关联后端。 在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。
  • backend(后端)是 Service 文档中所述的服务和端口名称的组合, 或者是通过 CRD 方式来实现的自定义资源后端。 与规则的 host 和 path 匹配的对 Ingress 的 HTTP(和 HTTPS )请求将发送到列出的 backend

通常在 Ingress 控制器中会配置 defaultBackend(默认后端),以服务于无法与规约中 path 匹配的所有请求。

路径类型

Ingress 中的每个路径都需要有对应的路径类型(Path Type)。未明确设置 pathType 的路径无法通过合法性检查。当前支持的路径类型有三种:

  • ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。

  • Exact:精确匹配 URL 路径,且区分大小写。

  • Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写,并且对路径中的元素逐个完成。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。

    说明: 如果路径的最后一个元素是请求路径中最后一个元素的子字符串,则不会匹配 (例如:/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz)。

示例

类型路径请求路径匹配与否?
Prefix/(所有路径)
Exact/foo/foo
Exact/foo/bar
Exact/foo/foo/
Exact/foo//foo
Prefix/foo/foo/foo/
Prefix/foo//foo/foo/
Prefix/aaa/bb/aaa/bbb
Prefix/aaa/bbb/aaa/bbb
Prefix/aaa/bbb//aaa/bbb是,忽略尾部斜线
Prefix/aaa/bbb/aaa/bbb/是,匹配尾部斜线
Prefix/aaa/bbb/aaa/bbb/ccc是,匹配子路径
Prefix/aaa/bbb/aaa/bbbxyz否,字符串前缀不匹配
Prefix//aaa/aaa/ccc是,匹配 /aaa 前缀
Prefix//aaa/aaa/bbb/aaa/bbb是,匹配 /aaa/bbb 前缀
Prefix//aaa/aaa/bbb/ccc是,匹配 / 前缀
Prefix/aaa/ccc否,使用默认后端
混合/foo (Prefix), /foo (Exact)/foo是,优选 Exact 类型

多重匹配

在某些情况下,Ingress 中的多条路径会匹配同一个请求。 这种情况下最长的匹配路径优先。 如果仍然有两条同等的匹配路径,则精确路径类型优先于前缀路径类型。

主机名通配符

主机名可以是精确匹配(例如 “foo.bar.com”)或者使用通配符来匹配 (例如 “*.foo.com”)。 精确匹配要求 HTTP host 头部字段与 host 字段值完全匹配。 通配符匹配则要求 HTTP host 头部字段与通配符规则中的后缀部分相同。

主机host 头部匹配与否?
*.foo.combar.foo.com基于相同的后缀匹配
*.foo.combaz.bar.foo.com不匹配,通配符仅覆盖了一个 DNS 标签
*.foo.comfoo.com不匹配,通配符仅覆盖了一个 DNS 标签

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐