【问题标题】:Rewrites with path regex are not working in EKS and nginx ingress controller使用路径正则表达式重写在 EKS 和 nginx 入口控制器中不起作用
【发布时间】:2021-02-28 11:19:50
【问题描述】:

我正在使用带有 kubernetes 1.18 版和 nginx igress 控制器的 EKS 集群。我在 delpoyment、服务和入口资源下创建了我注意到入口资源不适用于带有正则表达式的路径,并且它总是从入口控制器本身返回 404,而不将请求传递给后端 pod。我已经使用 describe 验证了我能够看到正确的后端。

你能帮忙吗?

deployment.yaml

apiVersion: apps/v1
   kind: Deployment
   metadata:
      name: "wildfly"
      namespace: "sit-web-n"
   spec:
      selector:
        matchLabels:
        app: "wildfly"
      replicas: 1
      template:
        metadata:
      labels:
        app: "wildfly"
     spec:
      containers:
      - image: <account>.dkr.ecr.eu-west-1.amazonaws.com/ecr-test:wildfly
        imagePullPolicy: Always
        name: "wildfly"
        env:
        - name: JAVA_OPTS
          value: "-Xms128m -Xmx768m"
        ports:
        - containerPort: 8080

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: "wildfly"
  namespace: "sit-web-n"
spec:
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
  type: NodePort
  selector:
    app: "wildfly"

ingress.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: wildfly
  namespace: "sit-web-n"
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  ingressClassName: nginx
  tls:
    - hosts:
      - wildfly.eks-test.co.uk
      secretName: tls-secret
   rules:
   - host: wildfly.eks-test.co.uk
    http:
      paths:
      - path: /customer-svc/?(.*)
        pathType: Prefix
        backend:
          serviceName: wildfly
          servicePort: 8080

后端服务

kubectl describe svc wildfly  -n sit-web-n
Name:                     wildfly
Namespace:                sit-web-n
Labels:                   <none>
Annotations:              Selector:  app=wildfly
Type:                     NodePort
IP:                       10.100.78.242
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  31350/TCP
Endpoints:                192.168.0.89:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
[test]#

入口

 kubectl describe ingress wildfly  -n sit-web-n
   Name:             wildfly
   Namespace:        sit-web-n
   Address:
   Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
    TLS:
     tls-secret terminates wildfly.eks-test.co.uk
    Rules:
     Host                    Path  Backends
      ----                    ----  --------
     wildfly.eks-test.co.uk
                            /customer-svc/?(.*)   wildfly:8080 (192.168.0.89:8080)
   Annotations:              nginx.ingress.kubernetes.io/force-ssl-redirect: false
                             nginx.ingress.kubernetes.io/rewrite-target: /$1
                             nginx.ingress.kubernetes.io/ssl-redirect: false
    Events:
     Type    Reason          Age   From                      Message
      ----    ------          ----  ----                      -------
      Normal  AddedOrUpdated  14m   nginx-ingress-controller  Configuration for sit-web-n/wildfly was added or updated

卷曲输出

curl -ik -H 'Host: wildfly.eks-test.co.uk' https://ip-192-168-0-101.eu-west-1.compute.internal/custom- 
   svc/health
    HTTP/1.1 404 Not Found
    Server: nginx
    Date: Tue, 17 Nov 2020 08:31:08 GMT
   Content-Type: text/html
   Content-Length: 146
   Connection: keep-alive
   Strict-Transport-Security: max-age=15724800; includeSubDomains; preload

   <html>
   <head><title>404 Not Found</title></head>
   <body>
   <center><h1>404 Not Found</h1></center>
   <hr><center>nginx</center>
   </body>
   </html>



nginx ingress controller logs -

