Teardown pod network even if the network namespace is closed

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu 2018-10-09 23:13:25 -07:00
parent 70da14e4b3
commit c39f63eaf4
2 changed files with 21 additions and 17 deletions

View File

@ -17,7 +17,6 @@ limitations under the License.
package server package server
import ( import (
"os"
"time" "time"
"github.com/containerd/containerd" "github.com/containerd/containerd"
@ -60,23 +59,21 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
} }
// Teardown network for sandbox. // Teardown network for sandbox.
if sandbox.NetNSPath != "" && sandbox.NetNS != nil { if sandbox.NetNSPath != "" {
if _, err := os.Stat(sandbox.NetNSPath); err != nil { netNSPath := sandbox.NetNSPath
if !os.IsNotExist(err) { if sandbox.NetNS == nil || sandbox.NetNS.Closed() {
return nil, errors.Wrapf(err, "failed to stat network namespace path %s", sandbox.NetNSPath) // Use empty netns path if netns is not available. This is defined in:
} // https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md
} else { netNSPath = ""
if teardownErr := c.teardownPod(id, sandbox.NetNSPath, sandbox.Config); teardownErr != nil {
return nil, errors.Wrapf(teardownErr, "failed to destroy network for sandbox %q", id)
}
} }
/*TODO:It is still possible that containerd crashes after we teardown the network, but before we remove the network namespace. if err := c.teardownPod(id, netNSPath, sandbox.Config); err != nil {
In that case, we'll not be able to remove the sandbox anymore. The chance is slim, but we should be aware of that. return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id)
In the future, once TearDownPod is idempotent, this will be fixed.*/ }
// Close the sandbox network namespace if it was created
//Close the sandbox network namespace if it was created if sandbox.NetNS != nil {
if err = sandbox.NetNS.Remove(); err != nil { if err = sandbox.NetNS.Remove(); err != nil {
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id) return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
}
} }
} }

View File

@ -27,6 +27,13 @@ import (
osinterface "github.com/containerd/cri/pkg/os" osinterface "github.com/containerd/cri/pkg/os"
) )
// The NetNS library assumes only containerd manages the lifecycle of the
// network namespace mount. The only case that netns will be unmounted by
// someone else is node reboot.
// If this assumption is broken, NetNS won't be aware of the external
// unmount, and there will be a state mismatch.
// TODO(random-liu): Don't cache state, always load from the system.
// ErrClosedNetNS is the error returned when network namespace is closed. // ErrClosedNetNS is the error returned when network namespace is closed.
var ErrClosedNetNS = errors.New("network namespace is closed") var ErrClosedNetNS = errors.New("network namespace is closed")