Merge pull request #58714 from dcbw/cni-plugin-dirs

Automatic merge from submit-queue (batch tested with PRs 59740, 59728, 60080, 60086, 58714). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

kubelet: make --cni-bin-dir accept a comma-separated list of CNI plugin directories

Allow CNI-related network plugin drivers (kubenet, cni) to search a list of
directories for plugin binaries instead of just one.  This allows using an
administrator-provided path and fallbacks to others (like the previous default
of /opt/cni/bin) for backwards compatibility.

```release-note
kubelet's --cni-bin-dir option now accepts multiple comma-separated CNI binary directory paths, which are search for CNI plugins in the given order.
```

@kubernetes/rh-networking @kubernetes/sig-network-misc @freehan @pecameron @rajatchopra
This commit is contained in:
Kubernetes Submit Queue 2018-03-19 21:34:39 -07:00 committed by GitHub
commit 7bd2263566
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 120 additions and 118 deletions

View File

@ -114,12 +114,12 @@ func GetDynamicPluginProber(pluginDir string) volume.DynamicPluginProber {
}
// ProbeNetworkPlugins collects all compiled-in plugins
func ProbeNetworkPlugins(cniConfDir, cniBinDir string) []network.NetworkPlugin {
func ProbeNetworkPlugins(cniConfDir string, cniBinDirs []string) []network.NetworkPlugin {
allPlugins := []network.NetworkPlugin{}
// for each existing plugin, add to the list
allPlugins = append(allPlugins, cni.ProbeNetworkPlugins(cniConfDir, cniBinDir)...)
allPlugins = append(allPlugins, kubenet.NewPlugin(cniBinDir))
allPlugins = append(allPlugins, cni.ProbeNetworkPlugins(cniConfDir, cniBinDirs)...)
allPlugins = append(allPlugins, kubenet.NewPlugin(cniBinDirs))
return allPlugins
}

View File

@ -80,6 +80,7 @@ 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"
@ -358,7 +359,7 @@ func UnsecuredDependencies(s *options.KubeletServer) (*kubelet.Dependencies, err
ExternalKubeClient: nil,
EventClient: nil,
Mounter: mounter,
NetworkPlugins: ProbeNetworkPlugins(s.CNIConfDir, s.CNIBinDir),
NetworkPlugins: ProbeNetworkPlugins(s.CNIConfDir, cni.SplitDirs(s.CNIBinDir)),
OOMAdjuster: oom.NewOOMAdjuster(),
OSInterface: kubecontainer.RealOS{},
Writer: writer,
@ -1117,7 +1118,7 @@ func RunDockershim(f *options.KubeletFlags, c *kubeletconfiginternal.KubeletConf
NonMasqueradeCIDR: f.NonMasqueradeCIDR,
PluginName: r.NetworkPluginName,
PluginConfDir: r.CNIConfDir,
PluginBinDir: r.CNIBinDir,
PluginBinDirs: cni.SplitDirs(r.CNIBinDir),
MTU: int(r.NetworkPluginMTU),
LegacyRuntimeHost: nh,
}

View File

@ -66,6 +66,7 @@ go_library(
"//pkg/kubelet/metrics/collectors:go_default_library",
"//pkg/kubelet/mountpod:go_default_library",
"//pkg/kubelet/network:go_default_library",
"//pkg/kubelet/network/cni:go_default_library",
"//pkg/kubelet/network/dns:go_default_library",
"//pkg/kubelet/pleg:go_default_library",
"//pkg/kubelet/pod:go_default_library",

View File

@ -98,7 +98,7 @@ func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) {
// Network plugin settings. Shared by both docker and rkt.
fs.StringVar(&s.NetworkPluginName, "network-plugin", s.NetworkPluginName, "<Warning: Alpha feature> The name of the network plugin to be invoked for various events in kubelet/pod lifecycle")
fs.StringVar(&s.CNIConfDir, "cni-conf-dir", s.CNIConfDir, "<Warning: Alpha feature> The full path of the directory in which to search for CNI config files. Default: /etc/cni/net.d")
fs.StringVar(&s.CNIBinDir, "cni-bin-dir", s.CNIBinDir, "<Warning: Alpha feature> The full path of the directory in which to search for CNI plugin binaries. Default: /opt/cni/bin")
fs.StringVar(&s.CNIBinDir, "cni-bin-dir", s.CNIBinDir, "<Warning: Alpha feature> A comma-separated list of full paths of directories in which to search for CNI plugin binaries. Default: /opt/cni/bin")
fs.Int32Var(&s.NetworkPluginMTU, "network-plugin-mtu", s.NetworkPluginMTU, "<Warning: Alpha feature> The MTU to be passed to the network plugin, to override the default. Set to 0 to use the default 1460 MTU.")
// Rkt-specific settings.

View File

@ -110,10 +110,10 @@ type NetworkPluginSettings struct {
NonMasqueradeCIDR string
// PluginName is the name of the plugin, runtime shim probes for
PluginName string
// PluginBinDir is the directory in which the binaries for the plugin with
// PluginName is kept. The admin is responsible for provisioning these
// binaries before-hand.
PluginBinDir 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.
PluginBinDirs []string
// PluginConfDir is the directory in which the admin places a CNI conf.
// Depending on the plugin, this may be an optional field, eg: kubenet
// generates its own plugin conf.
@ -229,8 +229,8 @@ func NewDockerService(config *ClientConfig, podSandboxImage string, streamingCon
}
}
// dockershim currently only supports CNI plugins.
cniPlugins := cni.ProbeNetworkPlugins(pluginSettings.PluginConfDir, pluginSettings.PluginBinDir)
cniPlugins = append(cniPlugins, kubenet.NewPlugin(pluginSettings.PluginBinDir))
cniPlugins := cni.ProbeNetworkPlugins(pluginSettings.PluginConfDir, pluginSettings.PluginBinDirs)
cniPlugins = append(cniPlugins, kubenet.NewPlugin(pluginSettings.PluginBinDirs))
netHost := &dockerNetworkHost{
pluginSettings.LegacyRuntimeHost,
&namespaceGetter{ds},

View File

@ -79,6 +79,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/metrics"
"k8s.io/kubernetes/pkg/kubelet/metrics/collectors"
"k8s.io/kubernetes/pkg/kubelet/network"
"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"
@ -587,7 +588,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
NonMasqueradeCIDR: nonMasqueradeCIDR,
PluginName: crOptions.NetworkPluginName,
PluginConfDir: crOptions.CNIConfDir,
PluginBinDir: crOptions.CNIBinDir,
PluginBinDirs: cni.SplitDirs(crOptions.CNIBinDir),
MTU: int(crOptions.NetworkPluginMTU),
}

View File

@ -33,10 +33,9 @@ import (
)
const (
CNIPluginName = "cni"
DefaultNetDir = "/etc/cni/net.d"
DefaultCNIDir = "/opt/cni/bin"
VendorCNIDirTemplate = "%s/opt/%s/bin"
CNIPluginName = "cni"
DefaultConfDir = "/etc/cni/net.d"
DefaultBinDir = "/opt/cni/bin"
)
type cniNetworkPlugin struct {
@ -47,12 +46,11 @@ type cniNetworkPlugin struct {
sync.RWMutex
defaultNetwork *cniNetwork
host network.Host
execer utilexec.Interface
nsenterPath string
pluginDir string
binDir string
vendorCNIDirPrefix string
host network.Host
execer utilexec.Interface
nsenterPath string
confDir string
binDirs []string
}
type cniNetwork struct {
@ -70,17 +68,33 @@ type cniPortMapping struct {
HostIP string `json:"hostIP"`
}
func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, binDir, vendorCNIDirPrefix string) []network.NetworkPlugin {
if binDir == "" {
binDir = DefaultCNIDir
func SplitDirs(dirs string) []string {
// Use comma rather than colon to work better with Windows too
return strings.Split(dirs, ",")
}
func ProbeNetworkPlugins(confDir string, binDirs []string) []network.NetworkPlugin {
old := binDirs
binDirs = make([]string, len(binDirs))
for _, dir := range old {
if dir != "" {
binDirs = append(binDirs, dir)
}
}
if len(binDirs) == 0 {
binDirs = []string{DefaultBinDir}
}
if confDir == "" {
confDir = DefaultConfDir
}
plugin := &cniNetworkPlugin{
defaultNetwork: nil,
loNetwork: getLoNetwork(binDir, vendorCNIDirPrefix),
execer: utilexec.New(),
pluginDir: pluginDir,
binDir: binDir,
vendorCNIDirPrefix: vendorCNIDirPrefix,
defaultNetwork: nil,
loNetwork: getLoNetwork(binDirs),
execer: utilexec.New(),
confDir: confDir,
binDirs: binDirs,
}
// sync NetworkConfig in best effort during probing.
@ -88,20 +102,13 @@ func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, binDir, vendorCNIDirPr
return []network.NetworkPlugin{plugin}
}
func ProbeNetworkPlugins(pluginDir, binDir string) []network.NetworkPlugin {
return probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, binDir, "")
}
func getDefaultCNINetwork(pluginDir, binDir, vendorCNIDirPrefix string) (*cniNetwork, error) {
if pluginDir == "" {
pluginDir = DefaultNetDir
}
files, err := libcni.ConfFiles(pluginDir, []string{".conf", ".conflist", ".json"})
func getDefaultCNINetwork(confDir string, binDirs []string) (*cniNetwork, error) {
files, err := libcni.ConfFiles(confDir, []string{".conf", ".conflist", ".json"})
switch {
case err != nil:
return nil, err
case len(files) == 0:
return nil, fmt.Errorf("No networks found in %s", pluginDir)
return nil, fmt.Errorf("No networks found in %s", confDir)
}
sort.Strings(files)
@ -136,21 +143,15 @@ func getDefaultCNINetwork(pluginDir, binDir, vendorCNIDirPrefix string) (*cniNet
glog.Warningf("CNI config list %s has no networks, skipping", confFile)
continue
}
confType := confList.Plugins[0].Network.Type
// Search for vendor-specific plugins as well as default plugins in the CNI codebase.
vendorDir := vendorCNIDir(vendorCNIDirPrefix, confType)
cninet := &libcni.CNIConfig{
Path: []string{vendorDir, binDir},
network := &cniNetwork{
name: confList.Name,
NetworkConfig: confList,
CNIConfig: &libcni.CNIConfig{Path: binDirs},
}
network := &cniNetwork{name: confList.Name, NetworkConfig: confList, CNIConfig: cninet}
return network, nil
}
return nil, fmt.Errorf("No valid networks found in %s", pluginDir)
}
func vendorCNIDir(prefix, pluginType string) string {
return fmt.Sprintf(VendorCNIDirTemplate, prefix, pluginType)
return nil, fmt.Errorf("No valid networks found in %s", confDir)
}
func (plugin *cniNetworkPlugin) Init(host network.Host, hairpinMode kubeletconfig.HairpinMode, nonMasqueradeCIDR string, mtu int) error {
@ -166,7 +167,7 @@ func (plugin *cniNetworkPlugin) Init(host network.Host, hairpinMode kubeletconfi
}
func (plugin *cniNetworkPlugin) syncNetworkConfig() {
network, err := getDefaultCNINetwork(plugin.pluginDir, plugin.binDir, plugin.vendorCNIDirPrefix)
network, err := getDefaultCNINetwork(plugin.confDir, plugin.binDirs)
if err != nil {
glog.Warningf("Unable to update cni config: %s", err)
return
@ -198,7 +199,7 @@ func (plugin *cniNetworkPlugin) Name() string {
}
func (plugin *cniNetworkPlugin) Status() error {
// sync network config from pluginDir periodically to detect network config updates
// sync network config from confDir periodically to detect network config updates
plugin.syncNetworkConfig()
// Can't set up pods if we don't have any CNI network configs yet

View File

@ -26,7 +26,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/network"
)
func getLoNetwork(binDir, vendorDirPrefix string) *cniNetwork {
func getLoNetwork(binDirs []string) *cniNetwork {
loConfig, err := libcni.ConfListFromBytes([]byte(`{
"cniVersion": "0.2.0",
"name": "cni-loopback",
@ -39,13 +39,10 @@ func getLoNetwork(binDir, vendorDirPrefix string) *cniNetwork {
// catch this
panic(err)
}
cninet := &libcni.CNIConfig{
Path: []string{vendorCNIDir(vendorDirPrefix, "loopback"), binDir},
}
loNetwork := &cniNetwork{
name: "lo",
NetworkConfig: loConfig,
CNIConfig: cninet,
CNIConfig: &libcni.CNIConfig{Path: binDirs},
}
return loNetwork

View File

@ -47,31 +47,28 @@ import (
fakeexec "k8s.io/utils/exec/testing"
)
func installPluginUnderTest(t *testing.T, testVendorCNIDirPrefix, testNetworkConfigPath, vendorName string, plugName string) {
pluginDir := path.Join(testNetworkConfigPath, plugName)
err := os.MkdirAll(pluginDir, 0777)
if err != nil {
t.Fatalf("Failed to create plugin config dir: %v", err)
// Returns .in file path, .out file path, and .env file path
func installPluginUnderTest(t *testing.T, testBinDir, testConfDir, testDataDir, binName string, confName string) (string, string, string) {
for _, dir := range []string{testBinDir, testConfDir, testDataDir} {
err := os.MkdirAll(dir, 0777)
if err != nil {
t.Fatalf("Failed to create test plugin dir %s: %v", dir, err)
}
}
pluginConfig := path.Join(pluginDir, plugName+".conf")
f, err := os.Create(pluginConfig)
if err != nil {
t.Fatalf("Failed to install plugin")
}
networkConfig := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true} }`, plugName, vendorName)
confFile := path.Join(testConfDir, confName+".conf")
f, err := os.Create(confFile)
if err != nil {
t.Fatalf("Failed to install plugin %s: %v", confFile, err)
}
networkConfig := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true} }`, confName, binName)
_, err = f.WriteString(networkConfig)
if err != nil {
t.Fatalf("Failed to write network config file (%v)", err)
}
f.Close()
vendorCNIDir := fmt.Sprintf(VendorCNIDirTemplate, testVendorCNIDirPrefix, vendorName)
err = os.MkdirAll(vendorCNIDir, 0777)
if err != nil {
t.Fatalf("Failed to create plugin dir: %v", err)
}
pluginExec := path.Join(vendorCNIDir, vendorName)
pluginExec := path.Join(testBinDir, binName)
f, err = os.Create(pluginExec)
const execScriptTempl = `#!/bin/bash
@ -83,11 +80,14 @@ mkdir -p {{.OutputDir}} &> /dev/null
echo -n "$CNI_COMMAND $CNI_NETNS $K8S_POD_NAMESPACE $K8S_POD_NAME $K8S_POD_INFRA_CONTAINER_ID" >& {{.OutputFile}}
echo -n "{ \"ip4\": { \"ip\": \"10.1.0.23/24\" } }"
`
inputFile := path.Join(testDataDir, binName+".in")
outputFile := path.Join(testDataDir, binName+".out")
envFile := path.Join(testDataDir, binName+".env")
execTemplateData := &map[string]interface{}{
"InputFile": path.Join(pluginDir, plugName+".in"),
"OutputFile": path.Join(pluginDir, plugName+".out"),
"OutputEnv": path.Join(pluginDir, plugName+".env"),
"OutputDir": pluginDir,
"InputFile": inputFile,
"OutputFile": outputFile,
"OutputEnv": envFile,
"OutputDir": testDataDir,
}
tObj := template.Must(template.New("test").Parse(execScriptTempl))
@ -107,6 +107,8 @@ echo -n "{ \"ip4\": { \"ip\": \"10.1.0.23/24\" } }"
}
f.Close()
return inputFile, outputFile, envFile
}
func tearDownPlugin(tmpDir string) {
@ -155,8 +157,8 @@ func (fnh *fakeNetworkHost) SupportsLegacyFeatures() bool {
func TestCNIPlugin(t *testing.T) {
// install some random plugin
pluginName := fmt.Sprintf("test%d", rand.Intn(1000))
vendorName := fmt.Sprintf("test_vendor%d", rand.Intn(1000))
netName := fmt.Sprintf("test%d", rand.Intn(1000))
binName := fmt.Sprintf("test_vendor%d", rand.Intn(1000))
podIP := "10.0.0.2"
podIPOutput := fmt.Sprintf("4: eth0 inet %s/24 scope global dynamic eth0\\ valid_lft forever preferred_lft forever", podIP)
@ -183,10 +185,11 @@ func TestCNIPlugin(t *testing.T) {
// TODO mock for the test plugin too
tmpDir := utiltesting.MkTmpdirOrDie("cni-test")
testNetworkConfigPath := path.Join(tmpDir, "plugins", "net", "cni")
testVendorCNIDirPrefix := tmpDir
testConfDir := path.Join(tmpDir, "etc", "cni", "net.d")
testBinDir := path.Join(tmpDir, "opt", "cni", "bin")
testDataDir := path.Join(tmpDir, "output")
defer tearDownPlugin(tmpDir)
installPluginUnderTest(t, testVendorCNIDirPrefix, testNetworkConfigPath, vendorName, pluginName)
inputFile, outputFile, outputEnv := installPluginUnderTest(t, testBinDir, testConfDir, testDataDir, binName, netName)
containerID := kubecontainer.ContainerID{Type: "test", ID: "test_infra_container"}
pods := []*containertest.FakePod{{
@ -198,7 +201,7 @@ func TestCNIPlugin(t *testing.T) {
NetnsPath: "/proc/12345/ns/net",
}}
plugins := probeNetworkPluginsWithVendorCNIDirPrefix(path.Join(testNetworkConfigPath, pluginName), "", testVendorCNIDirPrefix)
plugins := ProbeNetworkPlugins(testConfDir, []string{testBinDir})
if len(plugins) != 1 {
t.Fatalf("Expected only one network plugin, got %d", len(plugins))
}
@ -238,9 +241,7 @@ func TestCNIPlugin(t *testing.T) {
if err != nil {
t.Errorf("Expected nil: %v", err)
}
outputEnv := path.Join(testNetworkConfigPath, pluginName, pluginName+".env")
eo, eerr := ioutil.ReadFile(outputEnv)
outputFile := path.Join(testNetworkConfigPath, pluginName, pluginName+".out")
output, err := ioutil.ReadFile(outputFile)
if err != nil || eerr != nil {
t.Errorf("Failed to read output file %s: %v (env %s err %v)", outputFile, err, eo, eerr)
@ -257,7 +258,6 @@ func TestCNIPlugin(t *testing.T) {
PortMappings []map[string]interface{} `json:"portMappings"`
} `json:"runtimeConfig"`
}{}
inputFile := path.Join(testNetworkConfigPath, pluginName, pluginName+".in")
inputBytes, inerr := ioutil.ReadFile(inputFile)
parseerr := json.Unmarshal(inputBytes, &inputConfig)
if inerr != nil || parseerr != nil {
@ -285,7 +285,7 @@ func TestCNIPlugin(t *testing.T) {
if err != nil {
t.Errorf("Expected nil: %v", err)
}
output, err = ioutil.ReadFile(path.Join(testNetworkConfigPath, pluginName, pluginName+".out"))
output, err = ioutil.ReadFile(outputFile)
expectedOutput = "DEL /proc/12345/ns/net podNamespace podName test_infra_container"
if string(output) != expectedOutput {
t.Errorf("Mismatch in expected output for setup hook. Expected '%s', got '%s'", expectedOutput, string(output))
@ -295,7 +295,7 @@ func TestCNIPlugin(t *testing.T) {
}
func TestLoNetNonNil(t *testing.T) {
if conf := getLoNetwork("", ""); conf == nil {
if conf := getLoNetwork(nil); conf == nil {
t.Error("Expected non-nil lo network")
}
}

View File

@ -27,7 +27,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/network"
)
func getLoNetwork(binDir, vendorDirPrefix string) *cniNetwork {
func getLoNetwork(binDirs []string) *cniNetwork {
return nil
}

View File

@ -66,7 +66,7 @@ const (
defaultIPAMDir = "/var/lib/cni/networks"
)
// CNI plugins required by kubenet in /opt/cni/bin or vendor directory
// CNI plugins required by kubenet in /opt/cni/bin or user-specified directory
var requiredCNIPlugins = [...]string{"bridge", "host-local", "loopback"}
type kubenetNetworkPlugin struct {
@ -91,15 +91,15 @@ type kubenetNetworkPlugin struct {
iptables utiliptables.Interface
sysctl utilsysctl.Interface
ebtables utilebtables.Interface
// vendorDir is passed by kubelet cni-bin-dir parameter.
// kubenet will search for cni binaries in DefaultCNIDir first, then continue to vendorDir.
vendorDir string
// binDirs is passed by kubelet cni-bin-dir parameter.
// kubenet will search for CNI binaries in DefaultCNIDir first, then continue to binDirs.
binDirs []string
nonMasqueradeCIDR string
podCidr string
gateway net.IP
}
func NewPlugin(networkPluginDir string) network.NetworkPlugin {
func NewPlugin(networkPluginDirs []string) network.NetworkPlugin {
protocol := utiliptables.ProtocolIpv4
execer := utilexec.New()
dbus := utildbus.New()
@ -110,7 +110,7 @@ func NewPlugin(networkPluginDir string) network.NetworkPlugin {
execer: utilexec.New(),
iptables: iptInterface,
sysctl: sysctl,
vendorDir: networkPluginDir,
binDirs: append([]string{DefaultCNIDir}, networkPluginDirs...),
hostportSyncer: hostport.NewHostportSyncer(iptInterface),
hostportManager: hostport.NewHostportManager(iptInterface),
nonMasqueradeCIDR: "10.0.0.0/8",
@ -121,9 +121,7 @@ func (plugin *kubenetNetworkPlugin) Init(host network.Host, hairpinMode kubeletc
plugin.host = host
plugin.hairpinMode = hairpinMode
plugin.nonMasqueradeCIDR = nonMasqueradeCIDR
plugin.cniConfig = &libcni.CNIConfig{
Path: []string{DefaultCNIDir, plugin.vendorDir},
}
plugin.cniConfig = &libcni.CNIConfig{Path: plugin.binDirs}
if mtu == network.UseDefaultMTU {
if link, err := findMinMTU(); err == nil {
@ -564,22 +562,24 @@ func (plugin *kubenetNetworkPlugin) Status() error {
return fmt.Errorf("Kubenet does not have netConfig. This is most likely due to lack of PodCIDR")
}
if !plugin.checkCNIPlugin() {
return fmt.Errorf("could not locate kubenet required CNI plugins %v at %q or %q", requiredCNIPlugins, DefaultCNIDir, plugin.vendorDir)
if !plugin.checkRequiredCNIPlugins() {
return fmt.Errorf("could not locate kubenet required CNI plugins %v at %q", requiredCNIPlugins, plugin.binDirs)
}
return nil
}
// checkCNIPlugin returns if all kubenet required cni plugins can be found at /opt/cni/bin or user specified NetworkPluginDir.
func (plugin *kubenetNetworkPlugin) checkCNIPlugin() bool {
if plugin.checkCNIPluginInDir(DefaultCNIDir) || plugin.checkCNIPluginInDir(plugin.vendorDir) {
return true
// checkRequiredCNIPlugins returns if all kubenet required cni plugins can be found at /opt/cni/bin or user specified NetworkPluginDir.
func (plugin *kubenetNetworkPlugin) checkRequiredCNIPlugins() bool {
for _, dir := range plugin.binDirs {
if plugin.checkRequiredCNIPluginsInOneDir(dir) {
return true
}
}
return false
}
// checkCNIPluginInDir returns if all required cni plugins are placed in dir
func (plugin *kubenetNetworkPlugin) checkCNIPluginInDir(dir string) bool {
// checkRequiredCNIPluginsInOneDir returns true if all required cni plugins are placed in dir
func (plugin *kubenetNetworkPlugin) checkRequiredCNIPluginsInOneDir(dir string) bool {
files, err := ioutil.ReadDir(dir)
if err != nil {
return false

View File

@ -30,7 +30,7 @@ type kubenetNetworkPlugin struct {
network.NoopNetworkPlugin
}
func NewPlugin(networkPluginDir string) network.NetworkPlugin {
func NewPlugin(networkPluginDirs []string) network.NetworkPlugin {
return &kubenetNetworkPlugin{}
}

View File

@ -1215,6 +1215,7 @@ func TestGenerateRunCommand(t *testing.T) {
hostName := "test-hostname"
boolTrue := true
boolFalse := false
pluginDirs := []string{"/tmp"}
tests := []struct {
networkPlugin network.NetworkPlugin
@ -1231,7 +1232,7 @@ func TestGenerateRunCommand(t *testing.T) {
}{
// Case #0, returns error.
{
kubenet.NewPlugin("/tmp"),
kubenet.NewPlugin(pluginDirs),
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-name-foo",
@ -1250,7 +1251,7 @@ func TestGenerateRunCommand(t *testing.T) {
},
// Case #1, returns no dns, with private-net.
{
kubenet.NewPlugin("/tmp"),
kubenet.NewPlugin(pluginDirs),
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-name-foo",
@ -1269,7 +1270,7 @@ func TestGenerateRunCommand(t *testing.T) {
},
// Case #2, returns no dns, with host-net.
{
kubenet.NewPlugin("/tmp"),
kubenet.NewPlugin(pluginDirs),
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-name-foo",
@ -1290,7 +1291,7 @@ func TestGenerateRunCommand(t *testing.T) {
},
// Case #3, returns dns, dns searches, with private-net.
{
kubenet.NewPlugin("/tmp"),
kubenet.NewPlugin(pluginDirs),
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-name-foo",
@ -1311,7 +1312,7 @@ func TestGenerateRunCommand(t *testing.T) {
},
// Case #4, returns no dns, dns searches, with host-network.
{
kubenet.NewPlugin("/tmp"),
kubenet.NewPlugin(pluginDirs),
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-name-foo",
@ -1351,7 +1352,7 @@ func TestGenerateRunCommand(t *testing.T) {
},
// Case #6, if all containers are privileged, the result should have 'insecure-options=all-run'
{
kubenet.NewPlugin("/tmp"),
kubenet.NewPlugin(pluginDirs),
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-name-foo",
@ -1373,7 +1374,7 @@ func TestGenerateRunCommand(t *testing.T) {
},
// Case #7, if not all containers are privileged, the result should not have 'insecure-options=all-run'
{
kubenet.NewPlugin("/tmp"),
kubenet.NewPlugin(pluginDirs),
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod-name-foo",