Change:
What happened: When K8s is started in dual-stack mode with IPv6 as the "main" (or base) family services specified with ipFamily:IPv4 still get a ipv6 ; The is expicitly set to "10.0.0.0" using . What you expected to happen: Services with ipFamily:IPv4 shall get ipv4 ClusterIP addresses. How to reproduce it (as minimally and precisely as possible): Setup a K8s cluster in dual-stack mode with family IPv6 as base Define a service with ipFamily: IPv4 To make K8s think IPv6 is the main family the cue is to define ipv6 addresses to K8s binaries. Below are my settings as an example. I do not use but install "from scratch"; Master processes; is accessed with ipv4 which does not affect the K8s family. Worker processes; Anything else we need to know?: There are other problems with dual-stack/ipv6-base but may be caused by this one. For example does not work and some processes does not become "ready". Ipv6 traffic to ipv6 services and DNS works; Environment: Kubernetes version (use ):Cloud provider or hardware configuration: - OS (e.g: ): BusyBox based own setup. Kernel (e.g. ):Install tools: "from scratch" Network plugin and version (if this is a network-related bug): Others:
/sig network /cc
The problem seem to be; The problem occurs when an ipv6 range is specified first, even in an ipv4-based dual-stack cluster. But the ipv6 range must be specified first otherwise the "kubernetes" service gets an ipv4 address but an ipv6 backend; ~Perhaps the way to fix this problem is to make sure the service address is from the right family and require that the order to is "ipv4,ipv6".~ Bad idea!
There seem to be a option; But I can't see it in the help printout. I will try to use it...
:disappointed:
Here it where the kubernetes service address is set;
/assign
/triage unresolved Comment when the issue is assessed and confirmed. I am a bot run by vllry. ‍

Discussion:
} secondaryAllocatorCIDR := r.secondaryServiceIPs.CIDR() <del> if netutil.IsIPv6String(service.Spec.ClusterIP) && netutil.IsIPv6CIDR(&secondaryAllocatorCIDR) { </del> <ins> if netutil.IsIPv6String(service.Spec.ClusterIP) == netutil.IsIPv6CIDR(&secondaryAllocatorCIDR) { </ins> return r.secondaryServiceIPs }

} secondaryAllocatorCIDR := r.secondaryServiceIPs.CIDR() <del> if *(service.Spec.IPFamily) == api.IPv6Protocol && netutil.IsIPv6CIDR(&secondaryAllocatorCIDR) { </del> <ins> if (*(service.Spec.IPFamily) == api.IPv6Protocol) == netutil.IsIPv6CIDR(&secondaryAllocatorCIDR) { </ins> return r.secondaryServiceIPs }

testCases := []struct { name string <ins> isIPv6Primary          bool </ins> enableDualStack        bool specExpctPrimary       bool clusterIPExpectPrimary bool

svc *api.Service }{ { <del> name: "spec:v4 ip:v4 dualstack:off", </del> <ins> name: "spec:v4 ip:v4 dualstack:off isIPv6Primary:false", isIPv6Primary:          false, </ins> specExpctPrimary:       true, clusterIPExpectPrimary: true, enableDualStack:        false,

}, }, { <del> name: "spec:v4 ip:v4 dualstack:on", </del> <ins> name: "spec:v4 ip:v4 dualstack:on isIPv6Primary:false", isIPv6Primary:          false, </ins> specExpctPrimary:       true, clusterIPExpectPrimary: true, enableDualStack:        true,

}, { <del> name: "spec:v4 ip:v6 dualstack:on", </del> <ins> name: "spec:v4 ip:v6 dualstack:on isIPv6Primary:false", isIPv6Primary:          false, </ins> specExpctPrimary:       true, clusterIPExpectPrimary: false, enableDualStack:        true,

}, { <del> name: "spec:v6 ip:v6 dualstack:on", </del> <ins> name: "spec:v6 ip:v6 dualstack:on isIPv6Primary:false", isIPv6Primary:          false, </ins> specExpctPrimary:       false, clusterIPExpectPrimary: false, enableDualStack:        true,

}, { <del> name: "spec:v6 ip:v4 dualstack:on", </del> <ins> name: "spec:v6 ip:v4 dualstack:on isIPv6Primary:false", isIPv6Primary:          false, </ins> specExpctPrimary:       false, clusterIPExpectPrimary: true, enableDualStack:        true,

}, }, }, <ins> { name: "spec:v6 ip:v6 dualstack:off isIPv6Primary:true", isIPv6Primary:          true, specExpctPrimary:       true, clusterIPExpectPrimary: true, enableDualStack:        false, svc: &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector:  map[string]string{"bar": "baz"}, Type:      api.ServiceTypeClusterIP, IPFamily:  &ipv6Service, ClusterIP: "2000::1", }, }, }, { name: "spec:v6 ip:v6 dualstack:on isIPv6Primary:true", isIPv6Primary:          true, specExpctPrimary:       true, clusterIPExpectPrimary: true, enableDualStack:        true, svc: &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector:  map[string]string{"bar": "baz"}, Type:      api.ServiceTypeClusterIP, IPFamily:  &ipv6Service, ClusterIP: "2000::1", }, }, }, { name: "spec:v6 ip:v4 dualstack:on isIPv6Primary:true", isIPv6Primary:          true, specExpctPrimary:       true, clusterIPExpectPrimary: false, enableDualStack:        true, svc: &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector:  map[string]string{"bar": "baz"}, Type:      api.ServiceTypeClusterIP, IPFamily:  &ipv6Service, ClusterIP: "10.0.0.1", }, }, }, { name: "spec:v4 ip:v4 dualstack:on isIPv6Primary:true", isIPv6Primary:          true, specExpctPrimary:       false, clusterIPExpectPrimary: false, enableDualStack:        true, svc: &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector:  map[string]string{"bar": "baz"}, Type:      api.ServiceTypeClusterIP, IPFamily:  &ipv4Service, ClusterIP: "10.0.0.1", }, }, }, { name: "spec:v4 ip:v6 dualstack:on isIPv6Primary:true", isIPv6Primary:          true, specExpctPrimary:       false, clusterIPExpectPrimary: true, enableDualStack:        true, svc: &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector:  map[string]string{"bar": "baz"}, Type:      api.ServiceTypeClusterIP, IPFamily:  &ipv4Service, ClusterIP: "2000::1", }, }, }, </ins> } for _, tc := range testCases {

storage, _, server := NewTestREST(t, nil, tc.enableDualStack) defer server.Terminate(t) <ins> if tc.isIPv6Primary { if storage.secondaryServiceIPs != nil { storage.serviceIPs, storage.secondaryServiceIPs = storage.secondaryServiceIPs, storage.serviceIPs } else { r, err := ipallocator.NewCIDRRange(makeIPNet6(t)) if err != nil { t.Fatalf("cannot create CIDR Range(primary) %v", err) } if tc.enableDualStack { storage.secondaryServiceIPs = storage.serviceIPs } storage.serviceIPs = r } } </ins> if tc.enableDualStack && storage.secondaryServiceIPs == nil { t.Errorf("storage must allocate secondary ServiceIPs allocator for dual stack") return