diff --git a/doc/configuration.md b/doc/configuration.md index 5028f1871..947665d2a 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -21,6 +21,8 @@ Following is the example of multus config file, in `/etc/cni/net.d/`. "Note1":"NOTE: you can set clusterNetwork+defaultNetworks OR delegates!!", "clusterNetwork": "defaultCRD", "defaultNetworks": ["sidecarCRD", "flannel"], + "systemNamespaces": ["kube-system", "admin"], + "multusNamespace": "kube-system", "Note2":"NOTE: If you use clusterNetwork/defaultNetworks, delegates is ignored", "delegates": [{ "type": "weave-net", @@ -48,6 +50,8 @@ User should chose following parameters combination (`clusterNetwork`+`defaultNet * `clusterNetwork` (string, required): default CNI network for pods, used in kubernetes cluster (Pod IP and so on): name of network-attachment-definition, CNI json file name (without extention, .conf/.conflist) or directory for CNI config file * `defaultNetworks` ([]string, required): default CNI network attachment: name of network-attachment-definition, CNI json file name (without extention, .conf/.conflist) or directory for CNI config file +* `systemNamespaces` ([]string, optional): list of namespaces for Kubernetes system (namespaces listed here will not have `defaultNetworks` added) +* `multusNamespace` (string, optional): namespace for `clusterNetwork`/`defaultNetworks` * `delegates` ([]map,required): number of delegate details in the Multus ### Network selection flow of clusterNetwork/defaultNetworks diff --git a/k8sclient/k8sclient.go b/k8sclient/k8sclient.go index 37464c528..446e41f0b 100644 --- a/k8sclient/k8sclient.go +++ b/k8sclient/k8sclient.go @@ -539,17 +539,17 @@ func GetPodNetwork(k8sclient KubeClient, k8sArgs *types.K8sArgs, confdir string, return delegates, nil } -func getDefaultNetDelegateCRD(client KubeClient, net string, confdir string) (*types.DelegateNetConf, error) { +func getDefaultNetDelegateCRD(client KubeClient, net, confdir, namespace string) (*types.DelegateNetConf, error) { logging.Debugf("getDefaultNetDelegate: %v, %v, %s", client, net, confdir) - rawPath := fmt.Sprintf("/apis/k8s.cni.cncf.io/v1/namespaces/%s/network-attachment-definitions/%s", "kube-system", net) + rawPath := fmt.Sprintf("/apis/k8s.cni.cncf.io/v1/namespaces/%s/network-attachment-definitions/%s", namespace, net) netData, err := client.GetRawWithPath(rawPath) if err != nil { - return nil, logging.Errorf("getDefaultNetDelegate: failed to get network resource, refer Multus README.md for the usage guide: %v", err) + return nil, logging.Errorf("getDefaultNetDelegateCRD: failed to get network resource, refer Multus README.md for the usage guide: %v", err) } customResource := &types.NetworkAttachmentDefinition{} if err := json.Unmarshal(netData, customResource); err != nil { - return nil, logging.Errorf("getDefaultNetDelegate: failed to get the netplugin data: %v", err) + return nil, logging.Errorf("getDefaultNetDelegateCRD: failed to get the netplugin data: %v", err) } configBytes, err := cniConfigFromNetworkResource(customResource, confdir) @@ -565,10 +565,10 @@ func getDefaultNetDelegateCRD(client KubeClient, net string, confdir string) (*t return delegate, nil } -func getNetDelegate(client KubeClient, netname string, confdir string) (*types.DelegateNetConf, error) { +func getNetDelegate(client KubeClient, netname, confdir, namespace string) (*types.DelegateNetConf, error) { logging.Debugf("getNetDelegate: %v, %v, %v", client, netname, confdir) // option1) search CRD object for the network - delegate, err := getDefaultNetDelegateCRD(client, netname, confdir) + delegate, err := getDefaultNetDelegateCRD(client, netname, confdir, namespace) if err == nil { return delegate, nil } @@ -626,7 +626,7 @@ func GetDefaultNetworks(k8sArgs *types.K8sArgs, conf *types.NetConf, kubeClient return nil } - delegate, err := getNetDelegate(kubeClient, conf.ClusterNetwork, conf.ConfDir) + delegate, err := getNetDelegate(kubeClient, conf.ClusterNetwork, conf.ConfDir, conf.MultusNamespace) if err != nil { return err } @@ -634,9 +634,9 @@ func GetDefaultNetworks(k8sArgs *types.K8sArgs, conf *types.NetConf, kubeClient delegates = append(delegates, delegate) // Pod in kube-system namespace does not have default network for now. - if string(k8sArgs.K8S_POD_NAMESPACE) != "kube-system" { + if !types.CheckSystemNamespaces(string(k8sArgs.K8S_POD_NAMESPACE), conf.SystemNamespaces) { for _, netname := range conf.DefaultNetworks { - delegate, err := getNetDelegate(kubeClient, netname, conf.ConfDir) + delegate, err := getNetDelegate(kubeClient, netname, conf.ConfDir, conf.MultusNamespace) if err != nil { return err } diff --git a/multus/multus.go b/multus/multus.go index 643ceb482..8ad9877a5 100644 --- a/multus/multus.go +++ b/multus/multus.go @@ -349,7 +349,7 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) (cn //create the network status, only in case Multus as kubeconfig if n.Kubeconfig != "" && kc != nil { - if kc.Podnamespace != "kube-system" { + if !types.CheckSystemNamespaces(kc.Podnamespace, n.SystemNamespaces) { delegateNetStatus, err := types.LoadNetworkStatus(tmpResult, delegate.Conf.Name, delegate.MasterPlugin) if err != nil { return nil, logging.Errorf("Multus: Err in setting network status: %v", err) @@ -362,7 +362,7 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) (cn //set the network status annotation in apiserver, only in case Multus as kubeconfig if n.Kubeconfig != "" && kc != nil { - if kc.Podnamespace != "kube-system" { + if !types.CheckSystemNamespaces(kc.Podnamespace, n.SystemNamespaces) { err = k8s.SetNetworkStatus(kc, netStatus) if err != nil { return nil, logging.Errorf("Multus: Err set the networks status: %v", err) @@ -436,7 +436,7 @@ func cmdDel(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) err //unset the network status annotation in apiserver, only in case Multus as kubeconfig if in.Kubeconfig != "" && kc != nil { - if kc.Podnamespace != "kube-system" { + if !types.CheckSystemNamespaces(kc.Podnamespace, in.SystemNamespaces) { err := k8s.SetNetworkStatus(kc, nil) if err != nil { return logging.Errorf("Multus: Err unset the networks status: %v", err) diff --git a/types/conf.go b/types/conf.go index fa986d41f..b8389be1a 100644 --- a/types/conf.go +++ b/types/conf.go @@ -31,6 +31,7 @@ const ( defaultConfDir = "/etc/cni/multus/net.d" defaultBinDir = "/opt/cni/bin" defaultReadinessIndicatorFile = "" + defaultMultusNamespace = "kube-system" ) func LoadDelegateNetConfList(bytes []byte, delegateConf *DelegateNetConf) error { @@ -216,6 +217,14 @@ func LoadNetConf(bytes []byte) (*NetConf, error) { netconf.ReadinessIndicatorFile = defaultReadinessIndicatorFile } + if len(netconf.SystemNamespaces) == 0 { + netconf.SystemNamespaces = []string{"kube-system"} + } + + if netconf.MultusNamespace == "" { + netconf.MultusNamespace = defaultMultusNamespace + } + // get RawDelegates and put delegates field if netconf.ClusterNetwork == "" { // for Delegates @@ -266,3 +275,13 @@ func delegateAddDeviceID(inBytes []byte, deviceID string) ([]byte, error) { } return configBytes, nil } + +// CheckSystemNamespaces checks whether given namespace is in systemNamespaces or not. +func CheckSystemNamespaces(namespace string, systemNamespaces []string) bool { + for _, nsname := range systemNamespaces { + if namespace == nsname { + return true + } + } + return false +} diff --git a/types/conf_test.go b/types/conf_test.go index 47f6c68cb..18cdc657c 100644 --- a/types/conf_test.go +++ b/types/conf_test.go @@ -124,4 +124,11 @@ var _ = Describe("config operations", func() { Expect(netConf.ReadinessIndicatorFile).To(Equal("/etc/cni/net.d/foo")) }) + It("check CheckSystemNamespaces() works fine", func() { + b1 := CheckSystemNamespaces("foobar", []string{"barfoo", "bafoo", "foobar"}) + Expect(b1).To(Equal(true)) + b2 := CheckSystemNamespaces("foobar1", []string{"barfoo", "bafoo", "foobar"}) + Expect(b2).To(Equal(false)) + }) + }) diff --git a/types/types.go b/types/types.go index 0d3d3d6f0..79e89c43c 100644 --- a/types/types.go +++ b/types/types.go @@ -49,6 +49,10 @@ type NetConf struct { ReadinessIndicatorFile string `json:"readinessindicatorfile"` // Option to isolate the usage of CR's to the namespace in which a pod resides. NamespaceIsolation bool `json:"namespaceIsolation"` + // Option to set system namespaces (to avoid to add defaultNetworks) + SystemNamespaces []string `json:"systemNamespaces"` + // Option to set the namespace that multus-cni uses (clusterNetwork/defaultNetworks) + MultusNamespace string `json:"multusNamespace"` } type RuntimeConfig struct {