mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-08 03:33:56 +00:00
Figure out single-stack/dual-stack support before creating the proxier
Rather than having this as part of createProxier(), explicitly figure out what IP families the proxier can support beforehand, and bail out if this conflicts with the detected IP family.
This commit is contained in:
parent
8abfa89e82
commit
1f2bf32e95
@ -572,7 +572,18 @@ func newProxyServer(config *kubeproxyconfig.KubeProxyConfiguration, master strin
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.Proxier, err = s.createProxier(config)
|
||||
ipv4Supported, ipv6Supported, dualStackSupported, err := s.platformCheckSupported()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if (s.PrimaryIPFamily == v1.IPv4Protocol && !ipv4Supported) || (s.PrimaryIPFamily == v1.IPv6Protocol && !ipv6Supported) {
|
||||
return nil, fmt.Errorf("no support for primary IP family %q", s.PrimaryIPFamily)
|
||||
} else if dualStackSupported {
|
||||
klog.InfoS("kube-proxy running in dual-stack mode", "primary ipFamily", s.PrimaryIPFamily)
|
||||
} else {
|
||||
klog.InfoS("kube-proxy running in single-stack mode", "ipFamily", s.PrimaryIPFamily)
|
||||
}
|
||||
|
||||
s.Proxier, err = s.createProxier(config, dualStackSupported)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -101,8 +101,32 @@ func (s *ProxyServer) platformSetup() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// platformCheckSupported is called immediately before creating the Proxier, to check
|
||||
// what IP families are supported (and whether the configuration is usable at all).
|
||||
func (s *ProxyServer) platformCheckSupported() (ipv4Supported, ipv6Supported, dualStackSupported bool, err error) {
|
||||
execer := exec.New()
|
||||
ipt := utiliptables.New(execer, utiliptables.ProtocolIPv4)
|
||||
ipv4Supported = ipt.Present()
|
||||
ipt = utiliptables.New(execer, utiliptables.ProtocolIPv6)
|
||||
ipv6Supported = ipt.Present()
|
||||
|
||||
// The Linux proxies can always support dual-stack if they can support both IPv4
|
||||
// and IPv6.
|
||||
dualStackSupported = ipv4Supported && ipv6Supported
|
||||
|
||||
if !ipv4Supported && !ipv6Supported {
|
||||
err = fmt.Errorf("iptables is not available on this host")
|
||||
} else if !ipv4Supported {
|
||||
klog.InfoS("No iptables support for family", "ipFamily", v1.IPv4Protocol)
|
||||
} else if !ipv6Supported {
|
||||
klog.InfoS("No iptables support for family", "ipFamily", v1.IPv6Protocol)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// createProxier creates the proxy.Provider
|
||||
func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguration) (proxy.Provider, error) {
|
||||
func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguration, dualStack bool) (proxy.Provider, error) {
|
||||
var proxier proxy.Provider
|
||||
var err error
|
||||
|
||||
@ -114,7 +138,6 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
||||
iptInterface := utiliptables.New(execer, primaryProtocol)
|
||||
|
||||
var ipt [2]utiliptables.Interface
|
||||
dualStack := true // While we assume that node supports, we do further checks below
|
||||
|
||||
// Create iptables handlers for both families, one is already created
|
||||
// Always ordered as IPv4, IPv6
|
||||
@ -126,12 +149,7 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
||||
ipt[1] = iptInterface
|
||||
}
|
||||
|
||||
if !ipt[0].Present() {
|
||||
return nil, fmt.Errorf("iptables is not supported for primary IP family %q", primaryProtocol)
|
||||
} else if !ipt[1].Present() {
|
||||
klog.InfoS("kube-proxy running in single-stack mode: secondary ipFamily is not supported", "ipFamily", ipt[1].Protocol())
|
||||
dualStack = false
|
||||
|
||||
if !dualStack {
|
||||
// Validate NodePortAddresses is single-stack
|
||||
npaByFamily := proxyutil.MapCIDRsByIPFamily(config.NodePortAddresses)
|
||||
secondaryFamily := proxyutil.OtherIPFamily(s.PrimaryIPFamily)
|
||||
@ -145,8 +163,6 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
||||
klog.InfoS("Using iptables Proxier")
|
||||
|
||||
if dualStack {
|
||||
klog.InfoS("kube-proxy running in dual-stack mode", "ipFamily", iptInterface.Protocol())
|
||||
klog.InfoS("Creating dualStackProxier for iptables")
|
||||
// Always ordered to match []ipt
|
||||
var localDetectors [2]proxyutiliptables.LocalTrafficDetector
|
||||
localDetectors, err = getDualStackLocalDetectorTuple(config.DetectLocalMode, config, ipt, s.podCIDRs)
|
||||
@ -212,8 +228,6 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
||||
|
||||
klog.InfoS("Using ipvs Proxier")
|
||||
if dualStack {
|
||||
klog.InfoS("Creating dualStackProxier for ipvs")
|
||||
|
||||
// Always ordered to match []ipt
|
||||
var localDetectors [2]proxyutiliptables.LocalTrafficDetector
|
||||
localDetectors, err = getDualStackLocalDetectorTuple(config.DetectLocalMode, config, ipt, s.podCIDRs)
|
||||
|
@ -30,7 +30,6 @@ import (
|
||||
// Enable pprof HTTP handlers.
|
||||
_ "net/http/pprof"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubernetes/pkg/proxy"
|
||||
proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config"
|
||||
"k8s.io/kubernetes/pkg/proxy/winkernel"
|
||||
@ -52,26 +51,38 @@ func (s *ProxyServer) platformSetup() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// platformCheckSupported is called immediately before creating the Proxier, to check
|
||||
// what IP families are supported (and whether the configuration is usable at all).
|
||||
func (s *ProxyServer) platformCheckSupported() (ipv4Supported, ipv6Supported, dualStackSupported bool, err error) {
|
||||
// Check if Kernel proxier can be used at all
|
||||
_, err = winkernel.CanUseWinKernelProxier(winkernel.WindowsKernelCompatTester{})
|
||||
if err != nil {
|
||||
return false, false, false, err
|
||||
}
|
||||
|
||||
// winkernel always supports both single-stack IPv4 and single-stack IPv6, but may
|
||||
// not support dual-stack.
|
||||
ipv4Supported = true
|
||||
ipv6Supported = true
|
||||
|
||||
compatTester := winkernel.DualStackCompatTester{}
|
||||
dualStackSupported = compatTester.DualStackCompatible(s.Config.Winkernel.NetworkName)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// createProxier creates the proxy.Provider
|
||||
func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguration) (proxy.Provider, error) {
|
||||
func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguration, dualStackMode bool) (proxy.Provider, error) {
|
||||
var healthzPort int
|
||||
if len(config.HealthzBindAddress) > 0 {
|
||||
_, port, _ := net.SplitHostPort(config.HealthzBindAddress)
|
||||
healthzPort, _ = strconv.Atoi(port)
|
||||
}
|
||||
|
||||
// Check if Kernel Space can be used.
|
||||
canUseWinKernelProxy, err := winkernel.CanUseWinKernelProxier(winkernel.WindowsKernelCompatTester{})
|
||||
if !canUseWinKernelProxy && err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var proxier proxy.Provider
|
||||
var err error
|
||||
|
||||
dualStackMode := getDualStackMode(config.Winkernel.NetworkName, winkernel.DualStackCompatTester{})
|
||||
if dualStackMode {
|
||||
klog.InfoS("Creating dualStackProxier for Windows kernel.")
|
||||
|
||||
proxier, err = winkernel.NewDualStackProxier(
|
||||
config.IPTables.SyncPeriod.Duration,
|
||||
config.IPTables.MinSyncPeriod.Duration,
|
||||
@ -103,10 +114,6 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
|
||||
return proxier, nil
|
||||
}
|
||||
|
||||
func getDualStackMode(networkname string, compatTester winkernel.StackCompatTester) bool {
|
||||
return compatTester.DualStackCompatible(networkname)
|
||||
}
|
||||
|
||||
// cleanupAndExit cleans up after a previous proxy run
|
||||
func cleanupAndExit() error {
|
||||
return errors.New("--cleanup-and-exit is not implemented on Windows")
|
||||
|
Loading…
Reference in New Issue
Block a user