diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 2f1065208ce..6dd9382e40b 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -80,7 +80,6 @@ import ( evictionapi "k8s.io/kubernetes/pkg/kubelet/eviction/api" dynamickubeletconfig "k8s.io/kubernetes/pkg/kubelet/kubeletconfig" "k8s.io/kubernetes/pkg/kubelet/kubeletconfig/configfiles" - "k8s.io/kubernetes/pkg/kubelet/network/cni" "k8s.io/kubernetes/pkg/kubelet/server" "k8s.io/kubernetes/pkg/kubelet/server/streaming" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" @@ -1112,12 +1111,12 @@ func RunDockershim(f *options.KubeletFlags, c *kubeletconfiginternal.KubeletConf // Initialize network plugin settings. pluginSettings := dockershim.NetworkPluginSettings{ - HairpinMode: kubeletconfiginternal.HairpinMode(c.HairpinMode), - NonMasqueradeCIDR: f.NonMasqueradeCIDR, - PluginName: r.NetworkPluginName, - PluginConfDir: r.CNIConfDir, - PluginBinDirs: cni.SplitDirs(r.CNIBinDir), - MTU: int(r.NetworkPluginMTU), + HairpinMode: kubeletconfiginternal.HairpinMode(c.HairpinMode), + NonMasqueradeCIDR: f.NonMasqueradeCIDR, + PluginName: r.NetworkPluginName, + PluginConfDir: r.CNIConfDir, + PluginBinDirString: r.CNIBinDir, + MTU: int(r.NetworkPluginMTU), } // Initialize streaming configuration. (Not using TLS now) diff --git a/pkg/kubelet/dockershim/docker_service.go b/pkg/kubelet/dockershim/docker_service.go index 4200d1465ad..00a115eb05e 100644 --- a/pkg/kubelet/dockershim/docker_service.go +++ b/pkg/kubelet/dockershim/docker_service.go @@ -110,6 +110,9 @@ type NetworkPluginSettings struct { NonMasqueradeCIDR string // PluginName is the name of the plugin, runtime shim probes for PluginName string + // PluginBinDirsString is a list of directiores delimited by commas, in + // which the binaries for the plugin with PluginName may be found. + PluginBinDirString string // PluginBinDirs is an array of directories in which the binaries for // the plugin with PluginName may be found. The admin is responsible for // provisioning these binaries before-hand. @@ -220,7 +223,17 @@ func NewDockerService(config *ClientConfig, podSandboxImage string, streamingCon return nil, err } } + + // Determine the hairpin mode. + if err := effectiveHairpinMode(pluginSettings); err != nil { + // This is a non-recoverable error. Returning it up the callstack will just + // lead to retries of the same failure, so just fail hard. + return nil, err + } + glog.Infof("Hairpin mode set to %q", pluginSettings.HairpinMode) + // dockershim currently only supports CNI plugins. + pluginSettings.PluginBinDirs = cni.SplitDirs(pluginSettings.PluginBinDirString) cniPlugins := cni.ProbeNetworkPlugins(pluginSettings.PluginConfDir, pluginSettings.PluginBinDirs) cniPlugins = append(cniPlugins, kubenet.NewPlugin(pluginSettings.PluginBinDirs)) netHost := &dockerNetworkHost{ @@ -497,3 +510,28 @@ func toAPIProtocol(protocol Protocol) v1.Protocol { glog.Warningf("Unknown protocol %q: defaulting to TCP", protocol) return v1.ProtocolTCP } + +// effectiveHairpinMode determines the effective hairpin mode given the +// configured mode, and whether cbr0 should be configured. +func effectiveHairpinMode(s *NetworkPluginSettings) error { + // The hairpin mode setting doesn't matter if: + // - We're not using a bridge network. This is hard to check because we might + // be using a plugin. + // - It's set to hairpin-veth for a container runtime that doesn't know how + // to set the hairpin flag on the veth's of containers. Currently the + // docker runtime is the only one that understands this. + // - It's set to "none". + if s.HairpinMode == kubeletconfig.PromiscuousBridge || s.HairpinMode == kubeletconfig.HairpinVeth { + if s.HairpinMode == kubeletconfig.PromiscuousBridge && s.PluginName != "kubenet" { + // This is not a valid combination, since promiscuous-bridge only works on kubenet. Users might be using the + // default values (from before the hairpin-mode flag existed) and we + // should keep the old behavior. + glog.Warningf("Hairpin mode set to %q but kubenet is not enabled, falling back to %q", s.HairpinMode, kubeletconfig.HairpinVeth) + s.HairpinMode = kubeletconfig.HairpinVeth + return nil + } + } else if s.HairpinMode != kubeletconfig.HairpinNone { + return fmt.Errorf("unknown value: %q", s.HairpinMode) + } + return nil +} diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index fae448b7eea..9a1755ffe7f 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -76,7 +76,6 @@ import ( "k8s.io/kubernetes/pkg/kubelet/logs" "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/metrics/collectors" - "k8s.io/kubernetes/pkg/kubelet/network/cni" "k8s.io/kubernetes/pkg/kubelet/network/dns" "k8s.io/kubernetes/pkg/kubelet/pleg" kubepod "k8s.io/kubernetes/pkg/kubelet/pod" @@ -543,14 +542,6 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, glog.Infof("Experimental host user namespace defaulting is enabled.") } - hairpinMode, err := effectiveHairpinMode(kubeletconfiginternal.HairpinMode(kubeCfg.HairpinMode), crOptions.NetworkPluginName) - if err != nil { - // This is a non-recoverable error. Returning it up the callstack will just - // lead to retries of the same failure, so just fail hard. - glog.Fatalf("Invalid hairpin mode: %v", err) - } - glog.Infof("Hairpin mode set to %q", hairpinMode) - machineInfo, err := klet.cadvisor.MachineInfo() if err != nil { return nil, err @@ -574,12 +565,12 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, // TODO: These need to become arguments to a standalone docker shim. pluginSettings := dockershim.NetworkPluginSettings{ - HairpinMode: hairpinMode, - NonMasqueradeCIDR: nonMasqueradeCIDR, - PluginName: crOptions.NetworkPluginName, - PluginConfDir: crOptions.CNIConfDir, - PluginBinDirs: cni.SplitDirs(crOptions.CNIBinDir), - MTU: int(crOptions.NetworkPluginMTU), + HairpinMode: kubeletconfiginternal.HairpinMode(kubeCfg.HairpinMode), + NonMasqueradeCIDR: nonMasqueradeCIDR, + PluginName: crOptions.NetworkPluginName, + PluginConfDir: crOptions.CNIConfDir, + PluginBinDirString: crOptions.CNIBinDir, + MTU: int(crOptions.NetworkPluginMTU), } klet.resourceAnalyzer = serverstats.NewResourceAnalyzer(klet, kubeCfg.VolumeStatsAggPeriod.Duration) diff --git a/pkg/kubelet/kubelet_network.go b/pkg/kubelet/kubelet_network.go index ecdb91f60be..fd7a84e4846 100644 --- a/pkg/kubelet/kubelet_network.go +++ b/pkg/kubelet/kubelet_network.go @@ -22,7 +22,6 @@ import ( "github.com/golang/glog" "k8s.io/api/core/v1" runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" - "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig" utiliptables "k8s.io/kubernetes/pkg/util/iptables" ) @@ -41,30 +40,6 @@ const ( KubeFirewallChain utiliptables.Chain = "KUBE-FIREWALL" ) -// effectiveHairpinMode determines the effective hairpin mode given the -// configured mode, container runtime, and whether cbr0 should be configured. -func effectiveHairpinMode(hairpinMode kubeletconfig.HairpinMode, networkPlugin string) (kubeletconfig.HairpinMode, error) { - // The hairpin mode setting doesn't matter if: - // - We're not using a bridge network. This is hard to check because we might - // be using a plugin. - // - It's set to hairpin-veth for a container runtime that doesn't know how - // to set the hairpin flag on the veth's of containers. Currently the - // docker runtime is the only one that understands this. - // - It's set to "none". - if hairpinMode == kubeletconfig.PromiscuousBridge || hairpinMode == kubeletconfig.HairpinVeth { - if hairpinMode == kubeletconfig.PromiscuousBridge && networkPlugin != "kubenet" { - // This is not a valid combination, since promiscuous-bridge only works on kubenet. Users might be using the - // default values (from before the hairpin-mode flag existed) and we - // should keep the old behavior. - glog.Warningf("Hairpin mode set to %q but kubenet is not enabled, falling back to %q", hairpinMode, kubeletconfig.HairpinVeth) - return kubeletconfig.HairpinVeth, nil - } - } else if hairpinMode != kubeletconfig.HairpinNone { - return "", fmt.Errorf("unknown value: %q", hairpinMode) - } - return hairpinMode, nil -} - // providerRequiresNetworkingConfiguration returns whether the cloud provider // requires special networking configuration. func (kl *Kubelet) providerRequiresNetworkingConfiguration() bool {