use a NodePort service as ExternalName in another service type ExternalName for configuring default-backend
What happened:
I'm trying to use an ExternalName service as a default backend for an Ingress to handle situation when the deployment has no active endpoints. I get 504 Gateway Time-out error. In controller logs:
W1010 15:04:46.362237 7 controller.go:1216] Service "default/web" does not have any active Endpoint.
2024/10/10 15:05:07 [error] 1294#1294: *41828 [lua] balancer.lua:348: balance(): error while setting current upstream peer [echo.default.svc.cluster.local]:8080: invalid IPv6 address while connecting to upstream, client: 192.168.49.1, server: hello-world.example, request: "GET / HTTP/1.1", host: "hello-world.example"
2024/10/10 15:05:12 [error] 1294#1294: *41828 upstream timed out (110: Operation timed out) while connecting to upstream, client: 192.168.49.1, server: hello-world.example, request: "GET / HTTP/1.1", upstream: "http://0.0.0.1:80/", host: "hello-world.example"
What you expected to happen:
The request should be passed to the default backend service. It should not treat the external name as an IPv6 address. AFAIK, it works when an external name service is used in Ingress. Why is default backend handled differently?
NGINX Ingress controller version (exec into the pod and run nginx-ingress-controller --version.): v1.11.2
Kubernetes version (use kubectl version):
v1.31.0
Environment:
Initially I experienced this in EKS, then I reproduced it in Minikube.
-
Cloud provider or hardware configuration: Minikube v1.34.0
-
OS (e.g. from /etc/os-release): Ubuntu 24.04
-
Kernel (e.g.
uname -a): 6.8.0-45 -
How was the ingress-nginx-controller installed: minikube addons enable ingress
How to reproduce this issue:
Install minikube
minikube start
Install the ingress controller
minikube addons enable ingress
Install hello-app with 0 replicas
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
namespace: default
spec:
replicas: 0
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
name: hello-app
kubectl expose deployment web --type=NodePort --port=8080
Install echo server
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: echo
name: echo
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- image: jmalloc/echo-server
imagePullPolicy: IfNotPresent
name: echo
kubectl expose deployment echo --type=NodePort --port=8080
Create ExternalName service that points to echo service
apiVersion: v1
kind: Service
metadata:
name: echo-en
namespace: default
spec:
externalName: echo.default.svc.cluster.local
type: ExternalName
ports:
- protocol: TCP
port: 8080
targetPort: 8080
Create an ingress for hello-app with echo service external name as default backend
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/default-backend: echo-en
name: example-ingress
spec:
ingressClassName: nginx
rules:
- host: hello-world.example
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8080
Send a request
❯ curl --resolve "hello-world.example:80:$( minikube ip )" -i http://hello-world.example
HTTP/1.1 504 Gateway Time-out
Date: Thu, 10 Oct 2024 15:35:28 GMT
Content-Type: text/html
Content-Length: 160
Connection: keep-alive
<html>
<head><title>504 Gateway Time-out</title></head>
<body>
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx</center>
</body>
</html>