Merge pull request #22827 from dcbw/net-plugin-capabilities

Automatic merge from submit-queue

Implement network plugin capabilities hook and shaping capability

Allow network plugins to declare that they handle shaping and that
Kuberenetes should not.  I've got an OpenShift PR that handles shaping in OVS but the kubelet code sends nasty pod events because it doesn't think shaping is used since --reconcile-cbr0 is not used with most network plugins.

See https://github.com/openshift/openshift-sdn/pull/266 for the OpenShift implementation.
pull/6/head
k8s-merge-robot 2016-03-31 03:20:07 -07:00
commit 62eb7d3db8
6 changed files with 48 additions and 20 deletions

View File

@ -1798,6 +1798,9 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, podStatus *kubecont
return err return err
} }
if !kl.shapingEnabled() {
return nil
}
ingress, egress, err := extractBandwidthResources(pod) ingress, egress, err := extractBandwidthResources(pod)
if err != nil { if err != nil {
return err return err
@ -2734,11 +2737,14 @@ func (kl *Kubelet) reconcileCBR0(podCIDR string) error {
if err := ensureCbr0(cidr, kl.hairpinMode == componentconfig.PromiscuousBridge, kl.babysitDaemons); err != nil { if err := ensureCbr0(cidr, kl.hairpinMode == componentconfig.PromiscuousBridge, kl.babysitDaemons); err != nil {
return err return err
} }
if kl.shaper == nil { if kl.shapingEnabled() {
glog.V(5).Info("Shaper is nil, creating") if kl.shaper == nil {
kl.shaper = bandwidth.NewTCShaper("cbr0") glog.V(5).Info("Shaper is nil, creating")
kl.shaper = bandwidth.NewTCShaper("cbr0")
}
return kl.shaper.ReconcileInterface()
} }
return kl.shaper.ReconcileInterface() return nil
} }
// updateNodeStatus updates node status to master with retries. // updateNodeStatus updates node status to master with retries.
@ -3594,6 +3600,15 @@ func (kl *Kubelet) updatePodCIDR(cidr string) {
kl.networkPlugin.Event(network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE, details) kl.networkPlugin.Event(network.NET_PLUGIN_EVENT_POD_CIDR_CHANGE, details)
} }
} }
func (kl *Kubelet) shapingEnabled() bool {
// Disable shaping if a network plugin is defined and supports shaping
if kl.networkPlugin != nil && kl.networkPlugin.Capabilities().Has(network.NET_PLUGIN_CAPABILITY_SHAPING) {
return false
}
return true
}
func (kl *Kubelet) GetNodeConfig() cm.NodeConfig { func (kl *Kubelet) GetNodeConfig() cm.NodeConfig {
return kl.containerManager.GetNodeConfig() return kl.containerManager.GetNodeConfig()
} }

View File

@ -38,6 +38,8 @@ const (
) )
type cniNetworkPlugin struct { type cniNetworkPlugin struct {
network.NoopNetworkPlugin
defaultNetwork *cniNetwork defaultNetwork *cniNetwork
host network.Host host network.Host
} }
@ -96,9 +98,6 @@ func (plugin *cniNetworkPlugin) Init(host network.Host) error {
return nil return nil
} }
func (plugin *cniNetworkPlugin) Event(name string, details map[string]interface{}) {
}
func (plugin *cniNetworkPlugin) Name() string { func (plugin *cniNetworkPlugin) Name() string {
return CNIPluginName return CNIPluginName
} }

View File

@ -72,6 +72,8 @@ import (
) )
type execNetworkPlugin struct { type execNetworkPlugin struct {
network.NoopNetworkPlugin
execName string execName string
execPath string execPath string
host network.Host host network.Host
@ -120,9 +122,6 @@ func (plugin *execNetworkPlugin) getExecutable() string {
return path.Join(plugin.execPath, execName) return path.Join(plugin.execPath, execName)
} }
func (plugin *execNetworkPlugin) Event(name string, details map[string]interface{}) {
}
func (plugin *execNetworkPlugin) Name() string { func (plugin *execNetworkPlugin) Name() string {
return plugin.execName return plugin.execName
} }

View File

@ -41,6 +41,8 @@ const (
) )
type kubenetNetworkPlugin struct { type kubenetNetworkPlugin struct {
network.NoopNetworkPlugin
host network.Host host network.Host
netConfig *libcni.NetworkConfig netConfig *libcni.NetworkConfig
cniConfig *libcni.CNIConfig cniConfig *libcni.CNIConfig

View File

@ -26,6 +26,7 @@ import (
) )
type kubenetNetworkPlugin struct { type kubenetNetworkPlugin struct {
network.NoopNetworkPlugin
} }
func NewPlugin() network.NetworkPlugin { func NewPlugin() network.NetworkPlugin {
@ -35,8 +36,6 @@ func NewPlugin() network.NetworkPlugin {
func (plugin *kubenetNetworkPlugin) Init(host network.Host) error { func (plugin *kubenetNetworkPlugin) Init(host network.Host) error {
return fmt.Errorf("Kubenet is not supported in this build") return fmt.Errorf("Kubenet is not supported in this build")
} }
func (plugin *kubenetNetworkPlugin) Event(name string, details map[string]interface{}) {
}
func (plugin *kubenetNetworkPlugin) Name() string { func (plugin *kubenetNetworkPlugin) Name() string {
return "kubenet" return "kubenet"

View File

@ -29,6 +29,7 @@ import (
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
utilerrors "k8s.io/kubernetes/pkg/util/errors" utilerrors "k8s.io/kubernetes/pkg/util/errors"
utilexec "k8s.io/kubernetes/pkg/util/exec" utilexec "k8s.io/kubernetes/pkg/util/exec"
utilsets "k8s.io/kubernetes/pkg/util/sets"
utilsysctl "k8s.io/kubernetes/pkg/util/sysctl" utilsysctl "k8s.io/kubernetes/pkg/util/sysctl"
"k8s.io/kubernetes/pkg/util/validation" "k8s.io/kubernetes/pkg/util/validation"
) )
@ -40,6 +41,12 @@ const DefaultPluginName = "kubernetes.io/no-op"
const NET_PLUGIN_EVENT_POD_CIDR_CHANGE = "pod-cidr-change" const NET_PLUGIN_EVENT_POD_CIDR_CHANGE = "pod-cidr-change"
const NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR = "pod-cidr" const NET_PLUGIN_EVENT_POD_CIDR_CHANGE_DETAIL_CIDR = "pod-cidr"
// Plugin capabilities
const (
// Indicates the plugin handles Kubernetes bandwidth shaping annotations internally
NET_PLUGIN_CAPABILITY_SHAPING int = 1
)
// Plugin is an interface to network plugins for the kubelet // Plugin is an interface to network plugins for the kubelet
type NetworkPlugin interface { type NetworkPlugin interface {
// Init initializes the plugin. This will be called exactly once // Init initializes the plugin. This will be called exactly once
@ -54,6 +61,9 @@ type NetworkPlugin interface {
// for a plugin by name, e.g. // for a plugin by name, e.g.
Name() string Name() string
// Returns a set of NET_PLUGIN_CAPABILITY_*
Capabilities() utilsets.Int
// SetUpPod is the method called after the infra container of // SetUpPod is the method called after the infra container of
// the pod has been created but before the other containers of the // the pod has been created but before the other containers of the
// pod are launched. // pod are launched.
@ -94,7 +104,7 @@ type Host interface {
func InitNetworkPlugin(plugins []NetworkPlugin, networkPluginName string, host Host) (NetworkPlugin, error) { func InitNetworkPlugin(plugins []NetworkPlugin, networkPluginName string, host Host) (NetworkPlugin, error) {
if networkPluginName == "" { if networkPluginName == "" {
// default to the no_op plugin // default to the no_op plugin
plug := &noopNetworkPlugin{} plug := &NoopNetworkPlugin{}
if err := plug.Init(host); err != nil { if err := plug.Init(host); err != nil {
return nil, err return nil, err
} }
@ -137,12 +147,12 @@ func UnescapePluginName(in string) string {
return strings.Replace(in, "~", "/", -1) return strings.Replace(in, "~", "/", -1)
} }
type noopNetworkPlugin struct { type NoopNetworkPlugin struct {
} }
const sysctlBridgeCallIptables = "net/bridge/bridge-nf-call-iptables" const sysctlBridgeCallIptables = "net/bridge/bridge-nf-call-iptables"
func (plugin *noopNetworkPlugin) Init(host Host) error { func (plugin *NoopNetworkPlugin) Init(host Host) error {
// Set bridge-nf-call-iptables=1 to maintain compatibility with older // Set bridge-nf-call-iptables=1 to maintain compatibility with older
// kubernetes versions to ensure the iptables-based kube proxy functions // kubernetes versions to ensure the iptables-based kube proxy functions
// correctly. Other plugins are responsible for setting this correctly // correctly. Other plugins are responsible for setting this correctly
@ -159,21 +169,25 @@ func (plugin *noopNetworkPlugin) Init(host Host) error {
return nil return nil
} }
func (plugin *noopNetworkPlugin) Event(name string, details map[string]interface{}) { func (plugin *NoopNetworkPlugin) Event(name string, details map[string]interface{}) {
} }
func (plugin *noopNetworkPlugin) Name() string { func (plugin *NoopNetworkPlugin) Name() string {
return DefaultPluginName return DefaultPluginName
} }
func (plugin *noopNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.DockerID) error { func (plugin *NoopNetworkPlugin) Capabilities() utilsets.Int {
return utilsets.NewInt()
}
func (plugin *NoopNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.DockerID) error {
return nil return nil
} }
func (plugin *noopNetworkPlugin) TearDownPod(namespace string, name string, id kubecontainer.DockerID) error { func (plugin *NoopNetworkPlugin) TearDownPod(namespace string, name string, id kubecontainer.DockerID) error {
return nil return nil
} }
func (plugin *noopNetworkPlugin) Status(namespace string, name string, id kubecontainer.DockerID) (*PodNetworkStatus, error) { func (plugin *NoopNetworkPlugin) Status(namespace string, name string, id kubecontainer.DockerID) (*PodNetworkStatus, error) {
return nil, nil return nil, nil
} }