Unverified Commit 1902a18c authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #59301 from dcbw/dockershim-stop-sandbox-no-ip

Automatic merge from submit-queue (batch tested with PRs 60435, 60334, 60458, 59301, 60125). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. dockershim: don't check pod IP in StopPodSandbox We're about to tear the container down, there's no point. It also suppresses an annoying error message due to kubelet stupidity that causes multiple parallel calls to StopPodSandbox for the same sandbox. docker_sandbox.go:355] failed to read pod IP from plugin/docker: NetworkPlugin cni failed on the status hook for pod "docker-registry-1-deploy_default": Unexpected command output nsenter: cannot open /proc/22646/ns/net: No such file or directory 1) A first StopPodSandbox() request triggered by SyncLoop(PLEG) for a ContainerDied event calls into TearDownPod() and thus the network plugin. Until this completes, networkReady=true for the sandbox. 2) A second StopPodSandbox() request triggered by SyncLoop(REMOVE) calls PodSandboxStatus() and calls into the network plugin to read the IP address because networkReady=true 3) The first request exits the network plugin, sets networReady=false, and calls StopContainer() on the sandbox. This destroys the network namespace. 4) The second request finally gets around to running nsenter but the network namespace is already destroyed. It returns an error which is logged by getIP(). ```release-note NONE ``` @yujuhong @freehan
parents 5badfc6b 60a955d4
...@@ -178,22 +178,18 @@ func (ds *dockerService) RunPodSandbox(ctx context.Context, r *runtimeapi.RunPod ...@@ -178,22 +178,18 @@ func (ds *dockerService) RunPodSandbox(ctx context.Context, r *runtimeapi.RunPod
func (ds *dockerService) StopPodSandbox(ctx context.Context, r *runtimeapi.StopPodSandboxRequest) (*runtimeapi.StopPodSandboxResponse, error) { func (ds *dockerService) StopPodSandbox(ctx context.Context, r *runtimeapi.StopPodSandboxRequest) (*runtimeapi.StopPodSandboxResponse, error) {
var namespace, name string var namespace, name string
var hostNetwork bool var hostNetwork bool
var checkpointErr, statusErr error
podSandboxID := r.PodSandboxId podSandboxID := r.PodSandboxId
resp := &runtimeapi.StopPodSandboxResponse{} resp := &runtimeapi.StopPodSandboxResponse{}
// Try to retrieve sandbox information from docker daemon or sandbox checkpoint // Try to retrieve minimal sandbox information from docker daemon or sandbox checkpoint.
statusResp, statusErr := ds.PodSandboxStatus(ctx, &runtimeapi.PodSandboxStatusRequest{PodSandboxId: podSandboxID}) inspectResult, metadata, statusErr := ds.getPodSandboxDetails(podSandboxID)
status := statusResp.GetStatus()
if statusErr == nil { if statusErr == nil {
hostNetwork = status.GetLinux().GetNamespaces().GetOptions().GetNetwork() == runtimeapi.NamespaceMode_NODE namespace = metadata.Namespace
m := status.GetMetadata() name = metadata.Name
namespace = m.Namespace hostNetwork = (networkNamespaceMode(inspectResult) == runtimeapi.NamespaceMode_NODE)
name = m.Name
} else { } else {
var checkpoint *PodSandboxCheckpoint checkpoint, checkpointErr := ds.checkpointHandler.GetCheckpoint(podSandboxID)
checkpoint, checkpointErr = ds.checkpointHandler.GetCheckpoint(podSandboxID)
// Proceed if both sandbox container and checkpoint could not be found. This means that following // Proceed if both sandbox container and checkpoint could not be found. This means that following
// actions will only have sandbox ID and not have pod namespace and name information. // actions will only have sandbox ID and not have pod namespace and name information.
...@@ -358,12 +354,26 @@ func (ds *dockerService) getIP(podSandboxID string, sandbox *dockertypes.Contain ...@@ -358,12 +354,26 @@ func (ds *dockerService) getIP(podSandboxID string, sandbox *dockertypes.Contain
return "" return ""
} }
// Returns the inspect container response, the sandbox metadata, and network namespace mode
func (ds *dockerService) getPodSandboxDetails(podSandboxID string) (*dockertypes.ContainerJSON, *runtimeapi.PodSandboxMetadata, error) {
resp, err := ds.client.InspectContainer(podSandboxID)
if err != nil {
return nil, nil, err
}
metadata, err := parseSandboxName(resp.Name)
if err != nil {
return nil, nil, err
}
return resp, metadata, nil
}
// PodSandboxStatus returns the status of the PodSandbox. // PodSandboxStatus returns the status of the PodSandbox.
func (ds *dockerService) PodSandboxStatus(ctx context.Context, req *runtimeapi.PodSandboxStatusRequest) (*runtimeapi.PodSandboxStatusResponse, error) { func (ds *dockerService) PodSandboxStatus(ctx context.Context, req *runtimeapi.PodSandboxStatusRequest) (*runtimeapi.PodSandboxStatusResponse, error) {
podSandboxID := req.PodSandboxId podSandboxID := req.PodSandboxId
// Inspect the container. r, metadata, err := ds.getPodSandboxDetails(podSandboxID)
r, err := ds.client.InspectContainer(podSandboxID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -388,10 +398,6 @@ func (ds *dockerService) PodSandboxStatus(ctx context.Context, req *runtimeapi.P ...@@ -388,10 +398,6 @@ func (ds *dockerService) PodSandboxStatus(ctx context.Context, req *runtimeapi.P
IP = ds.getIP(podSandboxID, r) IP = ds.getIP(podSandboxID, r)
} }
metadata, err := parseSandboxName(r.Name)
if err != nil {
return nil, err
}
labels, annotations := extractLabels(r.Config.Labels) labels, annotations := extractLabels(r.Config.Labels)
status := &runtimeapi.PodSandboxStatus{ status := &runtimeapi.PodSandboxStatus{
Id: r.ID, Id: r.ID,
......
...@@ -219,9 +219,6 @@ func TestNetworkPluginInvocation(t *testing.T) { ...@@ -219,9 +219,6 @@ func TestNetworkPluginInvocation(t *testing.T) {
mockPlugin.EXPECT().Name().Return("mockNetworkPlugin").AnyTimes() mockPlugin.EXPECT().Name().Return("mockNetworkPlugin").AnyTimes()
setup := mockPlugin.EXPECT().SetUpPod(ns, name, cID) setup := mockPlugin.EXPECT().SetUpPod(ns, name, cID)
// StopPodSandbox performs a lookup on status to figure out if the sandbox
// is running with hostnetworking, as all its given is the ID.
mockPlugin.EXPECT().GetPodNetworkStatus(ns, name, cID)
mockPlugin.EXPECT().TearDownPod(ns, name, cID).After(setup) mockPlugin.EXPECT().TearDownPod(ns, name, cID).After(setup)
_, err := ds.RunPodSandbox(getTestCTX(), &runtimeapi.RunPodSandboxRequest{Config: c}) _, err := ds.RunPodSandbox(getTestCTX(), &runtimeapi.RunPodSandboxRequest{Config: c})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment