Kubernetes 入口控制器 Traefik 路由无法正常工作

问题描述 投票:0回答:1

我无法配置 Traefik ingress 按预期工作。

我想看到 3 个不同的服务在路径

/
/api-server
/hermes
上运行。但无论出于何种原因,我在所有路径中都只看到一个应用程序 (theia-svc)。

k8.ingress-traefik.yml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/force-ssl-redirect: "false"
    ingress.kubernetes.io/ssl-redirect: "true"
    cert-manager.io/cluster-issuer: letsencrypt
    # traefik.ingress.kubernetes.io/rewrite-target: "/"
    # traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
    traefik.ingress.kubernetes.io/app-root: "/"
    # traefik.ingress.kubernetes.io/frontend-entry-points: "http,https"

  name: traefik-ingress
spec:
  ingressClassName: traefik
  rules:
    - host: dev.mywebsite.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: theia-svc
                port:
                  number: 80
          - path: /api-server
            pathType: Prefix
            backend:
              service:
                name: api-server-svc
                port:
                  number: 8082
          - path: /hermes
            pathType: Exact
            backend:
              service:
                name: hermes-svc
                port:
                  number: 8000
          - path: /hermes2/
            pathType: Exact
            backend:
              service:
                name: hermes-svc
                port:
                  number: 8000
          - path: /hermes3/
            pathType: Prefix
            backend:
              service:
                name: hermes-svc
                port:
                  number: 8000
  tls:
    - hosts:
        - dev.mywebsite.io
      secretName: tls-secret

kubectl get service
抓取IP进行测试:

NAME             TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE     SELECTOR
api-server-svc   LoadBalancer   10.104.36.20    23.29.118.63   8082:32017/TCP   137m    app=api-server-pod
hermes-svc       ClusterIP      10.106.25.215   <none>         8000/TCP         67m     app=hermes-pod
kubernetes       ClusterIP      10.96.0.1       <none>         443/TCP          5h36m   <none>
theia-svc        ClusterIP      10.96.41.226    <none>         80/TCP           5h7m    app=theia-pod

curl 10.106.25.215:8000
测试 hermes-svc:

<!DOCTYPE html><html>...</html>

浏览器中的结果:

- https://dev.mywebsite.io/api-server    => 404
- https://dev.mywebsite.io/              => theia-svc
- https://dev.mywebsite.io/hermes        => theia-svc
- https://dev.mywebsite.io/hermes/       => theia-svc
- https://dev.mywebsite.io/hermes2       => theia-svc
- https://dev.mywebsite.io/hermes2/      => 404
- https://dev.mywebsite.io/hermes3       => theia-svc
- https://dev.mywebsite.io/hermes3/      => 404

编辑:2023年7月3日

我发现我阅读了错误的文档,因此使用了错误的清单语法。我能够修复路由问题,但现在我没有看到应用 TLS (https) 证书,而之前的清单中路由损坏的情况就是如此。

新的k8.ingress-traefik.yml

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-ingressroute
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - match: Host(`dev.mywebsite.io`) && PathPrefix(`/api-server`)
      kind: Rule
      services:
        - name: api-server-svc
          port: 8082
      middlewares:
        - name: stripprefix
    - match: Host(`dev.mywebsite.io`) && PathPrefix(`/hermes`)
      kind: Rule
      services:
        - name: hermes-svc
          port: 8000
      middlewares:
        - name: stripprefix
  tls:
    certResolver: myresolver
    options:
      name: traefik-tls-option
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: stripprefix
spec:
  stripPrefix:
    prefixes:
      - /api-server
      - /hermes
---
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
  name: traefik-tls-option
spec:
  minVersion: VersionTLS12
  cipherSuites:
    - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
    - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
    - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  curvePreferences:
    - CurveP521
    - CurveP384
  sniStrict: true
kubernetes routes kubernetes-ingress traefik traefik-ingress
1个回答
-1
投票

您的入口资源存在多个问题。

首先,正如我在评论中指出的,规则是按顺序处理的。如果您的第一条规则是匹配 / 的前缀规则,那么它将匹配

everything
;其他规则并不重要。 接下来,您对前两个

Exact

路径使用

/hermes*
规则,但尾部斜杠的使用不一致。你有:

    /hermes
  • /hermes2/
  • /hermes3/
  • 
    
  • 请注意尾随
/

的使用不一致。这意味着:


    /hermes
  1. 的请求将匹配
    /hermes
    的规则。
  2. /hermes/
  3. 的请求不会匹配任何内容。
  4. /hermes2
  5. 的请求不会匹配任何内容。
  6. /hermes2/
  7. 的请求将匹配
    /hermes2/
    的规则。
  8. /hermes3
  9. 的请求不会匹配任何内容。
  10. /hermes3/
  11. 的请求将匹配
    /hermes3/
    的规则。
  12. /hermes3/foo
  13. 的请求将匹配
    /hermes3/
    的规则。
    
    
  14. 如果您期望
/hermes

