mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
kubenet: Fix panic when teardown run before setup
Teardown can run before Setup when the kubelet is restarted... in that case, the shaper was nil and thus calling the shaper resulted in a panic This fixes that by ensuring the shaper is always set... +1 level of indirection and all that.
This commit is contained in:
parent
2f5e738dc1
commit
7e0b9bfa66
@ -64,19 +64,19 @@ const (
|
|||||||
type kubenetNetworkPlugin struct {
|
type kubenetNetworkPlugin struct {
|
||||||
network.NoopNetworkPlugin
|
network.NoopNetworkPlugin
|
||||||
|
|
||||||
host network.Host
|
host network.Host
|
||||||
netConfig *libcni.NetworkConfig
|
netConfig *libcni.NetworkConfig
|
||||||
loConfig *libcni.NetworkConfig
|
loConfig *libcni.NetworkConfig
|
||||||
cniConfig libcni.CNI
|
cniConfig libcni.CNI
|
||||||
shaper bandwidth.BandwidthShaper
|
bandwidthShaper bandwidth.BandwidthShaper
|
||||||
mu sync.Mutex //Mutex for protecting podIPs map and netConfig
|
mu sync.Mutex //Mutex for protecting podIPs map, netConfig, and shaper initialization
|
||||||
podIPs map[kubecontainer.ContainerID]string
|
podIPs map[kubecontainer.ContainerID]string
|
||||||
MTU int
|
MTU int
|
||||||
execer utilexec.Interface
|
execer utilexec.Interface
|
||||||
nsenterPath string
|
nsenterPath string
|
||||||
hairpinMode componentconfig.HairpinMode
|
hairpinMode componentconfig.HairpinMode
|
||||||
hostPortMap map[hostport]closeable
|
hostPortMap map[hostport]closeable
|
||||||
iptables utiliptables.Interface
|
iptables utiliptables.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlugin() network.NetworkPlugin {
|
func NewPlugin() network.NetworkPlugin {
|
||||||
@ -335,19 +335,13 @@ func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id k
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first SetUpPod call creates the bridge; ensure shaping is enabled
|
// The first SetUpPod call creates the bridge; get a shaper for the sake of
|
||||||
if plugin.shaper == nil {
|
// initialization
|
||||||
plugin.shaper = bandwidth.NewTCShaper(BridgeName)
|
shaper := plugin.shaper()
|
||||||
if plugin.shaper == nil {
|
|
||||||
return fmt.Errorf("Failed to create bandwidth shaper!")
|
|
||||||
}
|
|
||||||
plugin.ensureBridgeTxQueueLen()
|
|
||||||
plugin.shaper.ReconcileInterface()
|
|
||||||
}
|
|
||||||
|
|
||||||
if egress != nil || ingress != nil {
|
if egress != nil || ingress != nil {
|
||||||
ipAddr := plugin.podIPs[id]
|
ipAddr := plugin.podIPs[id]
|
||||||
if err := plugin.shaper.ReconcileCIDR(fmt.Sprintf("%s/32", ipAddr), egress, ingress); err != nil {
|
if err := shaper.ReconcileCIDR(fmt.Sprintf("%s/32", ipAddr), egress, ingress); err != nil {
|
||||||
return fmt.Errorf("Failed to add pod to shaper: %v", err)
|
return fmt.Errorf("Failed to add pod to shaper: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,7 +368,7 @@ func (plugin *kubenetNetworkPlugin) TearDownPod(namespace string, name string, i
|
|||||||
if hasIP {
|
if hasIP {
|
||||||
glog.V(5).Infof("Removing pod IP %s from shaper", podIP)
|
glog.V(5).Infof("Removing pod IP %s from shaper", podIP)
|
||||||
// shaper wants /32
|
// shaper wants /32
|
||||||
if err := plugin.shaper.Reset(fmt.Sprintf("%s/32", podIP)); err != nil {
|
if err := plugin.shaper().Reset(fmt.Sprintf("%s/32", podIP)); err != nil {
|
||||||
glog.Warningf("Failed to remove pod IP %s from shaper: %v", podIP, err)
|
glog.Warningf("Failed to remove pod IP %s from shaper: %v", podIP, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -811,3 +805,15 @@ func (plugin *kubenetNetworkPlugin) cleanupHostportMap(containerPortMap map[api.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shaper retrieves the bandwidth shaper and, if it hasn't been fetched before,
|
||||||
|
// initializes it and ensures the bridge is appropriately configured
|
||||||
|
// This function should only be called while holding the `plugin.mu` lock
|
||||||
|
func (plugin *kubenetNetworkPlugin) shaper() bandwidth.BandwidthShaper {
|
||||||
|
if plugin.bandwidthShaper == nil {
|
||||||
|
plugin.bandwidthShaper = bandwidth.NewTCShaper(BridgeName)
|
||||||
|
plugin.ensureBridgeTxQueueLen()
|
||||||
|
plugin.bandwidthShaper.ReconcileInterface()
|
||||||
|
}
|
||||||
|
return plugin.bandwidthShaper
|
||||||
|
}
|
||||||
|
@ -135,8 +135,8 @@ func TestTeardownCallsShaper(t *testing.T) {
|
|||||||
mockcni := &mock_cni.MockCNI{}
|
mockcni := &mock_cni.MockCNI{}
|
||||||
kubenet := newFakeKubenetPlugin(map[kubecontainer.ContainerID]string{}, fexec, fhost)
|
kubenet := newFakeKubenetPlugin(map[kubecontainer.ContainerID]string{}, fexec, fhost)
|
||||||
kubenet.cniConfig = mockcni
|
kubenet.cniConfig = mockcni
|
||||||
kubenet.shaper = fshaper
|
|
||||||
kubenet.iptables = ipttest.NewFake()
|
kubenet.iptables = ipttest.NewFake()
|
||||||
|
kubenet.bandwidthShaper = fshaper
|
||||||
|
|
||||||
mockcni.On("DelNetwork", mock.AnythingOfType("*libcni.NetworkConfig"), mock.AnythingOfType("*libcni.RuntimeConf")).Return(nil)
|
mockcni.On("DelNetwork", mock.AnythingOfType("*libcni.NetworkConfig"), mock.AnythingOfType("*libcni.RuntimeConf")).Return(nil)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user