mirror of
https://github.com/k8snetworkplumbingwg/multus-cni.git
synced 2025-07-01 10:01:49 +00:00
Add portmap capability support
Signed-off-by: Mathieu Rohon <mathieu.rohon@orange.com>
This commit is contained in:
parent
635a275746
commit
a4f5fd4bf0
@ -137,6 +137,7 @@ $ kubectl exec -it samplepod -- ip a
|
|||||||
- type (string, required): "multus"
|
- type (string, required): "multus"
|
||||||
- kubeconfig (string, optional): kubeconfig file for the out of cluster communication with kube-apiserver. See the example [kubeconfig](https://github.com/intel/multus-cni/blob/master/doc/node-kubeconfig.yaml)
|
- kubeconfig (string, optional): kubeconfig file for the out of cluster communication with kube-apiserver. See the example [kubeconfig](https://github.com/intel/multus-cni/blob/master/doc/node-kubeconfig.yaml)
|
||||||
- delegates (([]map,required): number of delegate details in the Multus
|
- delegates (([]map,required): number of delegate details in the Multus
|
||||||
|
- capabilities ({}list, optional): [capabilities](https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md#dynamic-plugin-specific-fields-capabilities--runtime-configuration) supported by at least one of the delegates. (NOTE: Multus only supports portMappings capability for now). See the [example](https://github.com/intel/multus-cni/blob/master/examples/multus-ptp-portmap.conf).
|
||||||
|
|
||||||
## Usage with Kubernetes CRD based network objects
|
## Usage with Kubernetes CRD based network objects
|
||||||
|
|
||||||
|
36
examples/multus-ptp-portmap.conf
Normal file
36
examples/multus-ptp-portmap.conf
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "multus-cni-network",
|
||||||
|
"type": "multus"
|
||||||
|
"capabilities": {
|
||||||
|
"portMappings": true
|
||||||
|
},
|
||||||
|
"delegates": [
|
||||||
|
{
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"name": "ptp-tuning-conflist",
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"dns": {
|
||||||
|
"nameservers": [
|
||||||
|
"172.16.1.1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ipMasq": true,
|
||||||
|
"ipam": {
|
||||||
|
"subnet": "172.16.0.0/24",
|
||||||
|
"type": "host-local"
|
||||||
|
},
|
||||||
|
"mtu": 512,
|
||||||
|
"type": "ptp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"capabilities": {
|
||||||
|
"portMappings": true
|
||||||
|
},
|
||||||
|
"externalSetMarkChain": "KUBE-MARK-MASQ",
|
||||||
|
"type": "portmap"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
@ -111,11 +111,12 @@ func validateIfName(nsname string, ifname string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func conflistAdd(rt *libcni.RuntimeConf, rawnetconflist []byte, binDir string) (cnitypes.Result, error) {
|
func conflistAdd(rt *libcni.RuntimeConf, rawnetconflist []byte, binDir string, exec invoke.Exec) (cnitypes.Result, error) {
|
||||||
logging.Debugf("conflistAdd: %v, %s, %s", rt, string(rawnetconflist), binDir)
|
logging.Debugf("conflistAdd: %v, %s, %s", rt, string(rawnetconflist), binDir)
|
||||||
// In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go
|
// In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go
|
||||||
binDirs := []string{binDir}
|
binDirs := filepath.SplitList(os.Getenv("CNI_PATH"))
|
||||||
cniNet := libcni.CNIConfig{Path: binDirs}
|
binDirs = append(binDirs, binDir)
|
||||||
|
cniNet := libcni.NewCNIConfig(binDirs, exec)
|
||||||
|
|
||||||
confList, err := libcni.ConfListFromBytes(rawnetconflist)
|
confList, err := libcni.ConfListFromBytes(rawnetconflist)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -160,7 +161,7 @@ func delegateAdd(exec invoke.Exec, ifName string, delegate *types.DelegateNetCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
if delegate.ConfListPlugin != false {
|
if delegate.ConfListPlugin != false {
|
||||||
result, err := conflistAdd(rt, delegate.Bytes, binDir)
|
result, err := conflistAdd(rt, delegate.Bytes, binDir, exec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, logging.Errorf("Multus: error in invoke Conflist add - %q: %v", delegate.ConfList.Name, err)
|
return nil, logging.Errorf("Multus: error in invoke Conflist add - %q: %v", delegate.ConfList.Name, err)
|
||||||
}
|
}
|
||||||
@ -246,7 +247,7 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) (cn
|
|||||||
for idx, delegate := range n.Delegates {
|
for idx, delegate := range n.Delegates {
|
||||||
lastIdx = idx
|
lastIdx = idx
|
||||||
ifName := getIfname(delegate, args.IfName, idx)
|
ifName := getIfname(delegate, args.IfName, idx)
|
||||||
rt, _ = types.LoadCNIRuntimeConf(args, k8sArgs, ifName)
|
rt, _ = types.LoadCNIRuntimeConf(args, k8sArgs, ifName, n.RuntimeConfig)
|
||||||
tmpResult, err = delegateAdd(exec, ifName, delegate, rt, n.BinDir)
|
tmpResult, err = delegateAdd(exec, ifName, delegate, rt, n.BinDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
@ -360,7 +361,7 @@ func cmdDel(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) err
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rt, _ := types.LoadCNIRuntimeConf(args, k8sArgs, "")
|
rt, _ := types.LoadCNIRuntimeConf(args, k8sArgs, "", in.RuntimeConfig)
|
||||||
return delPlugins(exec, args.IfName, in.Delegates, len(in.Delegates)-1, rt, in.BinDir)
|
return delPlugins(exec, args.IfName, in.Delegates, len(in.Delegates)-1, rt, in.BinDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,4 +306,49 @@ var _ = Describe("multus operations", func() {
|
|||||||
// plugin 1 is the masterplugin
|
// plugin 1 is the masterplugin
|
||||||
Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue())
|
Expect(reflect.DeepEqual(r, expectedResult1)).To(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("ensure delegates get portmap runtime config", func() {
|
||||||
|
args := &skel.CmdArgs{
|
||||||
|
ContainerID: "123456789",
|
||||||
|
Netns: testNS.Path(),
|
||||||
|
IfName: "eth0",
|
||||||
|
StdinData: []byte(`{
|
||||||
|
"name": "node-cni-network",
|
||||||
|
"type": "multus",
|
||||||
|
"delegates": [{
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"name": "mynet-confList",
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"type": "firstPlugin",
|
||||||
|
"capabilities": {"portMappings": true}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
"runtimeConfig": {
|
||||||
|
"portMappings": [
|
||||||
|
{"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}`),
|
||||||
|
}
|
||||||
|
|
||||||
|
fExec := &fakeExec{}
|
||||||
|
expectedConf1 := `{
|
||||||
|
"capabilities": {"portMappings": true},
|
||||||
|
"name": "mynet-confList",
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"type": "firstPlugin",
|
||||||
|
"runtimeConfig": {
|
||||||
|
"portMappings": [
|
||||||
|
{"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
fExec.addPlugin(nil, "eth0", expectedConf1, nil, nil)
|
||||||
|
os.Setenv("CNI_COMMAND", "ADD")
|
||||||
|
os.Setenv("CNI_IFNAME", "eth0")
|
||||||
|
_, err := cmdAdd(args, fExec, nil)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -73,9 +73,9 @@ func LoadDelegateNetConf(bytes []byte, ifnameRequest string) (*DelegateNetConf,
|
|||||||
return delegateConf, nil
|
return delegateConf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string) (*libcni.RuntimeConf, error) {
|
func LoadCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string, rc *RuntimeConfig) (*libcni.RuntimeConf, error) {
|
||||||
|
|
||||||
logging.Debugf("LoadCNIRuntimeConf: %v, %v, %s", args, k8sArgs, ifName)
|
logging.Debugf("LoadCNIRuntimeConf: %v, %v, %s, %v", args, k8sArgs, ifName, rc)
|
||||||
// In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go#buildCNIRuntimeConf
|
// In part, adapted from K8s pkg/kubelet/dockershim/network/cni/cni.go#buildCNIRuntimeConf
|
||||||
// Todo
|
// Todo
|
||||||
// ingress, egress and bandwidth capability features as same as kubelet.
|
// ingress, egress and bandwidth capability features as same as kubelet.
|
||||||
@ -90,6 +90,12 @@ func LoadCNIRuntimeConf(args *skel.CmdArgs, k8sArgs *K8sArgs, ifName string) (*l
|
|||||||
{"K8S_POD_INFRA_CONTAINER_ID", string(k8sArgs.K8S_POD_INFRA_CONTAINER_ID)},
|
{"K8S_POD_INFRA_CONTAINER_ID", string(k8sArgs.K8S_POD_INFRA_CONTAINER_ID)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rc != nil {
|
||||||
|
rt.CapabilityArgs = map[string]interface{}{
|
||||||
|
"portMappings": rc.PortMaps,
|
||||||
|
}
|
||||||
|
}
|
||||||
return rt, nil
|
return rt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,13 +35,20 @@ var _ = Describe("config operations", func() {
|
|||||||
"kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml",
|
"kubeconfig": "/etc/kubernetes/node-kubeconfig.yaml",
|
||||||
"delegates": [{
|
"delegates": [{
|
||||||
"type": "weave-net"
|
"type": "weave-net"
|
||||||
}]
|
}],
|
||||||
|
"runtimeConfig": {
|
||||||
|
"portMappings": [
|
||||||
|
{"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
}`
|
}`
|
||||||
netConf, err := LoadNetConf([]byte(conf))
|
netConf, err := LoadNetConf([]byte(conf))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(len(netConf.Delegates)).To(Equal(1))
|
Expect(len(netConf.Delegates)).To(Equal(1))
|
||||||
Expect(netConf.Delegates[0].Conf.Type).To(Equal("weave-net"))
|
Expect(netConf.Delegates[0].Conf.Type).To(Equal("weave-net"))
|
||||||
Expect(netConf.Delegates[0].MasterPlugin).To(BeTrue())
|
Expect(netConf.Delegates[0].MasterPlugin).To(BeTrue())
|
||||||
|
Expect(len(netConf.RuntimeConfig.PortMaps)).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("succeeds if only delegates are set", func() {
|
It("succeeds if only delegates are set", func() {
|
||||||
|
@ -36,12 +36,24 @@ type NetConf struct {
|
|||||||
CNIDir string `json:"cniDir"`
|
CNIDir string `json:"cniDir"`
|
||||||
BinDir string `json:"binDir"`
|
BinDir string `json:"binDir"`
|
||||||
// RawDelegates is private to the NetConf class; use Delegates instead
|
// RawDelegates is private to the NetConf class; use Delegates instead
|
||||||
RawDelegates []map[string]interface{} `json:"delegates"`
|
RawDelegates []map[string]interface{} `json:"delegates"`
|
||||||
Delegates []*DelegateNetConf `json:"-"`
|
Delegates []*DelegateNetConf `json:"-"`
|
||||||
NetStatus []*NetworkStatus `json:"-"`
|
NetStatus []*NetworkStatus `json:"-"`
|
||||||
Kubeconfig string `json:"kubeconfig"`
|
Kubeconfig string `json:"kubeconfig"`
|
||||||
LogFile string `json:"logFile"`
|
LogFile string `json:"logFile"`
|
||||||
LogLevel string `json:"logLevel"`
|
LogLevel string `json:"logLevel"`
|
||||||
|
RuntimeConfig *RuntimeConfig `json:"runtimeConfig,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RuntimeConfig struct {
|
||||||
|
PortMaps []PortMapEntry `json:"portMappings,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PortMapEntry struct {
|
||||||
|
HostPort int `json:"hostPort"`
|
||||||
|
ContainerPort int `json:"containerPort"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
HostIP string `json:"hostIP,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetworkStatus struct {
|
type NetworkStatus struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user