/hermes/
去同一个地方...好吧,欢迎来到
Traefik 问题#5159
(以及#563、#4521、#3330、#4804、#3852) 、#1037 等)。 根据您的要求,最简单的解决方案可能是将您的

Exact

规则替换为

Prefix
规则。如果我们改为编写(我已删除 SSL 配置,因为它与这些测试无关):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: traefik-ingress
spec:
  ingressClassName: traefik
  rules:
    - host: dev.mywebsite.io
      http:
        paths:
          - path: /api-server
            pathType: Prefix
            backend:
              service:
                name: api-server-svc
                port:
                  number: 8082
          - path: /hermes
            pathType: Prefix
            backend:
              service:
                name: hermes-svc
                port:
                  number: 8000
          - path: /
            pathType: Prefix
            backend:
              service:
                name: theia-svc
                port:
                  number: 80

然后我们得到:

- http://dev.mywebsite.io/api-server => api - http://dev.mywebsite.io/ => theia - http://dev.mywebsite.io/hermes => hermes - http://dev.mywebsite.io/hermes/ => hermes - http://dev.mywebsite.io/hermes2 => hermes - http://dev.mywebsite.io/hermes2/ => hermes - http://dev.mywebsite.io/hermes3 => hermes - http://dev.mywebsite.io/hermes3/ => hermes

当然,这也意味着我们得到:

- http://dev.mywebsite.io/hermes113 => hermes - http://dev.mywebsite.io/hermes_was_dog => hermes

等等

或者,您可以通过引入一些正则表达式中间件来解决尾部斜杠问题。鉴于这些清单:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: traefik.ingress.kubernetes.io/router.middlewares: example-add-trailing-slash@kubernetescrd labels: app: traefik-example name: traefik-ingress spec: ingressClassName: traefik rules: - host: dev.mywebsite.io http: paths: - backend: service: name: api-server-svc port: number: 8082 path: /api-server pathType: Prefix - backend: service: name: hermes-svc port: number: 8000 path: /hermes/ pathType: Exact - backend: service: name: hermes-svc port: number: 8000 path: /hermes2/ pathType: Exact - backend: service: name: hermes-svc port: number: 8000 path: /hermes3/ pathType: Prefix - backend: service: name: theia-svc port: number: 80 path: / pathType: Prefix --- apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: labels: app: traefik-example name: add-trailing-slash spec: redirectRegex: permanent: true regex: ^https?://(.*)/(hermes[23]?)$ replacement: /${2}/

我们得到以下行为:

- http://dev.mywebsite.io/api-server => api - http://dev.mywebsite.io/ => theia - http://dev.mywebsite.io/hermes => hermes - http://dev.mywebsite.io/hermes/ => hermes - http://dev.mywebsite.io/hermes/foo => theia - http://dev.mywebsite.io/hermes2 => hermes - http://dev.mywebsite.io/hermes2/ => hermes - http://dev.mywebsite.io/hermes2/foo => theia - http://dev.mywebsite.io/hermes3 => hermes - http://dev.mywebsite.io/hermes3/ => hermes - http://dev.mywebsite.io/hermes3/foo => hermes - http://dev.mywebsite.io/hermes113 => theia - http://dev.mywebsite.io/hermes_was_a_dog => theia

NB

:请注意,在引用中间件时,Traefik 要求您添加部署 Ingress 的命名空间;我将上述清单部署到名为 example 的命名空间中,因此

add-trailing-slash
中间件被引用为
example-add-trailing-slash
在上面的示例中,请注意 

/hermes

/hermes/
都转到
hermes-svc
,但
/hermes/foo
,因为您使用的是 Exact 路径规则(对于
/hermes2
也类似)。
这对于 

/hermes3/foo

来说不是这样,因为在该规则中您使用的是

Prefix
匹配。 我已经整理了一个完整的示例

here

为了处理您最近的评论,我假设我们应该将所有内容都匹配为
Prefix

,而不是使用

Exact
,这样:

    http://dev.mywebsite.io/api-server/a/b/c
  • 前往
    api-server
    ,路径为
    /a/b/c
  • http://dev.mywebsite.io/hermes/a/b/c
  • 前往
    hermes
    ,路径为
    /a/b/c
  • http://dev.mywebsite.io/hermes2/a/b/c
  • 前往
    hermes
    ,路径为
    /a/b/c
  • http://dev.mywebsite.io/hermes3/a/b/c
  • 前往
    hermes
    ,路径为
    /a/b/c
    
    
  • 对于这些结果,我们添加一个

stripPrefix 中间件

,如下所示:
apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: strip-prefix spec: stripPrefix: forceSlash: false prefixes: - /api-server - /hermes2 - /hermes3 - /hermes

并像这样编写我们的 Ingress:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: traefik-ingress annotations: traefik.ingress.kubernetes.io/router.middlewares: example-add-trailing-slash@kubernetescrd,example-strip-prefix@kubernetescrd spec: ingressClassName: traefik rules: - host: dev.mywebsite.io http: paths: - path: /api-server pathType: Prefix backend: service: name: api-server-svc port: number: 8082 - path: /hermes pathType: Prefix backend: service: name: hermes-svc port: number: 8000 - path: /hermes2 pathType: Prefix backend: service: name: hermes-svc port: number: 8000 - path: /hermes3 pathType: Prefix backend: service: name: hermes-svc port: number: 8000 - path: / pathType: Prefix backend: service: name: theia-svc port: number: 80

请注意,我们在本例中同时使用了 
add-trailing-slash

strip-prefix
中间件。
我已经更新了

链接的存储库

和包含的测试。

© www.soinside.com 2019 - 2024. All rights reserved.