Skip to content

The admission webhook is not working as expect: It doesn't prevent to user from creating two ingress resources that have the same host/path combination. #8972

Closed
@cha7ri

Description

@cha7ri

What happened:
I did a quick investigation and the issue seems to be here this code check only the first host and return nil if it doesn't overlap. More details below:

The admission webhook is not working as expect: It doesn't prevent to user from creating two ingress resources that have the same host/path combination. Example:

  • cafe-ingress.yaml
kind: Ingress
metadata:
  name: cafe-ingress
spec:
  tls:
    - hosts:
        - cafe.example.com
      secretName: cafe-secret
  rules:
    - host: "cafe.example.com"
      http:
        paths:
          - path: /tea
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
          - path: /coffee
            pathType: Prefix
            backend:
              service:
                name: coffee-svc
                port:
                  number: 80
  • cafe-ingress-1
kind: Ingress
metadata:
  name: cafe-ingress-1
spec:
  tls:
    - hosts:
        - cafe.example.com
      secretName: cafe-secret
  rules:
    - host: "dummy.example.com"
      http:
        paths:
          - path: /tea
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
    - host: "cafe.example.com"
      http:
        paths:
          - path: /tea
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
          - path: /coffee
            pathType: Prefix
            backend:
              service:
                name: coffee-svc
                port:
                  number: 80

In the example above both ingresses will be created.
But if we change the cafe-ingress.yaml and make host: "cafe.example.com" the first host, it will fail with "cafe-ingress-1": admission webhook "validate.nginx.ingress.kubernetes.io" denied the request: host "cafe.example.com" and path "/tea" is already defined in ingress default/cafe-ingress

What you expected to happen:

It shouldn't create both ingresses even if we we put cafe.example.com as a second host.

NGINX Ingress controller version (exec into the pod and run nginx-ingress-controller --version.):

-------------------------------------------------------------------------------
NGINX Ingress controller
  Release:       v1.1.0
  Build:         cacbee86b6ccc45bde8ffc184521bed3022e7dee
  Repository:    https://github.com/kubernetes/ingress-nginx
  nginx version: nginx/1.19.9

-------------------------------------------------------------------------------

Kubernetes version (use kubectl version):

  buildDate: "2022-06-15T14:22:29Z"
  compiler: gc
  gitCommit: f66044f4361b9f1f96f0053dd46cb7dce5e990a8
  gitTreeState: clean
  gitVersion: v1.24.2
  goVersion: go1.18.3
  major: "1"
  minor: "24"
  platform: darwin/amd64
kustomizeVersion: v4.5.4
serverVersion:
  buildDate: "2022-06-09T18:22:07Z"
  compiler: gc
  gitCommit: e1318dce57b3e319a2e3fecf343677d1c4d4aa75
  gitTreeState: clean
  gitVersion: v1.21.13-eks-84b4fe6
  goVersion: go1.16.15
  major: "1"
  minor: 21+
  platform: linux/amd64```

- **How was the ingress-nginx-controller installed**:
``` helm ls -A | grep -i ingress
ingress-nginx-public-le         	ingress-nginx     	49      	2022-06-27 11:34:25.658567825 +0000 UTC	deployed	ingress-nginx-4.0.12                	1.1.0

How to reproduce this issue:

Create a new cluster using kind

kind create cluster --name nginx-test --image kindest/node:v1.21.12

Install ingress nginx controller

 kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml

Make sure it's running

kubectl get pods --namespace=ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-xvr5m        0/1     Completed   0          48m
ingress-nginx-admission-patch-lzp8c         0/1     Completed   1          48m
ingress-nginx-controller-55dcf56b68-2dj8w   1/1     Running     0          48m

Apply the first ingress

echo "apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cafe-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
    - hosts:
        - cafe.example.com
      secretName: cafe-secret
  rules:
    - host: "cafe.example.com"
      http:
        paths:
          - path: /tea
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
          - path: /coffee
            pathType: Prefix
            backend:
              service:
                name: coffee-svc
                port:
                  number: 80
" | kubectl apply -f -

Apply the second ingress

echo "apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cafe-ingress-1
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
    - hosts:
        - cafe.example.com
      secretName: cafe-secret
  rules:
    - host: "dummy.example.com"
      http:
        paths:
          - path: /tea
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
    - host: "cafe.example.com"
      http:
        paths:
          - path: /tea
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
          - path: /coffee
            pathType: Prefix
            backend:
              service:
                name: coffee-svc
                port:
                  number: 80
" | kubectl apply -f -

Check that both ingresses are created

kubectl get ingress
NAME             CLASS    HOSTS                                ADDRESS   PORTS     AGE
cafe-ingress     <none>   cafe.example.com                               80, 443   26m
cafe-ingress-1   <none>   dummy.example.com,cafe.example.com             80, 443   26m

Check that nginx config has changed

POD_NAMESPACE=ingress-nginx
POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app.kubernetes.io/name=ingress-nginx --field-selector=status.phase=Running -o jsonpath='{.items[0].metadata.name}')

kubectl exec -it $POD_NAME -n $POD_NAMESPACE -- cat /etc/nginx/nginx.conf | grep "start server"
	## start server _
	## start server cafe.example.com
	## start server dummy.example.com

Edit the second ingress

echo "apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cafe-ingress-1
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
    - hosts:
        - cafe.example.com
      secretName: cafe-secret
  rules:
    - host: "cafe.example.com"
      http:
        paths:
          - path: /tea
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
    - host: "dummy.example.com"
      http:
        paths:
          - path: /tea
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
          - path: /coffee
            pathType: Prefix
            backend:
              service:
                name: coffee-svc
                port:
                  number: 80
" | kubectl apply -f -

You should see the error below

for: "STDIN": admission webhook "validate.nginx.ingress.kubernetes.io" denied the request: host "cafe.example.com" and path "/tea" is already defined in ingress default/cafe-ingress

Metadata

Metadata

Labels

needs-kindIndicates a PR lacks a `kind/foo` label and requires one.needs-priorityneeds-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions