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

8yparm6h  于 2023-08-03  发布在  Kubernetes
关注(0)|答案(1)|浏览(99)

我无法将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

编辑:07/03/2023

我发现我阅读了错误的文档,因此使用了不正确的清单语法。我能够修复路由问题,但现在我没有看到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

mkshixfv

mkshixfv1#

您的入口资源存在几个问题。
首先,正如我在评论中提到的,规则是按顺序处理的。如果第一个规则是匹配/的前缀规则,那么它将匹配everything;其他的规则不重要。
接下来,对前两个/hermes*路径使用了Exact规则,但在使用尾随斜杠时并不一致。您有:

  • /hermes
  • /hermes2/
  • /hermes3/

注意尾部/的不一致使用。这意味着:

  1. /hermes的请求将与/hermes的规则匹配。
  2. /hermes/的请求不会匹配任何东西。
  3. /hermes2的请求不会匹配任何东西。
  4. /hermes2/的请求将与/hermes2/的规则匹配。
    1.对/hermes3的请求不会匹配任何内容。
    1.对/hermes3/的请求将匹配/hermes3/的规则。
  5. /hermes3/foo的请求将与/hermes3/的规则匹配。
    如果你希望/hermes/hermes/都去同一个地方...好吧,欢迎来到Traefik issue #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

注意:Traefik在引用Middleware时,需要在前面添加部署Ingress的Namespace;我将上面的清单部署到一个名为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以路径/a/b/c转到api-server
  • http://dev.mywebsite.io/hermes/a/b/c转到路径为/a/b/chermes
  • http://dev.mywebsite.io/hermes2/a/b/c以路径/a/b/c转到hermes
  • http://dev.mywebsite.io/hermes3/a/b/c以路径/a/b/c转到hermes

对于这些结果,我们添加一个stripPrefix middleware,如下所示:

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


我们这样写:

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-slashstrip-prefix中间件。
我已经更新了the linked repository和包含的测试。

相关问题