Ingress-nginx: ingress 0.31.0 and 0.31.1 fails with duplicate location /

Created on 28 Apr 2020  路  3Comments  路  Source: kubernetes/ingress-nginx

NGINX Ingress controller version: 0.31.0 and 0.31.1

Kubernetes version (use kubectl version): 0.18.2

Environment:

  • Cloud provider or hardware configuration: none, using metallb on 3x vm's
  • OS (e.g. from /etc/os-release): ubuntu 20.04
  • Kernel (e.g. uname -a):5.4.0-26-generic
  • Install tools:
  • Others:

What happened:

I am trying to apply the following ingress resource on the nginx controller 0.31.0 (and also 0.31.1):

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: registry
  namespace: container-registry
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: my-container-registry.dk
      http:
        paths:
          - path: /
            backend:
              serviceName: registry
              servicePort: 443
EOF

kubectl returns the following error message:

admission webhook "validate.nginx.ingress.kubernetes.io" denied the request:
-------------------------------------------------------------------------------
Error: exit status 1
2020/04/28 11:26:56 [emerg] 193#193: duplicate location "/" in /tmp/nginx-cfg165130373:552
nginx: [emerg] duplicate location "/" in /tmp/nginx-cfg165130373:552
nginx: configuration file /tmp/nginx-cfg165130373 test failed

What you expected to happen:

I would expect that the ingress resource was created.

It works if I change the path to something different, and it also works if I downgrade the controller image version to 0.30.0.

I am not sure, but it could possibly have something to do with these lines.

How to reproduce it:

  • Install a clean cluster using kubeadm, kubernetes v. 1.18.2
  • Install metallb:
kubectl create namespace metallb
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
  • Install nginx ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.31.1/deploy/static/provider/cloud/deploy.yaml
  • Create an ingress
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: registry
  namespace: container-registry
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: my-container-registry.dk
      http:
        paths:
          - path: /
            backend:
              serviceName: registry
              servicePort: 443
EOF

This call will fail with the "duplicate location /" error.

  • Change the path to something different
kubectl edit ingress -n container-registry registry

Change the path to /sub and re-apply the service resource.

Attach to the controller pod and take a look at /etc/nginx/nginx.conf. It contains:

...
server {
                server_name my-container-registry.dk;

                listen 80  ;
                listen 443  ssl http2 ;

                set $proxy_upstream_name "-";

                ssl_certificate_by_lua_block {
                        certificate.call()
                }

                location /sub {

                        set $namespace      "container-registry";
                        set $ingress_name   "registry";
                        set $service_name   "registry";
                        set $service_port   "443";
                        set $location_path  "/sub";

                        ...
                }

                location / {

                        set $namespace      "";
                        set $ingress_name   "";
                        set $service_name   "";
                        set $service_port   "";
                        set $location_path  "/";

                        ...
                }
}
...

Note that the / location is added by default with default values - I guess this is causing the duplicate error message

  • Downgrade to controller version to 0.30.0
kubectl edit deployment -n ingress-nginx ingress-nginx-controller

Change image to quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 and wait for the controller to come up using the new image

Re-apply the ingress with the path set back to / - this time the ingress resource will return: "ingress.networking.k8s.io/registry configured"

kinbug

Most helpful comment

I've upgraded to 0.31.1 today on my test cluster and I've had the same issue.

I've found the following workaround : enable use-regex on each ingress that uses a path: /

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"

Instead of having 2 location / {, it generates a single one with : location ~* "^/" {

All 3 comments

I've upgraded to 0.31.1 today on my test cluster and I've had the same issue.

I've found the following workaround : enable use-regex on each ingress that uses a path: /

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"

Instead of having 2 location / {, it generates a single one with : location ~* "^/" {

We are going to release 0.32 in two days. This issue is fixed in
quay.io/kubernetes-ingress-controller/nginx-ingress-controller-amd64:dev

I've upgraded to 0.31.1 today on my test cluster and I've had the same issue.

I've found the following workaround : enable use-regex on each ingress that uses a path: /

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"

Instead of having 2 location / {, it generates a single one with : location ~* "^/" {

I do not want the location ~* "^/",how can I make it?

Was this page helpful?
0 / 5 - 0 ratings