diff --git a/internal/ingress/controller/endpoints.go b/internal/ingress/controller/endpoints.go index bdddcb0a0..26d7f298e 100644 --- a/internal/ingress/controller/endpoints.go +++ b/internal/ingress/controller/endpoints.go @@ -23,6 +23,7 @@ import ( "strconv" "strings" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/klog/v2" @@ -81,7 +82,8 @@ func getEndpoints(s *corev1.Service, port *corev1.ServicePort, proto corev1.Prot } for _, ss := range ep.Subsets { - for _, epPort := range ss.Ports { + matchedPortNameFound := false + for i, epPort := range ss.Ports { if !reflect.DeepEqual(epPort.Protocol, proto) { continue @@ -92,8 +94,16 @@ func getEndpoints(s *corev1.Service, port *corev1.ServicePort, proto corev1.Prot if port.Name == "" { // port.Name is optional if there is only one port targetPort = epPort.Port + matchedPortNameFound = true } else if port.Name == epPort.Name { targetPort = epPort.Port + matchedPortNameFound = true + } + + if i == len(ss.Ports)-1 && !matchedPortNameFound && port.TargetPort.Type == intstr.Int { + // use service target port if it's a number and no port name matched + // https://github.com/kubernetes/ingress-nginx/issues/7390 + targetPort = port.TargetPort.IntVal } if targetPort <= 0 { diff --git a/internal/ingress/controller/endpoints_test.go b/internal/ingress/controller/endpoints_test.go index 20d53c526..83c8e1837 100644 --- a/internal/ingress/controller/endpoints_test.go +++ b/internal/ingress/controller/endpoints_test.go @@ -315,7 +315,50 @@ func TestGetEndpoints(t *testing.T) { []ingress.Endpoint{}, }, { - "should return no endpoint when the name of the port name do not match any port in the endpoint Subsets", + "should return no endpoint when the name of the port name do not match any port in the endpoint Subsets and TargetPort is string", + &corev1.Service{ + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeClusterIP, + ClusterIP: "1.1.1.1", + Ports: []corev1.ServicePort{ + { + Name: "default", + TargetPort: intstr.FromString("port-1"), + }, + }, + }, + }, + &corev1.ServicePort{ + Name: "default", + TargetPort: intstr.FromString("port-1"), + }, + corev1.ProtocolTCP, + func(string) (*corev1.Endpoints, error) { + nodeName := "dummy" + return &corev1.Endpoints{ + Subsets: []corev1.EndpointSubset{ + { + Addresses: []corev1.EndpointAddress{ + { + IP: "1.1.1.1", + NodeName: &nodeName, + }, + }, + Ports: []corev1.EndpointPort{ + { + Protocol: corev1.ProtocolTCP, + Port: int32(80), + Name: "another-name", + }, + }, + }, + }, + }, nil + }, + []ingress.Endpoint{}, + }, + { + "should return one endpoint when the name of the port name do not match any port in the endpoint Subsets and TargetPort is int", &corev1.Service{ Spec: corev1.ServiceSpec{ Type: corev1.ServiceTypeClusterIP, @@ -355,7 +398,12 @@ func TestGetEndpoints(t *testing.T) { }, }, nil }, - []ingress.Endpoint{}, + []ingress.Endpoint{ + { + Address: "1.1.1.1", + Port: "80", + }, + }, }, { "should return one endpoint when the name of the port name match a port in the endpoint Subsets",