daemon/daemon.go Daemon: containerd libcontainerdtypes.Client
是和containerd交互的client
daemon/start.go
func (daemon *Daemon) containerStart
err = daemon.containerd.Create(ctx, container.ID, spec, createOptions, withImageName(imageRef.String()))if err != nil {if errdefs.IsConflict(err) {logrus.WithError(err).WithField("container", container.ID).Error("Container not cleaned up from containerd from previous run")// best effort to clean up old container objectdaemon.containerd.DeleteTask(ctx, container.ID)if err := daemon.containerd.Delete(ctx, container.ID); err != nil && !errdefs.IsNotFound(err) {logrus.WithError(err).WithField("container", container.ID).Error("Error cleaning up stale containerd container object")}err = daemon.containerd.Create(ctx, container.ID, spec, createOptions, withImageName(imageRef.String()))}if err != nil {return translateContainerdStartErr(container.Path, container.SetExitCode, err)}}// TODO(mlaventure): we need to specify checkpoint options herepid, err := daemon.containerd.Start(context.Background(), container.ID, checkpointDir,container.StreamConfig.Stdin() != nil || container.Config.Tty,container.InitializeStdio)if err != nil {if err := daemon.containerd.Delete(context.Background(), container.ID); err != nil {logrus.WithError(err).WithField("container", container.ID).Error("failed to delete failed start container")}return translateContainerdStartErr(container.Path, container.SetExitCode, err)}
对于docker run这个命令:
实际执行的是 create + start
