@@ -48,8 +48,10 @@ import (
48
48
"k8s.io/kubernetes/pkg/proxy/apis/config"
49
49
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
50
50
"k8s.io/kubernetes/pkg/proxy/healthcheck"
51
+ "k8s.io/kubernetes/pkg/proxy/metaproxier"
51
52
"k8s.io/kubernetes/pkg/proxy/metrics"
52
53
"k8s.io/kubernetes/pkg/util/async"
54
+ utilnet "k8s.io/utils/net"
53
55
)
54
56
55
57
// KernelCompatTester tests whether the required kernel capabilities are
@@ -101,6 +103,7 @@ type loadBalancerFlags struct {
101
103
useMUX bool
102
104
preserveDIP bool
103
105
sessionAffinity bool
106
+ isIPv6 bool
104
107
}
105
108
106
109
// internal struct for string service information
@@ -163,13 +166,17 @@ type endpointsInfo struct {
163
166
hns HostNetworkService
164
167
}
165
168
166
- //Uses mac prefix and IPv4 address to return a mac address
169
+ //Uses mac prefix and IP address to return a mac address
167
170
//This ensures mac addresses are unique for proper load balancing
168
- //Does not support IPv6 and returns a dummy mac
171
+ //There is a possibility of MAC collisions but this Mac address is used for remote endpoints only
172
+ //and not sent on the wire.
169
173
func conjureMac (macPrefix string , ip net.IP ) string {
170
174
if ip4 := ip .To4 (); ip4 != nil {
171
175
a , b , c , d := ip4 [0 ], ip4 [1 ], ip4 [2 ], ip4 [3 ]
172
176
return fmt .Sprintf ("%v-%02x-%02x-%02x-%02x" , macPrefix , a , b , c , d )
177
+ } else if ip6 := ip .To16 (); ip6 != nil {
178
+ a , b , c , d := ip6 [15 ], ip6 [14 ], ip6 [13 ], ip6 [12 ]
179
+ return fmt .Sprintf ("%v-%02x-%02x-%02x-%02x" , macPrefix , a , b , c , d )
173
180
}
174
181
return "02-11-22-33-44-55"
175
182
}
@@ -502,6 +509,7 @@ type Proxier struct {
502
509
// with some partial data after kube-proxy restart.
503
510
endpointsSynced bool
504
511
servicesSynced bool
512
+ isIPv6Mode bool
505
513
initialized int32
506
514
syncRunner * async.BoundedFrequencyRunner // governs calls to syncProxyRules
507
515
@@ -664,6 +672,8 @@ func NewProxier(
664
672
}
665
673
}
666
674
675
+ isIPv6 := utilnet .IsIPv6 (nodeIP )
676
+
667
677
proxier := & Proxier {
668
678
portsMap : make (map [localPort ]closeable ),
669
679
serviceMap : make (proxyServiceMap ),
@@ -685,6 +695,7 @@ func NewProxier(
685
695
hostMac : hostMac ,
686
696
isDSR : isDSR ,
687
697
supportedFeatures : supportedFeatures ,
698
+ isIPv6Mode : isIPv6 ,
688
699
}
689
700
690
701
burstSyncs := 2
@@ -694,6 +705,38 @@ func NewProxier(
694
705
695
706
}
696
707
708
+ func NewDualStackProxier (
709
+ syncPeriod time.Duration ,
710
+ minSyncPeriod time.Duration ,
711
+ masqueradeAll bool ,
712
+ masqueradeBit int ,
713
+ clusterCIDR string ,
714
+ hostname string ,
715
+ nodeIP [2 ]net.IP ,
716
+ recorder record.EventRecorder ,
717
+ healthzServer healthcheck.ProxierHealthUpdater ,
718
+ config config.KubeProxyWinkernelConfiguration ,
719
+ ) (proxy.Provider , error ) {
720
+
721
+ // Create an ipv4 instance of the single-stack proxier
722
+ ipv4Proxier , err := NewProxier (syncPeriod , minSyncPeriod , masqueradeAll , masqueradeBit ,
723
+ clusterCIDR , hostname , nodeIP [0 ], recorder , healthzServer , config )
724
+
725
+ if err != nil {
726
+ return nil , fmt .Errorf ("unable to create ipv4 proxier: %v, hostname: %s, clusterCIDR : %s, nodeIP:%v" , err , hostname , clusterCIDR , nodeIP [0 ])
727
+ }
728
+
729
+ ipv6Proxier , err := NewProxier (syncPeriod , minSyncPeriod , masqueradeAll , masqueradeBit ,
730
+ clusterCIDR , hostname , nodeIP [1 ], recorder , healthzServer , config )
731
+ if err != nil {
732
+ return nil , fmt .Errorf ("unable to create ipv6 proxier: %v, hostname: %s, clusterCIDR : %s, nodeIP:%v" , err , hostname , clusterCIDR , nodeIP [1 ])
733
+ }
734
+
735
+ // Return a meta-proxier that dispatch calls between the two
736
+ // single-stack proxier instances
737
+ return metaproxier .NewMetaProxier (ipv4Proxier , ipv6Proxier ), nil
738
+ }
739
+
697
740
// CleanupLeftovers removes all hns rules created by the Proxier
698
741
// It returns true if an error was encountered. Errors are logged.
699
742
func CleanupLeftovers () (encounteredError bool ) {
@@ -1275,7 +1318,7 @@ func (proxier *Proxier) syncProxyRules() {
1275
1318
1276
1319
hnsLoadBalancer , err := hns .getLoadBalancer (
1277
1320
hnsEndpoints ,
1278
- loadBalancerFlags {isDSR : proxier .isDSR , sessionAffinity : sessionAffinityClientIP },
1321
+ loadBalancerFlags {isDSR : proxier .isDSR , isIPv6 : proxier . isIPv6Mode , sessionAffinity : sessionAffinityClientIP },
1279
1322
sourceVip ,
1280
1323
svcInfo .clusterIP .String (),
1281
1324
Enum (svcInfo .protocol ),
@@ -1300,7 +1343,7 @@ func (proxier *Proxier) syncProxyRules() {
1300
1343
}
1301
1344
hnsLoadBalancer , err := hns .getLoadBalancer (
1302
1345
nodePortEndpoints ,
1303
- loadBalancerFlags {localRoutedVIP : true , sessionAffinity : sessionAffinityClientIP },
1346
+ loadBalancerFlags {localRoutedVIP : true , sessionAffinity : sessionAffinityClientIP , isIPv6 : proxier . isIPv6Mode },
1304
1347
sourceVip ,
1305
1348
"" ,
1306
1349
Enum (svcInfo .protocol ),
@@ -1321,7 +1364,7 @@ func (proxier *Proxier) syncProxyRules() {
1321
1364
// Try loading existing policies, if already available
1322
1365
hnsLoadBalancer , err = hns .getLoadBalancer (
1323
1366
hnsEndpoints ,
1324
- loadBalancerFlags {sessionAffinity : sessionAffinityClientIP },
1367
+ loadBalancerFlags {sessionAffinity : sessionAffinityClientIP , isIPv6 : proxier . isIPv6Mode },
1325
1368
sourceVip ,
1326
1369
externalIP .ip ,
1327
1370
Enum (svcInfo .protocol ),
@@ -1344,7 +1387,7 @@ func (proxier *Proxier) syncProxyRules() {
1344
1387
}
1345
1388
hnsLoadBalancer , err := hns .getLoadBalancer (
1346
1389
lbIngressEndpoints ,
1347
- loadBalancerFlags {isDSR : svcInfo .preserveDIP || proxier .isDSR , useMUX : svcInfo .preserveDIP , preserveDIP : svcInfo .preserveDIP , sessionAffinity : sessionAffinityClientIP },
1390
+ loadBalancerFlags {isDSR : svcInfo .preserveDIP || proxier .isDSR , useMUX : svcInfo .preserveDIP , preserveDIP : svcInfo .preserveDIP , sessionAffinity : sessionAffinityClientIP , isIPv6 : proxier . isIPv6Mode },
1348
1391
sourceVip ,
1349
1392
lbIngressIP .ip ,
1350
1393
Enum (svcInfo .protocol ),
0 commit comments