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

3/29/2020

I'm moving a PHP application into Kubernetes and running into a "Bad Gateway" after some actions are performed.

I'm thinking the error is from one of two things:

  • The PHP program is sending a GET to http://192.168.39.129/admin/a_merge_xls_db.php?tmp_tbl=_imp_companies_20200329_160813
  • Or from the upload itself

I doubt it is the last one because this Excel file is only 14kb.

What is going on is the user has an Excel template to import new accounts. They go to the admin portal /admin, select to import, it parses the Excel file, and imports into Postgres.

Despite this error, the data is making its way into the database. After it successfully imports, a GET is sent to a_merge_xls_db.php?tmp_tbl=_imp_companies_20200329_160813. That is when the "Bad Gateway" comes up after like 7 seconds.

Seems like it might be an issue in my ingress.yaml for ingress-nginx abd handling the ?=_ or something. I've tried a few things, but still am not able to resolve the issue.

Here is what I have in the 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: /$1
    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

Any suggestions?

ADDITIONAL INFO 3/30/20

I'm including the Dockerfile.dev and admin.yaml as I'm still having issues:

# 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

If I just have the - path: /admin, I have an issue where the assets are not being served. The .css and .js come back as with 200, but nothing is applied to the application. If I navigate to the URL of the asset, for example, http://192.168.39.129/admin/css/portal.css it just shows the page you get when you go to /admin.

This issue is resolved by changing back to - path: /admin/?(.*), but then I run into the issue I initially posted about.

I've been playing with various regex most of the morning, but still get the same results when it comes to the "Bad Domain".

I'm likely overlooking something given I'm learning Kubernetes. It really seems like it should be working given coderanger's suggestion and also this issue which echos the same thing:

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

-- eox.dev
kubernetes
nginx-ingress
php

1 Answer

3/30/2020

You need to specify the nginx.ingress.kubernetes.io/use-regex: "true" annotation. This is called out because by default Kubernetes Ingress objects expect plain prefix matching, not regexs. Or in your case, just use an actual prefix, /, /admin, and /api.

-- coderanger
Source: StackOverflow