mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #80725 from aramase/dualstack-phase2-e2e
E2E tests for dualstack phase2
This commit is contained in:
commit
63bd1d7a5c
@ -80,6 +80,7 @@ go_library(
|
||||
"//vendor/github.com/onsi/gomega:go_default_library",
|
||||
"//vendor/google.golang.org/api/compute/v0.alpha:go_default_library",
|
||||
"//vendor/google.golang.org/api/compute/v1:go_default_library",
|
||||
"//vendor/k8s.io/utils/net:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -30,7 +30,9 @@ import (
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
e2edeploy "k8s.io/kubernetes/test/e2e/framework/deployment"
|
||||
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
|
||||
e2eservice "k8s.io/kubernetes/test/e2e/framework/service"
|
||||
imageutils "k8s.io/kubernetes/test/utils/image"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// Tests for ipv6 dual stack feature
|
||||
@ -204,8 +206,152 @@ var _ = SIGDescribe("[Feature:IPv6DualStackAlphaFeature] [LinuxOnly]", func() {
|
||||
|
||||
assertNetworkConnectivity(f, *serverPods, *clientPods, "dualstack-test-client", "80")
|
||||
})
|
||||
|
||||
ginkgo.It("should create service with cluster ip from primary service range [Feature:IPv6DualStackAlphaFeature:Phase2]", func() {
|
||||
serviceName := "defaultclusterip"
|
||||
ns := f.Namespace.Name
|
||||
jig := e2eservice.NewTestJig(cs, serviceName)
|
||||
|
||||
defaultIPFamily := v1.IPv4Protocol
|
||||
if framework.TestContext.ClusterIsIPv6() {
|
||||
defaultIPFamily = v1.IPv6Protocol
|
||||
}
|
||||
|
||||
t := e2eservice.NewServerTest(cs, ns, serviceName)
|
||||
defer func() {
|
||||
defer ginkgo.GinkgoRecover()
|
||||
if errs := t.Cleanup(); len(errs) != 0 {
|
||||
framework.Failf("errors in cleanup: %v", errs)
|
||||
}
|
||||
}()
|
||||
|
||||
ginkgo.By("creating service " + ns + "/" + serviceName + " with Service.Spec.IPFamily not set")
|
||||
service := createService(t.ServiceName, t.Namespace, t.Labels, nil)
|
||||
|
||||
jig.Labels = t.Labels
|
||||
jig.CreateServicePods(cs, ns, 2)
|
||||
svc, err := t.CreateService(service)
|
||||
framework.ExpectNoError(err, "failed to create service: %s in namespace: %s", serviceName, ns)
|
||||
|
||||
validateNumOfServicePorts(svc, 2)
|
||||
|
||||
// check the spec has been set to default ip family
|
||||
validateServiceAndClusterIPFamily(svc, defaultIPFamily)
|
||||
|
||||
// ensure endpoint belong to same ipfamily as service
|
||||
endpoint, err := cs.CoreV1().Endpoints(svc.Namespace).Get(svc.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
framework.Failf("Get endpoints for service %s/%s failed (%s)", svc.Namespace, svc.Name, err)
|
||||
}
|
||||
validateEndpointsBelongToIPFamily(svc, endpoint, defaultIPFamily)
|
||||
})
|
||||
|
||||
ginkgo.It("should create service with ipv4 cluster ip [Feature:IPv6DualStackAlphaFeature:Phase2]", func() {
|
||||
serviceName := "ipv4clusterip"
|
||||
ns := f.Namespace.Name
|
||||
ipv4 := v1.IPv4Protocol
|
||||
|
||||
jig := e2eservice.NewTestJig(cs, serviceName)
|
||||
|
||||
t := e2eservice.NewServerTest(cs, ns, serviceName)
|
||||
defer func() {
|
||||
defer ginkgo.GinkgoRecover()
|
||||
if errs := t.Cleanup(); len(errs) != 0 {
|
||||
framework.Failf("errors in cleanup: %v", errs)
|
||||
}
|
||||
}()
|
||||
|
||||
ginkgo.By("creating service " + ns + "/" + serviceName + " with Service.Spec.IPFamily IPv4" + ns)
|
||||
service := createService(t.ServiceName, t.Namespace, t.Labels, &ipv4)
|
||||
|
||||
jig.Labels = t.Labels
|
||||
jig.CreateServicePods(cs, ns, 2)
|
||||
svc, err := t.CreateService(service)
|
||||
framework.ExpectNoError(err, "failed to create service: %s in namespace: %s", serviceName, ns)
|
||||
|
||||
validateNumOfServicePorts(svc, 2)
|
||||
|
||||
// check the spec has been set to IPv4 and cluster ip belong to IPv4 family
|
||||
validateServiceAndClusterIPFamily(svc, ipv4)
|
||||
|
||||
// ensure endpoints belong to same ipfamily as service
|
||||
endpoint, err := cs.CoreV1().Endpoints(svc.Namespace).Get(svc.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
framework.Failf("Get endpoints for service %s/%s failed (%s)", svc.Namespace, svc.Name, err)
|
||||
}
|
||||
validateEndpointsBelongToIPFamily(svc, endpoint, ipv4)
|
||||
})
|
||||
|
||||
ginkgo.It("should create service with ipv6 cluster ip [Feature:IPv6DualStackAlphaFeature:Phase2]", func() {
|
||||
serviceName := "ipv6clusterip"
|
||||
ns := f.Namespace.Name
|
||||
ipv6 := v1.IPv6Protocol
|
||||
|
||||
jig := e2eservice.NewTestJig(cs, serviceName)
|
||||
|
||||
t := e2eservice.NewServerTest(cs, ns, serviceName)
|
||||
defer func() {
|
||||
defer ginkgo.GinkgoRecover()
|
||||
if errs := t.Cleanup(); len(errs) != 0 {
|
||||
framework.Failf("errors in cleanup: %v", errs)
|
||||
}
|
||||
}()
|
||||
|
||||
ginkgo.By("creating service " + ns + "/" + serviceName + " with Service.Spec.IPFamily IPv6" + ns)
|
||||
service := createService(t.ServiceName, t.Namespace, t.Labels, &ipv6)
|
||||
|
||||
jig.Labels = t.Labels
|
||||
jig.CreateServicePods(cs, ns, 2)
|
||||
svc, err := t.CreateService(service)
|
||||
framework.ExpectNoError(err, "failed to create service: %s in namespace: %s", serviceName, ns)
|
||||
|
||||
validateNumOfServicePorts(svc, 2)
|
||||
|
||||
// check the spec has been set to IPv6 and cluster ip belongs to IPv6 family
|
||||
validateServiceAndClusterIPFamily(svc, ipv6)
|
||||
|
||||
// ensure endpoints belong to same ipfamily as service
|
||||
endpoint, err := cs.CoreV1().Endpoints(svc.Namespace).Get(svc.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
framework.Failf("Get endpoints for service %s/%s failed (%s)", svc.Namespace, svc.Name, err)
|
||||
}
|
||||
validateEndpointsBelongToIPFamily(svc, endpoint, ipv6)
|
||||
})
|
||||
})
|
||||
|
||||
func validateNumOfServicePorts(svc *v1.Service, expectedNumOfPorts int) {
|
||||
if len(svc.Spec.Ports) != expectedNumOfPorts {
|
||||
framework.Failf("got unexpected len(Spec.Ports) for service: %v", svc)
|
||||
}
|
||||
}
|
||||
|
||||
func validateServiceAndClusterIPFamily(svc *v1.Service, expectedIPFamily v1.IPFamily) {
|
||||
if svc.Spec.IPFamily == nil {
|
||||
framework.Failf("service ip family nil for service %s/%s", svc.Namespace, svc.Name)
|
||||
}
|
||||
if *svc.Spec.IPFamily != expectedIPFamily {
|
||||
framework.Failf("ip family mismatch for service: %s/%s, expected: %s, actual: %s", svc.Namespace, svc.Name, expectedIPFamily, *svc.Spec.IPFamily)
|
||||
}
|
||||
|
||||
isIPv6ClusterIP := netutils.IsIPv6String(svc.Spec.ClusterIP)
|
||||
if (expectedIPFamily == v1.IPv4Protocol && isIPv6ClusterIP) || (expectedIPFamily == v1.IPv6Protocol && !isIPv6ClusterIP) {
|
||||
framework.Failf("got unexpected service ip %s, should belong to %s ip family", svc.Spec.ClusterIP, expectedIPFamily)
|
||||
}
|
||||
}
|
||||
|
||||
func validateEndpointsBelongToIPFamily(svc *v1.Service, endpoint *v1.Endpoints, expectedIPFamily v1.IPFamily) {
|
||||
if len(endpoint.Subsets) == 0 {
|
||||
framework.Failf("Endpoint has no subsets, cannot determine service ip family matches endpoints ip family for service %s/%s", svc.Namespace, svc.Name)
|
||||
}
|
||||
for _, ss := range endpoint.Subsets {
|
||||
for _, e := range ss.Addresses {
|
||||
if (expectedIPFamily == v1.IPv6Protocol && isIPv4(e.IP)) || (expectedIPFamily == v1.IPv4Protocol && netutils.IsIPv6String(e.IP)) {
|
||||
framework.Failf("service endpoint %s doesn't belong to %s ip family", e.IP, expectedIPFamily)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func assertNetworkConnectivity(f *framework.Framework, serverPods v1.PodList, clientPods v1.PodList, containerName, port string) {
|
||||
// curl from each client pod to all server pods to assert connectivity
|
||||
duration := "10s"
|
||||
@ -256,3 +402,30 @@ func isIPv4CIDR(cidr string) bool {
|
||||
framework.ExpectNoError(err)
|
||||
return isIPv4(ip.String())
|
||||
}
|
||||
|
||||
// createService returns a service spec with defined arguments
|
||||
func createService(name, ns string, labels map[string]string, ipFamily *v1.IPFamily) *v1.Service {
|
||||
return &v1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Selector: labels,
|
||||
Type: v1.ServiceTypeNodePort,
|
||||
IPFamily: ipFamily,
|
||||
Ports: []v1.ServicePort{
|
||||
{
|
||||
Name: "tcp-port",
|
||||
Port: 53,
|
||||
Protocol: v1.ProtocolTCP,
|
||||
},
|
||||
{
|
||||
Name: "udp-port",
|
||||
Port: 53,
|
||||
Protocol: v1.ProtocolUDP,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user