New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: don't create sandbox when bridge is none to avoid docker restart hang. #42454
Fix: don't create sandbox when bridge is none to avoid docker restart hang. #42454
Conversation
af3d378
to
a790247
Compare
ping @AkihiroSuda @fuweid |
I'm a bit confused; wouldn't the container still need a sandbox?
Do you know why it's not removed? Feels like that may be the actual bug? |
SummaryWhen we set bridge to "none" and create a container, we'll get:
When we delete the container, it will:
DetailCreate containerfunc (daemon *Daemon) allocateNetwork(container *container.Container) (retErr error) {
if nConf, ok := container.NetworkSettings.Networks[defaultNetName]; ok {
// set container.Config.NetworkDisabled here
if err := daemon.connectToNetwork(container, defaultNetName, nConf.EndpointSettings, updateSettings); err != nil {
return err
}
}
// Create its network sandbox now if not present
if len(networks) == 0 {
if nil == daemon.getNetworkSandbox(container) {
sb, err := daemon.netController.NewSandbox(container.ID, sbOptions...)
if err != nil {
return err
}
updateSandboxNetworkSettings(container, sb)
defer func() {
if retErr != nil {
sb.Delete()
}
}()
}
}
}
func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, ...) (err error) {
// ...
if containertypes.NetworkMode(idOrName).IsBridge() &&
daemon.configStore.DisableBridge {
container.Config.NetworkDisabled = true
return nil
}
// ...
} Delete containerWhen deleting the container, we'll check func (daemon *Daemon) releaseNetwork(container *container.Container) {
if container.HostConfig.NetworkMode.IsContainer() || container.Config.NetworkDisabled {
return
}
// ...
sb, err := daemon.netController.SandboxByID(sid)
// ...
if err := sb.Delete(); err != nil {
logrus.Errorf("Error deleting sandbox id %s for container %s: %v", sid, container.ID, err)
}
// ...
} @thaJeztah Sorry for my late response. |
Is the sandbox ID set in that case? Because if that's the case, removing the moby/daemon/container_operations.go Lines 1017 to 1027 in a773178
If the sandbox-ID is not set (empty), it would already return early. and if it's set, it would clean it up. If the sandbox ID is set in this case, I think that's something that should be done (even with this fix applied) Looking further; I wonder if there's other situations that are overlooked for which things should be skipped; thinking of moby/daemon/container_operations.go Lines 978 to 989 in a773178
|
a790247
to
fcde313
Compare
@@ -1014,7 +1014,7 @@ func (daemon *Daemon) releaseNetwork(container *container.Container) { | |||
if daemon.netController == nil { | |||
return | |||
} | |||
if container.HostConfig.NetworkMode.IsContainer() || container.Config.NetworkDisabled { | |||
if container.HostConfig.NetworkMode.IsContainer() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that container.NetworkSettings
is a pointer, so could (potentially) be nil
; perhaps we need a check for that below, to prevent a panic if that ever happens (not sure if possible)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that container.NetworkSettings is a pointer, so could (potentially) be nil; perhaps we need a check for that below, to prevent a panic if that ever happens (not sure if possible)
I think that container.NetworkSettings
is never nil
, unless someone update the container config on disk and restart docker daemon. It's always good to check.
Signed-off-by: payall4u <payall4u@qq.com>
fcde313
to
33bfb32
Compare
Ping @thaJeztah |
From #42461
- What I did
If we create container with docker daemon disable bridge, we'll create needless sandbox.
And when the container be removed, the sandbox will be stayed here. Only when dockerd be restarted, those sandbox would be deleted by sandboxCleanup(). 4000 such sandbox will cost nearly 10 minutes. It means restarting docker daemon will hang more then 10 minutes.
So I think we should assign the
NetworkDisabled
earlier.- How I did it
I fix the bug by setting NetworkDisabled correctly.
- How to verify it
"bridge": "none"
for i in $(seq 1 4000); do docker run --rm ubuntu; done
to create many sandbox.- Description for the changelog
Setting NetworkDisabled correctly to avoid restart docker hang.
- A picture of a cute animal (not mandatory but encouraged)
馃惂馃惂馃惂