当 URI 有参数(“?”)或上传后,入口 nginx 路径返回为 "Bad Gateway"

ingress-nginx path comes back as "Bad Gateway" when URI has parameters ("?") or after upload

我正在将一个 PHP 应用程序移动到 Kubernetes 中,并在执行一些操作后 运行 将其移动到 "Bad Gateway" 中。

我认为错误来自两件事之一:

我怀疑它是最后一个,因为这个 Excel 文件只有 14kb。

发生的事情是用户有一个 Excel 模板来导入新帐户。他们转到管理门户 /admin、select 进行导入,它解析 Excel 文件,然后导入到 Postgres。

尽管出现此错误,数据仍在进入数据库。成功导入后,一个GET被发送到a_merge_xls_db.php?tmp_tbl=_imp_companies_20200329_160813。那是 "Bad Gateway" 在大约 7 秒后出现的时候。

似乎这可能是我的 ingress.yaml 中的一个问题,因为 ingress-nginx abd 处理 ?=_ 之类的。我已经尝试了一些方法,但仍然无法解决问题。

这是我在 ingress.yaml 中的内容:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/add-base-url: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: 500mb
  name: ingress-service
  namespace: default
spec:
  rules:
    - http:
        paths:
          - path: /?(.*)
            backend:
              serviceName: client-cluster-ip-service-dev
              servicePort: 3000
          - path: /admin/?(.*)
            backend:
              serviceName: admin-cluster-ip-service-dev
              servicePort: 4000
          - path: /api/?(.*)
            backend:
              serviceName: api-cluster-ip-service-dev
              servicePort: 5000

有什么建议吗?

附加信息 2020 年 3 月 30 日

我将 Dockerfile.devadmin.yaml 包括在内,因为我仍然遇到问题:

# Dockerfile.dev

FROM php:7.3-fpm
EXPOSE 4000
RUN apt-get update \ 
    && apt-get install -y libpq-dev zlib1g-dev libzip-dev \
    && docker-php-ext-install pgsql zip
COPY . /app
WORKDIR /app/src
CMD ["php", "-S", "0.0.0.0:4000"]
# admin.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: admin-deployment-dev
spec:
  replicas: 1
  selector:
    matchLabels:
      component: admin
  template:
    metadata:
      labels:
        component: admin
    spec:
      containers:
        - name: admin
          image: testappacr.azurecr.io/test-app-admin
          ports:
            - containerPort: 4000
          env:
            - name: PGUSER
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: PGUSER
            - name: PGHOST
              value: postgres-cluster-ip-service-dev
            - name: PGPORT
              value: "1423"
            - name: PGDATABASE
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: PGDATABASE
            - name: PGPASSWORD
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: PGPASSWORD
            - name: SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: SECRET_KEY
            - name: SENDGRID_API_KEY
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: SENDGRID_API_KEY
            - name: DOMAIN
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: DOMAIN           
            - name: DEBUG
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: DEBUG
          volumeMounts:
          - mountPath: "/docs/"
            name: file-storage
      volumes:
        - name: file-storage
          persistentVolumeClaim:
            claimName: file-storage
---
apiVersion: v1
kind: Service
metadata:
  name: admin-cluster-ip-service-dev
spec:
  type: ClusterIP
  selector:
    component: admin
  ports:
    - port: 4000
      targetPort: 4000

如果我只有 - path: /admin,我会遇到无法提供资产的问题。 .css.js200 一样返回,但没有任何应用程序。如果我导航到资产的 URL,例如 http://192.168.39.129/admin/css/portal.css,它只会显示您转到 /admin.

时获得的页面

这个问题通过改回 - path: /admin/?(.*) 得到解决,但后来我 运行 进入了我最初发布的问题。

整个早上我都在玩各种正则表达式,但在 "Bad Domain".

时仍然得到相同的结果

考虑到我正在学习 Kubernetes,我可能会忽略一些东西。考虑到 coderanger 的建议,它似乎真的应该工作,这个问题也反映了同样的事情:

https://github.com/kubernetes/ingress-nginx/issues/3380

您需要指定 nginx.ingress.kubernetes.io/use-regex: "true" 注释。这是因为默认情况下 Kubernetes Ingress 对象需要普通前缀匹配,而不是正则表达式。或者在您的情况下,只需使用实际前缀 //admin/api.