mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +00:00
Merge pull request #52935 from m1093782566/ipv6
Automatic merge from submit-queue (batch tested with PRs 53454, 53446, 52935, 53443, 52917). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Remove ipv4 constraint of Node IPs in ipvs proxier **What this PR does / why we need it**: We are targeting to IPV6. So, we should remove ipv4 constraint of Node IPs in ipvs proxier. Besides, adding some log messages. **Which issue this PR fixes**: xref #51866 **Special notes for your reviewer**: **Release note**: ```release-note NONE ```
This commit is contained in:
commit
a2ce3bcf63
@ -54,6 +54,7 @@ go_library(
|
|||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
|
|
||||||
clientv1 "k8s.io/api/core/v1"
|
clientv1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
@ -155,17 +156,17 @@ func (r *realIPGetter) NodeIPs() (ips []net.IP, err error) {
|
|||||||
}
|
}
|
||||||
intf, err := net.InterfaceByName(name)
|
intf, err := net.InterfaceByName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
utilruntime.HandleError(fmt.Errorf("Failed to get interface by name: %s, error: %v", name, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
addrs, err := intf.Addrs()
|
addrs, err := intf.Addrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
utilruntime.HandleError(fmt.Errorf("Failed to get addresses from interface: %s, error: %v", name, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, a := range addrs {
|
for _, a := range addrs {
|
||||||
if ipnet, ok := a.(*net.IPNet); ok {
|
if ipnet, ok := a.(*net.IPNet); ok {
|
||||||
if ipnet.IP.To4() != nil {
|
ips = append(ips, ipnet.IP)
|
||||||
ips = append(ips, ipnet.IP.To4())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,8 +171,10 @@ func makeTestEndpoints(namespace, name string, eptFunc func(*api.Endpoints)) *ap
|
|||||||
func TestNodePort(t *testing.T) {
|
func TestNodePort(t *testing.T) {
|
||||||
ipt := iptablestest.NewFake()
|
ipt := iptablestest.NewFake()
|
||||||
ipvs := ipvstest.NewFake()
|
ipvs := ipvstest.NewFake()
|
||||||
nodeIP := net.ParseIP("100.101.102.103")
|
nodeIPv4 := net.ParseIP("100.101.102.103")
|
||||||
fp := NewFakeProxier(ipt, ipvs, []net.IP{nodeIP})
|
nodeIPv6 := net.ParseIP("2001:db8::1:1")
|
||||||
|
nodeIPs := sets.NewString(nodeIPv4.String(), nodeIPv6.String())
|
||||||
|
fp := NewFakeProxier(ipt, ipvs, []net.IP{nodeIPv4, nodeIPv6})
|
||||||
svcIP := "10.20.30.41"
|
svcIP := "10.20.30.41"
|
||||||
svcPort := 80
|
svcPort := 80
|
||||||
svcNodePort := 3001
|
svcNodePort := 3001
|
||||||
@ -193,12 +195,16 @@ func TestNodePort(t *testing.T) {
|
|||||||
}}
|
}}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
epIP := "10.180.0.1"
|
epIPv4 := "10.180.0.1"
|
||||||
|
epIPv6 := "1002:ab8::2:10"
|
||||||
|
epIPs := sets.NewString(epIPv4, epIPv6)
|
||||||
makeEndpointsMap(fp,
|
makeEndpointsMap(fp,
|
||||||
makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *api.Endpoints) {
|
makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *api.Endpoints) {
|
||||||
ept.Subsets = []api.EndpointSubset{{
|
ept.Subsets = []api.EndpointSubset{{
|
||||||
Addresses: []api.EndpointAddress{{
|
Addresses: []api.EndpointAddress{{
|
||||||
IP: epIP,
|
IP: epIPv4,
|
||||||
|
}, {
|
||||||
|
IP: epIPv6,
|
||||||
}},
|
}},
|
||||||
Ports: []api.EndpointPort{{
|
Ports: []api.EndpointPort{{
|
||||||
Name: svcPortName.Port,
|
Name: svcPortName.Port,
|
||||||
@ -215,19 +221,19 @@ func TestNodePort(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to get ipvs services, err: %v", err)
|
t.Errorf("Failed to get ipvs services, err: %v", err)
|
||||||
}
|
}
|
||||||
if len(services) != 2 {
|
if len(services) != 3 {
|
||||||
t.Errorf("Expect 2 ipvs services, got %d", len(services))
|
t.Errorf("Expect 3 ipvs services, got %d", len(services))
|
||||||
}
|
}
|
||||||
found := false
|
found := false
|
||||||
for _, svc := range services {
|
for _, svc := range services {
|
||||||
if svc.Address.Equal(nodeIP) && svc.Port == uint16(svcNodePort) && svc.Protocol == string(api.ProtocolTCP) {
|
if nodeIPs.Has(svc.Address.String()) && svc.Port == uint16(svcNodePort) && svc.Protocol == string(api.ProtocolTCP) {
|
||||||
found = true
|
found = true
|
||||||
destinations, err := ipvs.GetRealServers(svc)
|
destinations, err := ipvs.GetRealServers(svc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to get ipvs destinations, err: %v", err)
|
t.Errorf("Failed to get ipvs destinations, err: %v", err)
|
||||||
}
|
}
|
||||||
for _, dest := range destinations {
|
for _, dest := range destinations {
|
||||||
if dest.Address.To4().String() != epIP || dest.Port != uint16(svcPort) {
|
if !epIPs.Has(dest.Address.String()) || dest.Port != uint16(svcPort) {
|
||||||
t.Errorf("service Endpoint mismatch ipvs service destination")
|
t.Errorf("service Endpoint mismatch ipvs service destination")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,7 +330,7 @@ func TestClusterIPNoEndpoint(t *testing.T) {
|
|||||||
if len(services) != 1 {
|
if len(services) != 1 {
|
||||||
t.Errorf("Expect 1 ipvs services, got %d", len(services))
|
t.Errorf("Expect 1 ipvs services, got %d", len(services))
|
||||||
} else {
|
} else {
|
||||||
if services[0].Address.To4().String() != svcIP || services[0].Port != uint16(svcPort) && services[0].Protocol == string(api.ProtocolTCP) {
|
if services[0].Address.String() != svcIP || services[0].Port != uint16(svcPort) || services[0].Protocol != string(api.ProtocolTCP) {
|
||||||
t.Errorf("Unexpected mismatch service")
|
t.Errorf("Unexpected mismatch service")
|
||||||
} else {
|
} else {
|
||||||
destinations, _ := ipvs.GetRealServers(services[0])
|
destinations, _ := ipvs.GetRealServers(services[0])
|
||||||
@ -339,34 +345,60 @@ func TestClusterIP(t *testing.T) {
|
|||||||
ipt := iptablestest.NewFake()
|
ipt := iptablestest.NewFake()
|
||||||
ipvs := ipvstest.NewFake()
|
ipvs := ipvstest.NewFake()
|
||||||
fp := NewFakeProxier(ipt, ipvs, nil)
|
fp := NewFakeProxier(ipt, ipvs, nil)
|
||||||
svcIP := "10.20.30.41"
|
|
||||||
svcPort := 80
|
svcIPv4 := "10.20.30.41"
|
||||||
svcPortName := proxy.ServicePortName{
|
svcPortV4 := 80
|
||||||
|
svcPortNameV4 := proxy.ServicePortName{
|
||||||
NamespacedName: makeNSN("ns1", "svc1"),
|
NamespacedName: makeNSN("ns1", "svc1"),
|
||||||
Port: "p80",
|
Port: "p80",
|
||||||
}
|
}
|
||||||
|
svcIPv6 := "1002:ab8::2:1"
|
||||||
|
svcPortV6 := 8080
|
||||||
|
svcPortNameV6 := proxy.ServicePortName{
|
||||||
|
NamespacedName: makeNSN("ns2", "svc2"),
|
||||||
|
Port: "p8080",
|
||||||
|
}
|
||||||
makeServiceMap(fp,
|
makeServiceMap(fp,
|
||||||
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *api.Service) {
|
makeTestService(svcPortNameV4.Namespace, svcPortNameV4.Name, func(svc *api.Service) {
|
||||||
svc.Spec.ClusterIP = svcIP
|
svc.Spec.ClusterIP = svcIPv4
|
||||||
svc.Spec.Ports = []api.ServicePort{{
|
svc.Spec.Ports = []api.ServicePort{{
|
||||||
Name: svcPortName.Port,
|
Name: svcPortNameV4.Port,
|
||||||
Port: int32(svcPort),
|
Port: int32(svcPortV4),
|
||||||
|
Protocol: api.ProtocolTCP,
|
||||||
|
}}
|
||||||
|
}),
|
||||||
|
makeTestService(svcPortNameV6.Namespace, svcPortNameV6.Name, func(svc *api.Service) {
|
||||||
|
svc.Spec.ClusterIP = svcIPv6
|
||||||
|
svc.Spec.Ports = []api.ServicePort{{
|
||||||
|
Name: svcPortNameV6.Port,
|
||||||
|
Port: int32(svcPortV6),
|
||||||
Protocol: api.ProtocolTCP,
|
Protocol: api.ProtocolTCP,
|
||||||
}}
|
}}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
epIP := "10.180.0.1"
|
epIPv4 := "10.180.0.1"
|
||||||
|
epIPv6 := "1009:ab8::5:6"
|
||||||
makeEndpointsMap(fp,
|
makeEndpointsMap(fp,
|
||||||
makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *api.Endpoints) {
|
makeTestEndpoints(svcPortNameV4.Namespace, svcPortNameV4.Name, func(ept *api.Endpoints) {
|
||||||
ept.Subsets = []api.EndpointSubset{{
|
ept.Subsets = []api.EndpointSubset{{
|
||||||
Addresses: []api.EndpointAddress{{
|
Addresses: []api.EndpointAddress{{
|
||||||
IP: epIP,
|
IP: epIPv4,
|
||||||
}},
|
}},
|
||||||
Ports: []api.EndpointPort{{
|
Ports: []api.EndpointPort{{
|
||||||
Name: svcPortName.Port,
|
Name: svcPortNameV4.Port,
|
||||||
Port: int32(svcPort),
|
Port: int32(svcPortV4),
|
||||||
|
}},
|
||||||
|
}}
|
||||||
|
}),
|
||||||
|
makeTestEndpoints(svcPortNameV6.Namespace, svcPortNameV6.Name, func(ept *api.Endpoints) {
|
||||||
|
ept.Subsets = []api.EndpointSubset{{
|
||||||
|
Addresses: []api.EndpointAddress{{
|
||||||
|
IP: epIPv6,
|
||||||
|
}},
|
||||||
|
Ports: []api.EndpointPort{{
|
||||||
|
Name: svcPortNameV6.Port,
|
||||||
|
Port: int32(svcPortV6),
|
||||||
}},
|
}},
|
||||||
}}
|
}}
|
||||||
}),
|
}),
|
||||||
@ -379,16 +411,36 @@ func TestClusterIP(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to get ipvs services, err: %v", err)
|
t.Errorf("Failed to get ipvs services, err: %v", err)
|
||||||
}
|
}
|
||||||
if len(services) != 1 {
|
if len(services) != 2 {
|
||||||
t.Errorf("Expect 1 ipvs services, got %d", len(services))
|
t.Errorf("Expect 2 ipvs services, got %d", len(services))
|
||||||
} else {
|
}
|
||||||
if services[0].Address.To4().String() != svcIP || services[0].Port != uint16(svcPort) && services[0].Protocol == string(api.ProtocolTCP) {
|
for i := range services {
|
||||||
|
// Check services
|
||||||
|
if services[i].Address.String() == svcIPv4 {
|
||||||
|
if services[i].Port != uint16(svcPortV4) || services[i].Protocol != string(api.ProtocolTCP) {
|
||||||
t.Errorf("Unexpected mismatch service")
|
t.Errorf("Unexpected mismatch service")
|
||||||
} else {
|
}
|
||||||
destinations, _ := ipvs.GetRealServers(services[0])
|
// Check destinations
|
||||||
|
destinations, _ := ipvs.GetRealServers(services[i])
|
||||||
if len(destinations) != 1 {
|
if len(destinations) != 1 {
|
||||||
t.Errorf("Unexpected %d destinations, expect 0 destinations", len(destinations))
|
t.Errorf("Expected 1 destinations, got %d destinations", len(destinations))
|
||||||
} else if destinations[0].Address.To4().String() != epIP || destinations[0].Port != uint16(svcPort) {
|
continue
|
||||||
|
}
|
||||||
|
if destinations[0].Address.String() != epIPv4 || destinations[0].Port != uint16(svcPortV4) {
|
||||||
|
t.Errorf("Unexpected mismatch destinations")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if services[i].Address.String() == svcIPv6 {
|
||||||
|
if services[i].Port != uint16(svcPortV6) || services[i].Protocol != string(api.ProtocolTCP) {
|
||||||
|
t.Errorf("Unexpected mismatch service")
|
||||||
|
}
|
||||||
|
// Check destinations
|
||||||
|
destinations, _ := ipvs.GetRealServers(services[i])
|
||||||
|
if len(destinations) != 1 {
|
||||||
|
t.Errorf("Expected 1 destinations, got %d destinations", len(destinations))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if destinations[0].Address.String() != epIPv6 || destinations[0].Port != uint16(svcPortV6) {
|
||||||
t.Errorf("Unexpected mismatch destinations")
|
t.Errorf("Unexpected mismatch destinations")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,7 +487,7 @@ func TestExternalIPsNoEndpoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
found := false
|
found := false
|
||||||
for _, svc := range services {
|
for _, svc := range services {
|
||||||
if svc.Address.To4().String() == svcExternalIPs && svc.Port == uint16(svcPort) && svc.Protocol == string(api.ProtocolTCP) {
|
if svc.Address.String() == svcExternalIPs && svc.Port == uint16(svcPort) && svc.Protocol == string(api.ProtocolTCP) {
|
||||||
found = true
|
found = true
|
||||||
destinations, _ := ipvs.GetRealServers(svc)
|
destinations, _ := ipvs.GetRealServers(svc)
|
||||||
if len(destinations) != 0 {
|
if len(destinations) != 0 {
|
||||||
@ -455,7 +507,7 @@ func TestExternalIPs(t *testing.T) {
|
|||||||
fp := NewFakeProxier(ipt, ipvs, nil)
|
fp := NewFakeProxier(ipt, ipvs, nil)
|
||||||
svcIP := "10.20.30.41"
|
svcIP := "10.20.30.41"
|
||||||
svcPort := 80
|
svcPort := 80
|
||||||
svcExternalIPs := "50.60.70.81"
|
svcExternalIPs := sets.NewString("50.60.70.81", "2012::51")
|
||||||
svcPortName := proxy.ServicePortName{
|
svcPortName := proxy.ServicePortName{
|
||||||
NamespacedName: makeNSN("ns1", "svc1"),
|
NamespacedName: makeNSN("ns1", "svc1"),
|
||||||
Port: "p80",
|
Port: "p80",
|
||||||
@ -465,7 +517,7 @@ func TestExternalIPs(t *testing.T) {
|
|||||||
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *api.Service) {
|
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *api.Service) {
|
||||||
svc.Spec.Type = "ClusterIP"
|
svc.Spec.Type = "ClusterIP"
|
||||||
svc.Spec.ClusterIP = svcIP
|
svc.Spec.ClusterIP = svcIP
|
||||||
svc.Spec.ExternalIPs = []string{svcExternalIPs}
|
svc.Spec.ExternalIPs = svcExternalIPs.UnsortedList()
|
||||||
svc.Spec.Ports = []api.ServicePort{{
|
svc.Spec.Ports = []api.ServicePort{{
|
||||||
Name: svcPortName.Port,
|
Name: svcPortName.Port,
|
||||||
Port: int32(svcPort),
|
Port: int32(svcPort),
|
||||||
@ -497,16 +549,16 @@ func TestExternalIPs(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to get ipvs services, err: %v", err)
|
t.Errorf("Failed to get ipvs services, err: %v", err)
|
||||||
}
|
}
|
||||||
if len(services) != 2 {
|
if len(services) != 3 {
|
||||||
t.Errorf("Expect 2 ipvs services, got %d", len(services))
|
t.Errorf("Expect 3 ipvs services, got %d", len(services))
|
||||||
}
|
}
|
||||||
found := false
|
found := false
|
||||||
for _, svc := range services {
|
for _, svc := range services {
|
||||||
if svc.Address.To4().String() == svcExternalIPs && svc.Port == uint16(svcPort) && svc.Protocol == string(api.ProtocolTCP) {
|
if svcExternalIPs.Has(svc.Address.String()) && svc.Port == uint16(svcPort) && svc.Protocol == string(api.ProtocolTCP) {
|
||||||
found = true
|
found = true
|
||||||
destinations, _ := ipvs.GetRealServers(svc)
|
destinations, _ := ipvs.GetRealServers(svc)
|
||||||
for _, dest := range destinations {
|
for _, dest := range destinations {
|
||||||
if dest.Address.To4().String() != epIP || dest.Port != uint16(svcPort) {
|
if dest.Address.String() != epIP || dest.Port != uint16(svcPort) {
|
||||||
t.Errorf("service Endpoint mismatch ipvs service destination")
|
t.Errorf("service Endpoint mismatch ipvs service destination")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -637,7 +689,7 @@ func TestOnlyLocalNodePorts(t *testing.T) {
|
|||||||
if len(destinations) != 1 {
|
if len(destinations) != 1 {
|
||||||
t.Errorf("Expect 1 ipvs destination, got %d", len(destinations))
|
t.Errorf("Expect 1 ipvs destination, got %d", len(destinations))
|
||||||
} else {
|
} else {
|
||||||
if destinations[0].Address.To4().String() != epIP2 || destinations[0].Port != uint16(svcPort) {
|
if destinations[0].Address.String() != epIP2 || destinations[0].Port != uint16(svcPort) {
|
||||||
t.Errorf("service Endpoint mismatch ipvs service destination")
|
t.Errorf("service Endpoint mismatch ipvs service destination")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ func (f *FakeIPVS) AddVirtualServer(serv *utilipvs.VirtualServer) error {
|
|||||||
key := toServiceKey(serv)
|
key := toServiceKey(serv)
|
||||||
f.Services[key] = serv
|
f.Services[key] = serv
|
||||||
// make sure no destination present when creating new service
|
// make sure no destination present when creating new service
|
||||||
f.Destinations = make(map[serviceKey][]*utilipvs.RealServer)
|
f.Destinations[key] = make([]*utilipvs.RealServer, 0)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user