Description
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