getEndpoints uses service target port directly if it's a number and mismatch with port name in endpoint (#7393)

This commit is contained in:
fatedier 2021-09-08 02:15:16 +08:00 committed by GitHub
parent a714fb69db
commit 82e1fc8cac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 3 deletions

View file

@ -23,6 +23,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation"
"k8s.io/klog/v2" "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 _, ss := range ep.Subsets {
for _, epPort := range ss.Ports { matchedPortNameFound := false
for i, epPort := range ss.Ports {
if !reflect.DeepEqual(epPort.Protocol, proto) { if !reflect.DeepEqual(epPort.Protocol, proto) {
continue continue
@ -92,8 +94,16 @@ func getEndpoints(s *corev1.Service, port *corev1.ServicePort, proto corev1.Prot
if port.Name == "" { if port.Name == "" {
// port.Name is optional if there is only one port // port.Name is optional if there is only one port
targetPort = epPort.Port targetPort = epPort.Port
matchedPortNameFound = true
} else if port.Name == epPort.Name { } else if port.Name == epPort.Name {
targetPort = epPort.Port 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 { if targetPort <= 0 {

View file

@ -315,7 +315,50 @@ func TestGetEndpoints(t *testing.T) {
[]ingress.Endpoint{}, []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{ &corev1.Service{
Spec: corev1.ServiceSpec{ Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP, Type: corev1.ServiceTypeClusterIP,
@ -355,7 +398,12 @@ func TestGetEndpoints(t *testing.T) {
}, },
}, nil }, 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", "should return one endpoint when the name of the port name match a port in the endpoint Subsets",