Skip to content

Commit 4edd81f

Browse files
committed
sdn: clean up pod IPAM allocation even if we don't have a netns
We don't actually need the netns for IPAM teardown, so don't bother passing it. Also ensure we can release an IPAM allocation even when the container has already died, in case kubelet didn't call the plugin in this case.
1 parent 32c2948 commit 4edd81f

File tree

1 file changed

+43
-34
lines changed

1 file changed

+43
-34
lines changed

pkg/sdn/plugin/pod_linux.go

+43-34
Original file line numberDiff line numberDiff line change
@@ -213,35 +213,41 @@ func addMacvlan(netns string) error {
213213

214214
// Run CNI IPAM for the container, either allocating an IP address and returning
215215
// it (for ADD) or releasing the lease and cleaning up (for DEL)
216-
func (m *podManager) runIPAM(netnsPath string, action cniserver.CNICommand, id string) (*cnitypes.Result, error) {
217-
args := &invoke.Args{
216+
func createIPAMArgs(netnsPath string, action cniserver.CNICommand, id string) *invoke.Args {
217+
return &invoke.Args{
218218
Command: string(action),
219219
ContainerID: id,
220220
NetNS: netnsPath,
221221
IfName: podInterfaceName,
222222
Path: "/opt/cni/bin",
223223
}
224+
}
224225

225-
if action == cniserver.CNI_ADD {
226-
result, err := invoke.ExecPluginWithResult("/opt/cni/bin/host-local", m.ipamConfig, args)
227-
if err != nil {
228-
return nil, fmt.Errorf("failed to run CNI IPAM ADD: %v", err)
229-
}
226+
func (m *podManager) ipamAdd(netnsPath string, id string) (*cnitypes.Result, error) {
227+
if netnsPath == "" {
228+
return nil, fmt.Errorf("netns requires for CNI_ADD")
229+
}
230230

231-
if result.IP4 == nil {
232-
return nil, fmt.Errorf("failed to obtain IP address from CNI IPAM")
233-
}
231+
args := createIPAMArgs(netnsPath, cniserver.CNI_ADD, id)
232+
result, err := invoke.ExecPluginWithResult("/opt/cni/bin/host-local", m.ipamConfig, args)
233+
if err != nil {
234+
return nil, fmt.Errorf("failed to run CNI IPAM ADD: %v", err)
235+
}
234236

235-
return result, nil
236-
} else if action == cniserver.CNI_DEL {
237-
err := invoke.ExecPluginWithoutResult("/opt/cni/bin/host-local", m.ipamConfig, args)
238-
if err != nil {
239-
return nil, fmt.Errorf("failed to run CNI IPAM DEL: %v", err)
240-
}
241-
return nil, nil
237+
if result.IP4 == nil {
238+
return nil, fmt.Errorf("failed to obtain IP address from CNI IPAM")
242239
}
243240

244-
return nil, fmt.Errorf("invalid IPAM action %v", action)
241+
return result, nil
242+
}
243+
244+
func (m *podManager) ipamDel(id string) error {
245+
args := createIPAMArgs("", cniserver.CNI_DEL, id)
246+
err := invoke.ExecPluginWithoutResult("/opt/cni/bin/host-local", m.ipamConfig, args)
247+
if err != nil {
248+
return fmt.Errorf("failed to run CNI IPAM DEL: %v", err)
249+
}
250+
return nil
245251
}
246252

247253
func isScriptError(err error) bool {
@@ -271,7 +277,7 @@ func (m *podManager) setup(req *cniserver.PodRequest) (*cnitypes.Result, *kubeho
271277
return nil, nil, err
272278
}
273279

274-
ipamResult, err := m.runIPAM(req.Netns, cniserver.CNI_ADD, req.ContainerId)
280+
ipamResult, err := m.ipamAdd(req.Netns, req.ContainerId)
275281
if err != nil {
276282
return nil, nil, fmt.Errorf("failed to run IPAM for %v: %v", req.ContainerId, err)
277283
}
@@ -281,7 +287,7 @@ func (m *podManager) setup(req *cniserver.PodRequest) (*cnitypes.Result, *kubeho
281287
var success bool
282288
defer func() {
283289
if !success {
284-
m.runIPAM(req.Netns, cniserver.CNI_DEL, req.ContainerId)
290+
m.ipamDel(req.ContainerId)
285291
if err := m.hostportHandler.SyncHostports(TUN, m.getRunningPods()); err != nil {
286292
glog.Warningf("failed syncing hostports: %v", err)
287293
}
@@ -393,29 +399,32 @@ func (m *podManager) update(req *cniserver.PodRequest) error {
393399

394400
// Clean up all pod networking (clear OVS flows, release IPAM lease, remove host/container veth)
395401
func (m *podManager) teardown(req *cniserver.PodRequest) error {
402+
netnsValid := true
396403
if err := ns.IsNSorErr(req.Netns); err != nil {
397404
if _, ok := err.(ns.NSPathNotExistErr); ok {
398-
glog.V(3).Infof("teardown called on already-destroyed pod %s/%s", req.PodNamespace, req.PodName)
399-
return nil
405+
glog.V(3).Infof("teardown called on already-destroyed pod %s/%s; only cleaning up IPAM", req.PodNamespace, req.PodName)
406+
netnsValid = false
400407
}
401408
}
402409

403-
hostVethName, contVethMac, podIP, err := getVethInfo(req.Netns, podInterfaceName)
404-
if err != nil {
405-
return err
406-
}
410+
if netnsValid {
411+
hostVethName, contVethMac, podIP, err := getVethInfo(req.Netns, podInterfaceName)
412+
if err != nil {
413+
return err
414+
}
407415

408-
// The script's teardown functionality doesn't need the VNID
409-
out, err := exec.Command(sdnScript, tearDownCmd, hostVethName, contVethMac, podIP, "-1").CombinedOutput()
410-
glog.V(5).Infof("TearDownPod network plugin output: %s, %v", string(out), err)
416+
// The script's teardown functionality doesn't need the VNID
417+
out, err := exec.Command(sdnScript, tearDownCmd, hostVethName, contVethMac, podIP, "-1").CombinedOutput()
418+
glog.V(5).Infof("TearDownPod network plugin output: %s, %v", string(out), err)
411419

412-
if isScriptError(err) {
413-
return fmt.Errorf("error running network teardown script: %s", getScriptError(out))
414-
} else if err != nil {
415-
return err
420+
if isScriptError(err) {
421+
return fmt.Errorf("error running network teardown script: %s", getScriptError(out))
422+
} else if err != nil {
423+
return err
424+
}
416425
}
417426

418-
if _, err := m.runIPAM(req.Netns, cniserver.CNI_DEL, req.ContainerId); err != nil {
427+
if err := m.ipamDel(req.ContainerId); err != nil {
419428
return err
420429
}
421430

0 commit comments

Comments
 (0)