Make kube-proxy check if IPv6 is really supported before assuming dual-stack

This commit is contained in:
Dan Winship
2021-02-16 12:33:18 -05:00
parent 0ce2036e81
commit 95c6a488d8
4 changed files with 56 additions and 39 deletions

View File

@@ -134,15 +134,7 @@ func newProxyServer(
}
nodeIP := detectNodeIP(client, hostname, config.BindAddress)
protocol := utiliptables.ProtocolIPv4
if utilsnet.IsIPv6(nodeIP) {
klog.V(0).Infof("kube-proxy node IP is an IPv6 address (%s), assume IPv6 operation", nodeIP.String())
protocol = utiliptables.ProtocolIPv6
} else {
klog.V(0).Infof("kube-proxy node IP is an IPv4 address (%s), assume IPv4 operation", nodeIP.String())
}
iptInterface = utiliptables.New(execer, protocol)
klog.Infof("Detected node IP %s", nodeIP.String())
// Create event recorder
eventBroadcaster := record.NewBroadcaster()
@@ -181,6 +173,38 @@ func newProxyServer(
klog.V(2).Info("DetectLocalMode: '", string(detectLocalMode), "'")
primaryProtocol := utiliptables.ProtocolIPv4
if utilsnet.IsIPv6(nodeIP) {
primaryProtocol = utiliptables.ProtocolIPv6
}
iptInterface = utiliptables.New(execer, primaryProtocol)
var ipt [2]utiliptables.Interface
dualStack := utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) && proxyMode != proxyModeUserspace
if dualStack {
// Create iptables handlers for both families, one is already created
// Always ordered as IPv4, IPv6
if primaryProtocol == utiliptables.ProtocolIPv4 {
ipt[0] = iptInterface
ipt[1] = utiliptables.New(execer, utiliptables.ProtocolIPv6)
// Just because the feature gate is enabled doesn't mean the node
// actually supports dual-stack
if _, err := ipt[1].ChainExists(utiliptables.TableNAT, utiliptables.ChainPostrouting); err != nil {
klog.Warningf("No iptables support for IPv6: %v", err)
dualStack = false
}
} else {
ipt[0] = utiliptables.New(execer, utiliptables.ProtocolIPv4)
ipt[1] = iptInterface
}
}
if dualStack {
klog.V(0).Infof("kube-proxy running in dual-stack mode, %s-primary", iptInterface.Protocol())
} else {
klog.V(0).Infof("kube-proxy running in single-stack %s mode", iptInterface.Protocol())
}
if proxyMode == proxyModeIPTables {
klog.V(0).Info("Using iptables Proxier.")
if config.IPTables.MasqueradeBit == nil {
@@ -188,20 +212,9 @@ func newProxyServer(
return nil, fmt.Errorf("unable to read IPTables MasqueradeBit from config")
}
if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
if dualStack {
klog.V(0).Info("creating dualStackProxier for iptables.")
// Create iptables handlers for both families, one is already created
// Always ordered as IPv4, IPv6
var ipt [2]utiliptables.Interface
if iptInterface.IsIPv6() {
ipt[1] = iptInterface
ipt[0] = utiliptables.New(execer, utiliptables.ProtocolIPv4)
} else {
ipt[0] = iptInterface
ipt[1] = utiliptables.New(execer, utiliptables.ProtocolIPv6)
}
// Always ordered to match []ipt
var localDetectors [2]proxyutiliptables.LocalTrafficDetector
localDetectors, err = getDualStackLocalDetectorTuple(detectLocalMode, config, ipt, nodeInfo)
@@ -256,20 +269,9 @@ func newProxyServer(
proxymetrics.RegisterMetrics()
} else if proxyMode == proxyModeIPVS {
klog.V(0).Info("Using ipvs Proxier.")
if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) {
if dualStack {
klog.V(0).Info("creating dualStackProxier for ipvs.")
// Create iptables handlers for both families, one is already created
// Always ordered as IPv4, IPv6
var ipt [2]utiliptables.Interface
if iptInterface.IsIPv6() {
ipt[1] = iptInterface
ipt[0] = utiliptables.New(execer, utiliptables.ProtocolIPv4)
} else {
ipt[0] = iptInterface
ipt[1] = utiliptables.New(execer, utiliptables.ProtocolIPv6)
}
nodeIPs := nodeIPTuple(config.BindAddress)
// Always ordered to match []ipt