2020/11/17 08:49:44 [error] 52#52: *17 open() "/etc/nginx/html/custom-svc/health" failed (2: No such file or directory), client: 172.31.0.183, server: wildfly.eks-test.co.uk, request: "GET /custom-svc/health HTTP/1.1", host: "wildfly.eks-test.co.uk"
wildfly.eks-test.co.uk 172.31.0.183 - - [17/Nov/2020:08:49:44 +0000] GET /custom-svc/health HTTP/1.1 404 146 0.000 - curl/7.61.1 - - -
2020/11/17 08:49:48 [error] 52#52: *18 open() "/etc/nginx/html/custom-svc/health" failed (2: No such file or directory), client: 172.31.0.183, server: wildfly.eks-test.co.uk, request: "GET /custom-svc/health HTTP/1.1", host: "wildfly.eks-test.co.uk"
wildfly.eks-test.co.uk 172.31.0.183 - - [17/Nov/2020:08:49:48 +0000] GET /custom-svc/health HTTP/1.1 404 146 0.000 - curl/7.61.1 - - -
   

【问题讨论】:

  • 1。你的控制器版本是什么。 2。这些日志看起来不是来自 nginx 入口控制器,而是来自您的后端。 3。您在 curl 命令中使用此路径“custom-svc/health”而不是 path: /customer-svc/4 请使用curl 直接在后端验证您的路径,例如curl localhost:8080/customer-svc/health vs curl localhost:8080/custom-svc/health 使用rewrite-target 它应该是curl localhost:8080/health

标签: kubernetes kubernetes-ingress nginx-ingress amazon-eks


【解决方案1】:

如评论中所述:

1。在 ingress 资源 中,您有 defined pathcustomer-svc 同时尝试访问 custom-svc

2"/etc/nginx/html/custom-svc/health" failed (2: No such file or directory)"。通常这样的错误会告诉我们底层后端没有这样的路径(对于 nginx 入口控制器来说很奇怪)。


很难想象所有的可能性,但请尝试遵循这一点:

确保您已安装并配置了正确的 nginx 控制器。不同的控制器和版本具有不同的配置和选项,例如:

注意从版本 0.22.0 开始,使用注解 nginx.ingress.kubernetes.io/rewrite-target 的入口定义与以前的版本不向后兼容。在版本 0.22.0 及更高版本中,请求 URI 中需要传递到重写路径的任何子字符串都必须在 capture group. 中明确定义

另外请看一下:

您可以将特定的 IngressClass 标记为集群的默认值。在 IngressClass 资源上将 ingressclass.kubernetes.io/is-default-class 注释设置为 true 将确保未指定 ingressClassName 字段的新 Ingress 将被分配此默认 IngressClass。


更新

如上所述:“不同的控制器和版本有不同的配置和选项”。 您使用的 nginxinc kubernetes-ingress controllerkubernetes/ingress-nginx 存储库中的 NGINX Ingress 控制器 不同。请查看此doc 以了解主要区别。

那些注释:

nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /$1

取自nginx-ingress (kubernetes),因此不适用于nginxinc kubernetes-ingress controller

作为uri重写的例子,请使用nginx.org/rewrites注解:

annotations:
  nginx.org/rewrites: "serviceName=wildfly rewrite=/"

此外,对于使用 nginxinc kubernetes-ingress 控制器 和正则表达式和高级路由支持,请查看VirtualServer.Route 自定义资源定义 (CRD) 概念。此功能需要在控制器安装期间安装/配置CRD support

Here 你可以找到完整的指南,如何使用 VirtualServer CRD 为 nginxinc kubernetes-ingress 控制器配置它。


附加信息:

教程:

【讨论】:

  • 感谢您的回复,我正在使用 kubernetes-ingress (nginxinc)(github.com/nginxinc/kubernetes-ingress/tree/master/deployments/…) 并使用 helm chart 部署了入口控制器,当我在路径中使用正则表达式时,我已经通过 pod 的访问日志进行了验证并且 rewrite-target 因为 $1 请求没有被转发到后端,而是在本地路径(nginx 的文档根目录)中搜索。
  • 谢谢马克,它成功了,我能够得到想要的结果,我还将通过虚拟服务器和虚拟服务器路由
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2019-01-16
  • 2018-01-08
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
相关资源
最近更新 更多