Skip to content

Commit

Permalink
Merge pull request #37149 from dmcgowan/split-libcontainerd
Browse files Browse the repository at this point in the history
libcontainerd: split client and daemon supervision
  • Loading branch information
thaJeztah committed Aug 16, 2018
2 parents 0a4f895 + dd2e19e commit 4d62192
Show file tree
Hide file tree
Showing 19 changed files with 338 additions and 474 deletions.
68 changes: 44 additions & 24 deletions cmd/dockerd/daemon.go
Expand Up @@ -36,7 +36,7 @@ import (
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/daemon/listeners"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/libcontainerd"
"github.com/docker/docker/libcontainerd/supervisor"
dopts "github.com/docker/docker/opts"
"github.com/docker/docker/pkg/authorization"
"github.com/docker/docker/pkg/jsonmessage"
Expand All @@ -45,7 +45,6 @@ import (
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/plugin"
"github.com/docker/docker/registry"
"github.com/docker/docker/runconfig"
"github.com/docker/go-connections/tlsconfig"
swarmapi "github.com/docker/swarmkit/api"
Expand Down Expand Up @@ -112,6 +111,10 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
return err
}

if err := system.MkdirAll(cli.Config.ExecRoot, 0700, ""); err != nil {
return err
}

if cli.Pidfile != "" {
pf, err := pidfile.New(cli.Pidfile)
if err != nil {
Expand All @@ -135,19 +138,27 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
return fmt.Errorf("Failed to load listeners: %v", err)
}

registryService, err := registry.NewService(cli.Config.ServiceOptions)
if err != nil {
return err
}
ctx, cancel := context.WithCancel(context.Background())
if cli.Config.ContainerdAddr == "" && runtime.GOOS != "windows" {
opts, err := cli.getContainerdDaemonOpts()
if err != nil {
cancel()
return fmt.Errorf("Failed to generate containerd options: %v", err)
}

rOpts, err := cli.getRemoteOptions()
if err != nil {
return fmt.Errorf("Failed to generate containerd options: %v", err)
}
containerdRemote, err := libcontainerd.New(filepath.Join(cli.Config.Root, "containerd"), filepath.Join(cli.Config.ExecRoot, "containerd"), rOpts...)
if err != nil {
return err
r, err := supervisor.Start(ctx, filepath.Join(cli.Config.Root, "containerd"), filepath.Join(cli.Config.ExecRoot, "containerd"), opts...)
if err != nil {
cancel()
return fmt.Errorf("Failed to start containerd: %v", err)
}

cli.Config.ContainerdAddr = r.Address()

// Try to wait for containerd to shutdown
defer r.WaitTimeout(10 * time.Second)
}
defer cancel()

signal.Trap(func() {
cli.stop()
<-stopc // wait for daemonCli.start() to return
Expand All @@ -162,7 +173,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
logrus.Fatalf("Error creating middlewares: %v", err)
}

d, err := daemon.NewDaemon(cli.Config, registryService, containerdRemote, pluginStore)
d, err := daemon.NewDaemon(ctx, cli.Config, pluginStore)
if err != nil {
return fmt.Errorf("Error starting daemon: %v", err)
}
Expand Down Expand Up @@ -207,10 +218,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {

initRouter(routerOptions)

// process cluster change notifications
watchCtx, cancel := context.WithCancel(context.Background())
defer cancel()
go d.ProcessClusterNotifications(watchCtx, c.GetWatchStream())
go d.ProcessClusterNotifications(ctx, c.GetWatchStream())

cli.setupConfigReloadTrap()

Expand All @@ -227,8 +235,12 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
// Wait for serve API to complete
errAPI := <-serveAPIWait
c.Cleanup()

shutdownDaemon(d)
containerdRemote.Cleanup()

// Stop notification processing and any background processes
cancel()

if errAPI != nil {
return fmt.Errorf("Shutting down due to ServeAPI error: %v", errAPI)
}
Expand Down Expand Up @@ -511,14 +523,22 @@ func (cli *DaemonCli) initMiddlewares(s *apiserver.Server, cfg *apiserver.Config
return nil
}

func (cli *DaemonCli) getRemoteOptions() ([]libcontainerd.RemoteOption, error) {
opts := []libcontainerd.RemoteOption{}

pOpts, err := cli.getPlatformRemoteOptions()
func (cli *DaemonCli) getContainerdDaemonOpts() ([]supervisor.DaemonOpt, error) {
opts, err := cli.getPlatformContainerdDaemonOpts()
if err != nil {
return nil, err
}
opts = append(opts, pOpts...)

if cli.Config.Debug {
opts = append(opts, supervisor.WithLogLevel("debug"))
} else if cli.Config.LogLevel != "" {
opts = append(opts, supervisor.WithLogLevel(cli.Config.LogLevel))
}

if !cli.Config.CriContainerd {
opts = append(opts, supervisor.WithPlugin("cri", nil))
}

return opts, nil
}

Expand Down
23 changes: 5 additions & 18 deletions cmd/dockerd/daemon_unix.go
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/containerd/containerd/runtime/linux"
"github.com/docker/docker/cmd/dockerd/hack"
"github.com/docker/docker/daemon"
"github.com/docker/docker/libcontainerd"
"github.com/docker/docker/libcontainerd/supervisor"
"github.com/docker/libnetwork/portallocator"
"golang.org/x/sys/unix"
)
Expand All @@ -36,29 +36,16 @@ func getDaemonConfDir(_ string) string {
return "/etc/docker"
}

func (cli *DaemonCli) getPlatformRemoteOptions() ([]libcontainerd.RemoteOption, error) {
opts := []libcontainerd.RemoteOption{
libcontainerd.WithOOMScore(cli.Config.OOMScoreAdjust),
libcontainerd.WithPlugin("linux", &linux.Config{
func (cli *DaemonCli) getPlatformContainerdDaemonOpts() ([]supervisor.DaemonOpt, error) {
opts := []supervisor.DaemonOpt{
supervisor.WithOOMScore(cli.Config.OOMScoreAdjust),
supervisor.WithPlugin("linux", &linux.Config{
Shim: daemon.DefaultShimBinary,
Runtime: daemon.DefaultRuntimeBinary,
RuntimeRoot: filepath.Join(cli.Config.Root, "runc"),
ShimDebug: cli.Config.Debug,
}),
}
if cli.Config.Debug {
opts = append(opts, libcontainerd.WithLogLevel("debug"))
} else if cli.Config.LogLevel != "" {
opts = append(opts, libcontainerd.WithLogLevel(cli.Config.LogLevel))
}
if cli.Config.ContainerdAddr != "" {
opts = append(opts, libcontainerd.WithRemoteAddr(cli.Config.ContainerdAddr))
} else {
opts = append(opts, libcontainerd.WithStartDaemon(true))
}
if !cli.Config.CriContainerd {
opts = append(opts, libcontainerd.WithPlugin("cri", nil))
}

return opts, nil
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/dockerd/daemon_windows.go
Expand Up @@ -6,7 +6,7 @@ import (
"os"
"path/filepath"

"github.com/docker/docker/libcontainerd"
"github.com/docker/docker/libcontainerd/supervisor"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows"
)
Expand Down Expand Up @@ -48,7 +48,7 @@ func notifyShutdown(err error) {
}
}

func (cli *DaemonCli) getPlatformRemoteOptions() ([]libcontainerd.RemoteOption, error) {
func (cli *DaemonCli) getPlatformContainerdDaemonOpts() ([]supervisor.DaemonOpt, error) {
return nil, nil
}

Expand Down
48 changes: 45 additions & 3 deletions daemon/daemon.go
Expand Up @@ -18,6 +18,11 @@ import (
"sync"
"time"

"google.golang.org/grpc"

"github.com/containerd/containerd"
"github.com/containerd/containerd/defaults"
"github.com/containerd/containerd/pkg/dialer"
"github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/swarm"
Expand Down Expand Up @@ -94,6 +99,7 @@ type Daemon struct {
PluginStore *plugin.Store // todo: remove
pluginManager *plugin.Manager
linkIndex *linkIndex
containerdCli *containerd.Client
containerd libcontainerd.Client
defaultIsolation containertypes.Isolation // Default isolation mode on Windows
clusterProvider cluster.Provider
Expand Down Expand Up @@ -565,9 +571,14 @@ func (daemon *Daemon) IsSwarmCompatible() error {

// NewDaemon sets up everything for the daemon to be able to service
// requests from the webserver.
func NewDaemon(config *config.Config, registryService registry.Service, containerdRemote libcontainerd.Remote, pluginStore *plugin.Store) (daemon *Daemon, err error) {
func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.Store) (daemon *Daemon, err error) {
setDefaultMtu(config)

registryService, err := registry.NewService(config.ServiceOptions)
if err != nil {
return nil, err
}

// Ensure that we have a correct root key limit for launching containers.
if err := ModifyRootKeyLimit(); err != nil {
logrus.Warnf("unable to modify root key limit, number of containers could be limited by this quota: %v", err)
Expand Down Expand Up @@ -720,8 +731,35 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
}
registerMetricsPluginCallback(d.PluginStore, metricsSockPath)

gopts := []grpc.DialOption{
grpc.WithInsecure(),
grpc.WithBackoffMaxDelay(3 * time.Second),
grpc.WithDialer(dialer.Dialer),

// TODO(stevvooe): We may need to allow configuration of this on the client.
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)),
}
if config.ContainerdAddr != "" {
d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(ContainersNamespace), containerd.WithDialOpts(gopts))
if err != nil {
return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr)
}
}

createPluginExec := func(m *plugin.Manager) (plugin.Executor, error) {
return pluginexec.New(getPluginExecRoot(config.Root), containerdRemote, m)
var pluginCli *containerd.Client

// Windows is not currently using containerd, keep the
// client as nil
if config.ContainerdAddr != "" {
pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(pluginexec.PluginNamespace), containerd.WithDialOpts(gopts))
if err != nil {
return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr)
}
}

return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, m)
}

// Plugin system initialization should happen before restore. Do not change order.
Expand Down Expand Up @@ -880,7 +918,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe

go d.execCommandGC()

d.containerd, err = containerdRemote.NewClient(ContainersNamespace, d)
d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), ContainersNamespace, d)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1037,6 +1075,10 @@ func (daemon *Daemon) Shutdown() error {
daemon.netController.Stop()
}

if daemon.containerdCli != nil {
daemon.containerdCli.Close()
}

return daemon.cleanupMounts()
}

Expand Down

0 comments on commit 4d62192

Please sign in to comment.