Skip to content

Commit

Permalink
Merge pull request kubernetes#18425 from dcbw/kube-59301-backport
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue.

UPSTREAM: 59301: 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().

Fixes: openshift/origin#18414

@danwinship

Origin-commit: 73e9c8fa185d0f7bb9a0798185f78598cf4bb42b
  • Loading branch information
k8s-publishing-bot committed Mar 23, 2018
2 parents cc0c3bc + e3ad62f commit 26679ff
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 18 deletions.
37 changes: 22 additions & 15 deletions pkg/kubelet/dockershim/docker_sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,15 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (id
func (ds *dockerService) StopPodSandbox(podSandboxID string) error {
var namespace, name string
var hostNetwork bool
var checkpointErr, statusErr error

// Try to retrieve sandbox information from docker daemon or sandbox checkpoint
status, statusErr := ds.PodSandboxStatus(podSandboxID)
// Try to retrieve minimal sandbox information from docker daemon or sandbox checkpoint.
inspectResult, metadata, statusErr := ds.getPodSandboxDetails(podSandboxID)
if statusErr == nil {
nsOpts := status.GetLinux().GetNamespaces().GetOptions()
hostNetwork = nsOpts != nil && nsOpts.HostNetwork
m := status.GetMetadata()
namespace = m.Namespace
name = m.Name
namespace = metadata.Namespace
name = metadata.Name
hostNetwork = sharesHostNetwork(inspectResult)
} 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
// actions will only have sandbox ID and not have pod namespace and name information.
Expand Down Expand Up @@ -341,10 +337,25 @@ func (ds *dockerService) getIP(podSandboxID string, sandbox *dockertypes.Contain
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.
func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeapi.PodSandboxStatus, error) {
// Inspect the container.
r, err := ds.client.InspectContainer(podSandboxID)
r, metadata, err := ds.getPodSandboxDetails(podSandboxID)
if err != nil {
return nil, err
}
Expand All @@ -370,10 +381,6 @@ func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeapi.PodS
}
hostNetwork := sharesHostNetwork(r)

metadata, err := parseSandboxName(r.Name)
if err != nil {
return nil, err
}
labels, annotations := extractLabels(r.Config.Labels)
return &runtimeapi.PodSandboxStatus{
Id: r.ID,
Expand Down
3 changes: 0 additions & 3 deletions pkg/kubelet/dockershim/docker_sandbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,6 @@ func TestNetworkPluginInvocation(t *testing.T) {

mockPlugin.EXPECT().Name().Return("mockNetworkPlugin").AnyTimes()
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)

_, err := ds.RunPodSandbox(c)
Expand Down

0 comments on commit 26679ff

Please sign in to comment.