Merge pull request #25136 from dcbw/kubenet-fixup-txqueuelen

Automatic merge from submit-queue

kubenet: fix up CNI bridge TX queue length if needed

CNI's bridge plugin mis-handles the TxQLen when creating the bridge,
leading to a zero-length TX queue.  This doesn't typically cause
problems (since virtual interfaces don't have hard queue limits)
but when adding traffic shaping, some qdiscs pull their packet
limits from the TX queue length, leading to a packet limit of 0
in some cases.  Until we can depend on a new enough version of
CNI, fix up the TX queue length internally.

Closes: https://github.com/kubernetes/kubernetes/issues/25092
pull/6/head
k8s-merge-robot 2016-05-06 06:29:31 -07:00
commit 32256d53aa
1 changed files with 33 additions and 0 deletions

View File

@ -26,6 +26,7 @@ import (
"syscall" "syscall"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
"github.com/vishvananda/netlink/nl"
"github.com/appc/cni/libcni" "github.com/appc/cni/libcni"
"github.com/golang/glog" "github.com/golang/glog"
@ -197,6 +198,37 @@ func (plugin *kubenetNetworkPlugin) clearBridgeAddressesExcept(keep string) {
} }
} }
// ensureBridgeTxQueueLen() ensures that the bridge interface's TX queue
// length is greater than zero. Due to a CNI <= 0.3.0 'bridge' plugin bug,
// the bridge is initially created with a TX queue length of 0, which gets
// used as the packet limit for FIFO traffic shapers, which drops packets.
// TODO: remove when we can depend on a fixed CNI
func (plugin *kubenetNetworkPlugin) ensureBridgeTxQueueLen() {
bridge, err := netlink.LinkByName(BridgeName)
if err != nil {
return
}
if bridge.Attrs().TxQLen > 0 {
return
}
req := nl.NewNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
req.AddData(msg)
nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(BridgeName))
req.AddData(nameData)
qlen := nl.NewRtAttr(syscall.IFLA_TXQLEN, nl.Uint32Attr(1000))
req.AddData(qlen)
_, err = req.Execute(syscall.NETLINK_ROUTE, 0)
if err != nil {
glog.V(5).Infof("Failed to set bridge tx queue length: %v", err)
}
}
func (plugin *kubenetNetworkPlugin) Name() string { func (plugin *kubenetNetworkPlugin) Name() string {
return KubenetPluginName return KubenetPluginName
} }
@ -243,6 +275,7 @@ func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id k
if plugin.shaper == nil { if plugin.shaper == nil {
return fmt.Errorf("Failed to create bandwidth shaper!") return fmt.Errorf("Failed to create bandwidth shaper!")
} }
plugin.ensureBridgeTxQueueLen()
plugin.shaper.ReconcileInterface() plugin.shaper.ReconcileInterface()
} }