add portmapping getter into network host
This commit is contained in:
		| @@ -25,6 +25,7 @@ import ( | |||||||
| 	dockertypes "github.com/docker/engine-api/types" | 	dockertypes "github.com/docker/engine-api/types" | ||||||
| 	"github.com/golang/glog" | 	"github.com/golang/glog" | ||||||
|  |  | ||||||
|  | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/apis/componentconfig" | 	"k8s.io/kubernetes/pkg/apis/componentconfig" | ||||||
| 	internalapi "k8s.io/kubernetes/pkg/kubelet/api" | 	internalapi "k8s.io/kubernetes/pkg/kubelet/api" | ||||||
| 	runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | 	runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" | ||||||
| @@ -34,6 +35,7 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/kubelet/dockertools" | 	"k8s.io/kubernetes/pkg/kubelet/dockertools" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/network" | 	"k8s.io/kubernetes/pkg/kubelet/network" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/network/cni" | 	"k8s.io/kubernetes/pkg/kubelet/network/cni" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubelet/network/hostport" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/network/kubenet" | 	"k8s.io/kubernetes/pkg/kubelet/network/kubenet" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/server/streaming" | 	"k8s.io/kubernetes/pkg/kubelet/server/streaming" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/util/cache" | 	"k8s.io/kubernetes/pkg/kubelet/util/cache" | ||||||
| @@ -107,6 +109,35 @@ type NetworkPluginSettings struct { | |||||||
| 	LegacyRuntimeHost network.LegacyHost | 	LegacyRuntimeHost network.LegacyHost | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // namespaceGetter is a wrapper around the dockerService that implements | ||||||
|  | // the network.NamespaceGetter interface. | ||||||
|  | type namespaceGetter struct { | ||||||
|  | 	ds *dockerService | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (n *namespaceGetter) GetNetNS(containerID string) (string, error) { | ||||||
|  | 	return n.ds.GetNetNS(containerID) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // portMappingGetter is a wrapper around the dockerService that implements | ||||||
|  | // the network.PortMappingGetter interface. | ||||||
|  | type portMappingGetter struct { | ||||||
|  | 	ds *dockerService | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *portMappingGetter) GetPodPortMappings(containerID string) ([]*hostport.PortMapping, error) { | ||||||
|  | 	return p.ds.GetPodPortMappings(containerID) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // dockerNetworkHost implements network.Host by wrapping the legacy host passed in by the kubelet | ||||||
|  | // and dockerServices which implementes the rest of the network host interfaces. | ||||||
|  | // The legacy host methods are slated for deletion. | ||||||
|  | type dockerNetworkHost struct { | ||||||
|  | 	network.LegacyHost | ||||||
|  | 	*namespaceGetter | ||||||
|  | 	*portMappingGetter | ||||||
|  | } | ||||||
|  |  | ||||||
| var internalLabelKeys []string = []string{containerTypeLabelKey, containerLogPathLabelKey, sandboxIDLabelKey} | var internalLabelKeys []string = []string{containerTypeLabelKey, containerLogPathLabelKey, sandboxIDLabelKey} | ||||||
|  |  | ||||||
| // NOTE: Anything passed to DockerService should be eventually handled in another way when we switch to running the shim as a different process. | // NOTE: Anything passed to DockerService should be eventually handled in another way when we switch to running the shim as a different process. | ||||||
| @@ -138,6 +169,7 @@ func NewDockerService(client dockertools.DockerInterface, seccompProfileRoot str | |||||||
| 	netHost := &dockerNetworkHost{ | 	netHost := &dockerNetworkHost{ | ||||||
| 		pluginSettings.LegacyRuntimeHost, | 		pluginSettings.LegacyRuntimeHost, | ||||||
| 		&namespaceGetter{ds}, | 		&namespaceGetter{ds}, | ||||||
|  | 		&portMappingGetter{ds}, | ||||||
| 	} | 	} | ||||||
| 	plug, err := network.InitNetworkPlugin(cniPlugins, pluginSettings.PluginName, netHost, pluginSettings.HairpinMode, pluginSettings.NonMasqueradeCIDR, pluginSettings.MTU) | 	plug, err := network.InitNetworkPlugin(cniPlugins, pluginSettings.PluginName, netHost, pluginSettings.HairpinMode, pluginSettings.NonMasqueradeCIDR, pluginSettings.MTU) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -240,12 +272,6 @@ func (ds *dockerService) UpdateRuntimeConfig(runtimeConfig *runtimeapi.RuntimeCo | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| // namespaceGetter is a wrapper around the dockerService that implements |  | ||||||
| // the network.NamespaceGetter interface. |  | ||||||
| type namespaceGetter struct { |  | ||||||
| 	*dockerService |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetNetNS returns the network namespace of the given containerID. The ID | // GetNetNS returns the network namespace of the given containerID. The ID | ||||||
| // supplied is typically the ID of a pod sandbox. This getter doesn't try | // supplied is typically the ID of a pod sandbox. This getter doesn't try | ||||||
| // to map non-sandbox IDs to their respective sandboxes. | // to map non-sandbox IDs to their respective sandboxes. | ||||||
| @@ -257,12 +283,24 @@ func (ds *dockerService) GetNetNS(podSandboxID string) (string, error) { | |||||||
| 	return getNetworkNamespace(r), nil | 	return getNetworkNamespace(r), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // dockerNetworkHost implements network.Host by wrapping the legacy host | // GetPodPortMappings returns the port mappings of the given podSandbox ID. | ||||||
| // passed in by the kubelet and adding NamespaceGetter methods. The legacy | func (ds *dockerService) GetPodPortMappings(podSandboxID string) ([]*hostport.PortMapping, error) { | ||||||
| // host methods are slated for deletion. | 	// TODO: get portmappings from docker labels for backward compatibility | ||||||
| type dockerNetworkHost struct { | 	checkpoint, err := ds.checkpointHandler.GetCheckpoint(podSandboxID) | ||||||
| 	network.LegacyHost | 	if err != nil { | ||||||
| 	*namespaceGetter | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	portMappings := []*hostport.PortMapping{} | ||||||
|  | 	for _, pm := range checkpoint.Data.PortMappings { | ||||||
|  | 		proto := toAPIProtocol(*pm.Protocol) | ||||||
|  | 		portMappings = append(portMappings, &hostport.PortMapping{ | ||||||
|  | 			HostPort:      *pm.HostPort, | ||||||
|  | 			ContainerPort: *pm.ContainerPort, | ||||||
|  | 			Protocol:      proto, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 	return portMappings, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Start initializes and starts components in dockerService. | // Start initializes and starts components in dockerService. | ||||||
| @@ -351,3 +389,14 @@ func (ds *dockerService) getDockerVersionFromCache() (*dockertypes.Version, erro | |||||||
| 	} | 	} | ||||||
| 	return dv, nil | 	return dv, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func toAPIProtocol(protocol Protocol) v1.Protocol { | ||||||
|  | 	switch protocol { | ||||||
|  | 	case protocolTCP: | ||||||
|  | 		return v1.ProtocolTCP | ||||||
|  | 	case protocolUDP: | ||||||
|  | 		return v1.ProtocolUDP | ||||||
|  | 	} | ||||||
|  | 	glog.Warningf("Unknown protocol %q: defaulting to TCP", protocol) | ||||||
|  | 	return v1.ProtocolTCP | ||||||
|  | } | ||||||
|   | |||||||
| @@ -484,7 +484,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub | |||||||
| 	} | 	} | ||||||
| 	glog.Infof("Hairpin mode set to %q", klet.hairpinMode) | 	glog.Infof("Hairpin mode set to %q", klet.hairpinMode) | ||||||
|  |  | ||||||
| 	if plug, err := network.InitNetworkPlugin(kubeDeps.NetworkPlugins, kubeCfg.NetworkPluginName, &criNetworkHost{&networkHost{klet}}, klet.hairpinMode, klet.nonMasqueradeCIDR, int(kubeCfg.NetworkPluginMTU)); err != nil { | 	if plug, err := network.InitNetworkPlugin(kubeDeps.NetworkPlugins, kubeCfg.NetworkPluginName, &criNetworkHost{&networkHost{klet}, &network.NoopPortMappingGetter{}}, klet.hairpinMode, klet.nonMasqueradeCIDR, int(kubeCfg.NetworkPluginMTU)); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else { | 	} else { | ||||||
| 		klet.networkPlugin = plug | 		klet.networkPlugin = plug | ||||||
|   | |||||||
| @@ -39,6 +39,7 @@ import ( | |||||||
| 	containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" | 	containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/network" | 	"k8s.io/kubernetes/pkg/kubelet/network" | ||||||
| 	"k8s.io/kubernetes/pkg/kubelet/network/cni/testing" | 	"k8s.io/kubernetes/pkg/kubelet/network/cni/testing" | ||||||
|  | 	networktest "k8s.io/kubernetes/pkg/kubelet/network/testing" | ||||||
| 	utilexec "k8s.io/kubernetes/pkg/util/exec" | 	utilexec "k8s.io/kubernetes/pkg/util/exec" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -111,6 +112,7 @@ func tearDownPlugin(tmpDir string) { | |||||||
| } | } | ||||||
|  |  | ||||||
| type fakeNetworkHost struct { | type fakeNetworkHost struct { | ||||||
|  | 	networktest.FakePortMappingGetter | ||||||
| 	kubeClient clientset.Interface | 	kubeClient clientset.Interface | ||||||
| 	runtime    kubecontainer.Runtime | 	runtime    kubecontainer.Runtime | ||||||
| } | } | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/apis/componentconfig" | 	"k8s.io/kubernetes/pkg/apis/componentconfig" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" | 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubelet/network/hostport" | ||||||
| 	utilexec "k8s.io/kubernetes/pkg/util/exec" | 	utilexec "k8s.io/kubernetes/pkg/util/exec" | ||||||
| 	utilsysctl "k8s.io/kubernetes/pkg/util/sysctl" | 	utilsysctl "k8s.io/kubernetes/pkg/util/sysctl" | ||||||
| ) | ) | ||||||
| @@ -111,9 +112,9 @@ type LegacyHost interface { | |||||||
| 	// Only used for hostport management | 	// Only used for hostport management | ||||||
| 	GetRuntime() kubecontainer.Runtime | 	GetRuntime() kubecontainer.Runtime | ||||||
|  |  | ||||||
| 	// SupportsLegacyFeaturs returns true if this host can support hostports | 	// SupportsLegacyFeatures returns true if the network host support GetPodByName, KubeClient interface and kubelet | ||||||
| 	// and bandwidth shaping. Both will either get added to CNI or dropped, | 	// runtime interface. These interfaces will no longer be implemented by CRI shims. | ||||||
| 	// so differnt implementations can choose to ignore them. | 	// This function helps network plugins to choose their behavior based on runtime. | ||||||
| 	SupportsLegacyFeatures() bool | 	SupportsLegacyFeatures() bool | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -121,17 +122,19 @@ type LegacyHost interface { | |||||||
| // TODO(#35457): get rid of this backchannel to the kubelet. The scope of | // TODO(#35457): get rid of this backchannel to the kubelet. The scope of | ||||||
| // the back channel is restricted to host-ports/testing, and restricted | // the back channel is restricted to host-ports/testing, and restricted | ||||||
| // to kubenet. No other network plugin wrapper needs it. Other plugins | // to kubenet. No other network plugin wrapper needs it. Other plugins | ||||||
| // only require a way to access namespace information, which they can do | // only require a way to access namespace information and port mapping | ||||||
| // directly through the embedded NamespaceGetter. | // information , which they can do directly through the embedded interfaces. | ||||||
| type Host interface { | type Host interface { | ||||||
| 	// NamespaceGetter is a getter for sandbox namespace information. | 	// NamespaceGetter is a getter for sandbox namespace information. | ||||||
| 	// It's the only part of this interface that isn't currently deprecated. |  | ||||||
| 	NamespaceGetter | 	NamespaceGetter | ||||||
|  |  | ||||||
|  | 	// PortMappingGetter is a getter for sandbox port mapping information. | ||||||
|  | 	PortMappingGetter | ||||||
|  |  | ||||||
| 	// LegacyHost contains methods that trap back into the Kubelet. Dependence | 	// LegacyHost contains methods that trap back into the Kubelet. Dependence | ||||||
| 	// *do not* add more dependencies in this interface. In a post-cri world, | 	// *do not* add more dependencies in this interface. In a post-cri world, | ||||||
| 	// network plugins will be invoked by the runtime shim, and should only | 	// network plugins will be invoked by the runtime shim, and should only | ||||||
| 	// require NamespaceGetter. | 	// require GetNetNS and GetPodPortMappings. | ||||||
| 	LegacyHost | 	LegacyHost | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -143,6 +146,14 @@ type NamespaceGetter interface { | |||||||
| 	GetNetNS(containerID string) (string, error) | 	GetNetNS(containerID string) (string, error) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // PortMappingGetter is an interface to retrieve port mapping information for a given | ||||||
|  | // sandboxID. Typically implemented by runtime shims that are closely coupled to | ||||||
|  | // CNI plugin wrappers like kubenet. | ||||||
|  | type PortMappingGetter interface { | ||||||
|  | 	// GetPodPortMappings returns sandbox port mappings information. | ||||||
|  | 	GetPodPortMappings(containerID string) ([]*hostport.PortMapping, error) | ||||||
|  | } | ||||||
|  |  | ||||||
| // InitNetworkPlugin inits the plugin that matches networkPluginName. Plugins must have unique names. | // InitNetworkPlugin inits the plugin that matches networkPluginName. Plugins must have unique names. | ||||||
| func InitNetworkPlugin(plugins []NetworkPlugin, networkPluginName string, host Host, hairpinMode componentconfig.HairpinMode, nonMasqueradeCIDR string, mtu int) (NetworkPlugin, error) { | func InitNetworkPlugin(plugins []NetworkPlugin, networkPluginName string, host Host, hairpinMode componentconfig.HairpinMode, nonMasqueradeCIDR string, mtu int) (NetworkPlugin, error) { | ||||||
| 	if networkPluginName == "" { | 	if networkPluginName == "" { | ||||||
| @@ -276,3 +287,9 @@ func GetPodIP(execer utilexec.Interface, nsenterPath, netnsPath, interfaceName s | |||||||
|  |  | ||||||
| 	return ip, nil | 	return ip, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type NoopPortMappingGetter struct{} | ||||||
|  |  | ||||||
|  | func (*NoopPortMappingGetter) GetPodPortMappings(containerID string) ([]*hostport.PortMapping, error) { | ||||||
|  | 	return nil, nil | ||||||
|  | } | ||||||
|   | |||||||
| @@ -24,10 +24,12 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" | 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" | ||||||
| 	containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" | 	containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubelet/network/hostport" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type fakeNetworkHost struct { | type fakeNetworkHost struct { | ||||||
| 	fakeNamespaceGetter | 	fakeNamespaceGetter | ||||||
|  | 	FakePortMappingGetter | ||||||
| 	kubeClient clientset.Interface | 	kubeClient clientset.Interface | ||||||
| 	Legacy     bool | 	Legacy     bool | ||||||
| 	Runtime    *containertest.FakeRuntime | 	Runtime    *containertest.FakeRuntime | ||||||
| @@ -61,3 +63,11 @@ type fakeNamespaceGetter struct { | |||||||
| func (nh *fakeNamespaceGetter) GetNetNS(containerID string) (string, error) { | func (nh *fakeNamespaceGetter) GetNetNS(containerID string) (string, error) { | ||||||
| 	return nh.ns, nil | 	return nh.ns, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type FakePortMappingGetter struct { | ||||||
|  | 	mem map[string][]*hostport.PortMapping | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (pm *FakePortMappingGetter) GetPodPortMappings(containerID string) ([]*hostport.PortMapping, error) { | ||||||
|  | 	return pm.mem[containerID], nil | ||||||
|  | } | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ import ( | |||||||
| 	"k8s.io/kubernetes/pkg/api/v1" | 	"k8s.io/kubernetes/pkg/api/v1" | ||||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||||
| 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" | 	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" | ||||||
|  | 	"k8s.io/kubernetes/pkg/kubelet/network" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // This just exports required functions from kubelet proper, for use by network | // This just exports required functions from kubelet proper, for use by network | ||||||
| @@ -54,6 +55,8 @@ func (nh *networkHost) SupportsLegacyFeatures() bool { | |||||||
| // methods, because networkHost is slated for deletion. | // methods, because networkHost is slated for deletion. | ||||||
| type criNetworkHost struct { | type criNetworkHost struct { | ||||||
| 	*networkHost | 	*networkHost | ||||||
|  | 	// criNetworkHost currently support legacy features. Hence no need to support PortMappingGetter | ||||||
|  | 	*network.NoopPortMappingGetter | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetNetNS returns the network namespace of the given containerID. | // GetNetNS returns the network namespace of the given containerID. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Minhan Xia
					Minhan Xia