fix: preserve ingress load balancer hostnames (#3994)

Signed-off-by: EndlessSeeker <1766508902@qq.com>
This commit is contained in:
EndlessSeeker
2026-06-22 11:34:38 +08:00
committed by GitHub
parent bd6039f53b
commit f060c9f51d
2 changed files with 163 additions and 23 deletions

View File

@@ -364,6 +364,8 @@ func getLoadBalancerIp(svc *v1.Service) []string {
hostName := strings.TrimSuffix(ingress.Hostname, SvcHostNameSuffix)
if net.ParseIP(hostName) != nil {
out = append(out, hostName)
} else {
out = append(out, ingress.Hostname)
}
}
}
@@ -389,7 +391,8 @@ func getSvcIpList(svcList []*v1.Service) []string {
func SortLbIngressList(lbi []v1.LoadBalancerIngress) func(int, int) bool {
return func(i int, j int) bool {
return lbi[i].IP < lbi[j].IP
return loadBalancerIngressAddress(lbi[i].IP, lbi[i].Hostname) <
loadBalancerIngressAddress(lbi[j].IP, lbi[j].Hostname)
}
}
@@ -397,7 +400,11 @@ func GetLbStatusList(svcList []*v1.Service) []v1.LoadBalancerIngress {
svcIpList := getSvcIpList(svcList)
lbi := make([]v1.LoadBalancerIngress, 0, len(svcIpList))
for _, ep := range svcIpList {
lbi = append(lbi, v1.LoadBalancerIngress{IP: ep})
if net.ParseIP(ep) != nil {
lbi = append(lbi, v1.LoadBalancerIngress{IP: ep})
} else {
lbi = append(lbi, v1.LoadBalancerIngress{Hostname: ep})
}
}
sort.SliceStable(lbi, SortLbIngressList(lbi))
@@ -406,7 +413,8 @@ func GetLbStatusList(svcList []*v1.Service) []v1.LoadBalancerIngress {
func SortLbIngressListV1(lbi []networkingv1.IngressLoadBalancerIngress) func(int, int) bool {
return func(i int, j int) bool {
return lbi[i].IP < lbi[j].IP
return loadBalancerIngressAddress(lbi[i].IP, lbi[i].Hostname) <
loadBalancerIngressAddress(lbi[j].IP, lbi[j].Hostname)
}
}
@@ -414,7 +422,11 @@ func GetLbStatusListV1(svcList []*v1.Service) []networkingv1.IngressLoadBalancer
svcIpList := getSvcIpList(svcList)
lbi := make([]networkingv1.IngressLoadBalancerIngress, 0, len(svcIpList))
for _, ep := range svcIpList {
lbi = append(lbi, networkingv1.IngressLoadBalancerIngress{IP: ep})
if net.ParseIP(ep) != nil {
lbi = append(lbi, networkingv1.IngressLoadBalancerIngress{IP: ep})
} else {
lbi = append(lbi, networkingv1.IngressLoadBalancerIngress{Hostname: ep})
}
}
sort.SliceStable(lbi, SortLbIngressListV1(lbi))
@@ -423,7 +435,8 @@ func GetLbStatusListV1(svcList []*v1.Service) []networkingv1.IngressLoadBalancer
func SortLbIngressListV1Beta1(lbi []networkingv1beta1.IngressLoadBalancerIngress) func(int, int) bool {
return func(i int, j int) bool {
return lbi[i].IP < lbi[j].IP
return loadBalancerIngressAddress(lbi[i].IP, lbi[i].Hostname) <
loadBalancerIngressAddress(lbi[j].IP, lbi[j].Hostname)
}
}
@@ -431,9 +444,20 @@ func GetLbStatusListV1Beta1(svcList []*v1.Service) []networkingv1beta1.IngressLo
svcIpList := getSvcIpList(svcList)
lbi := make([]networkingv1beta1.IngressLoadBalancerIngress, 0, len(svcIpList))
for _, ep := range svcIpList {
lbi = append(lbi, networkingv1beta1.IngressLoadBalancerIngress{IP: ep})
if net.ParseIP(ep) != nil {
lbi = append(lbi, networkingv1beta1.IngressLoadBalancerIngress{IP: ep})
} else {
lbi = append(lbi, networkingv1beta1.IngressLoadBalancerIngress{Hostname: ep})
}
}
sort.SliceStable(lbi, SortLbIngressListV1Beta1(lbi))
return lbi
}
func loadBalancerIngressAddress(ip, hostname string) string {
if ip != "" {
return ip
}
return hostname
}

View File

@@ -21,6 +21,8 @@ import (
"istio.io/istio/pilot/pkg/model"
"istio.io/istio/pkg/config"
v1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/alibaba/higress/v2/pkg/ingress/kube/annotations"
@@ -206,6 +208,9 @@ func TestGenerateUniqueRouteName(t *testing.T) {
func TestGetLbStatusList(t *testing.T) {
clusterPrefix = "gw-123-"
svcName := clusterPrefix
aliyunHostname := "higress.cn-hangzhou.alb.aliyuncs.com"
awsHostname := "k8s-kubeingr-higressg-1234567890.eu-north-1.elb.amazonaws.com"
tencentHostname := "lb-12345678.clb.ap-guangzhou.tencentclb.com"
svcList := []*v1.Service{
{
ObjectMeta: metav1.ObjectMeta{
@@ -224,6 +229,57 @@ func TestGetLbStatusList(t *testing.T) {
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: svcName,
},
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
Status: v1.ServiceStatus{
LoadBalancer: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: awsHostname,
},
},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: svcName,
},
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
Status: v1.ServiceStatus{
LoadBalancer: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: aliyunHostname,
},
},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: svcName,
},
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
Status: v1.ServiceStatus{
LoadBalancer: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: tencentHostname,
},
},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: svcName,
@@ -295,17 +351,15 @@ func TestGetLbStatusList(t *testing.T) {
}
lbiList := GetLbStatusList(svcList)
if len(lbiList) != 4 {
t.Fatal("len should be 4")
}
if lbiList[0].IP != "1.1.1.1" {
t.Fatal("should be 1.1.1.1")
}
if lbiList[3].IP != "4.4.4.4" {
t.Fatal("should be 4.4.4.4")
}
assert.Equal(t, []v1.LoadBalancerIngress{
{IP: "1.1.1.1"},
{IP: "2.2.2.2"},
{IP: "3.3.3.3"},
{IP: "4.4.4.4"},
{Hostname: aliyunHostname},
{Hostname: awsHostname},
{Hostname: tencentHostname},
}, lbiList)
}
func TestSortRoutes(t *testing.T) {
@@ -1012,6 +1066,9 @@ func TestPartMd5(t *testing.T) {
func TestGetLbStatusListV1AndV1Beta1(t *testing.T) {
clusterPrefix = "gw-123-"
svcName := clusterPrefix
aliyunHostname := "higress.cn-hangzhou.alb.aliyuncs.com"
awsHostname := "k8s-kubeingr-higressg-1234567890.eu-north-1.elb.amazonaws.com"
tencentHostname := "lb-12345678.clb.ap-guangzhou.tencentclb.com"
svcList := []*v1.Service{
{
ObjectMeta: metav1.ObjectMeta{
@@ -1047,23 +1104,82 @@ func TestGetLbStatusListV1AndV1Beta1(t *testing.T) {
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: svcName,
},
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
Status: v1.ServiceStatus{
LoadBalancer: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: awsHostname,
},
},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: svcName,
},
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
Status: v1.ServiceStatus{
LoadBalancer: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: aliyunHostname,
},
},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: svcName,
},
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
Status: v1.ServiceStatus{
LoadBalancer: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: tencentHostname,
},
},
},
},
},
}
// Test the V1 version
t.Run("GetLbStatusListV1", func(t *testing.T) {
lbiList := GetLbStatusListV1(svcList)
assert.Equal(t, 2, len(lbiList), "There should be 2 entry points")
assert.Equal(t, "1.1.1.1", lbiList[0].IP, "The first IP should be 1.1.1.1")
assert.Equal(t, "2.2.2.2", lbiList[1].IP, "The second IP should be 2.2.2.2")
assert.Equal(t, []networkingv1.IngressLoadBalancerIngress{
{IP: "1.1.1.1"},
{IP: "2.2.2.2"},
{Hostname: aliyunHostname},
{Hostname: awsHostname},
{Hostname: tencentHostname},
}, lbiList)
})
// Test the V1Beta1 version
t.Run("GetLbStatusListV1Beta1", func(t *testing.T) {
lbiList := GetLbStatusListV1Beta1(svcList)
assert.Equal(t, 2, len(lbiList), "There should be 2 entry points")
assert.Equal(t, "1.1.1.1", lbiList[0].IP, "The first IP should be 1.1.1.1")
assert.Equal(t, "2.2.2.2", lbiList[1].IP, "The second IP should be 2.2.2.2")
assert.Equal(t, []networkingv1beta1.IngressLoadBalancerIngress{
{IP: "1.1.1.1"},
{IP: "2.2.2.2"},
{Hostname: aliyunHostname},
{Hostname: awsHostname},
{Hostname: tencentHostname},
}, lbiList)
})
}