daemon: make the snapshotter configurable
Treat (storage/graph)Driver as snapshotter Also moved some layerStore related initialization to the non-c8d case because otherwise they get treated as a graphdriver plugins. Co-authored-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Djordje Lukic <djordje.lukic@docker.com> Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
464882e398
commit
d8d990f2e3
|
@ -53,7 +53,7 @@ func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outSt
|
||||||
for _, img := range imgs {
|
for _, img := range imgs {
|
||||||
platformImg := containerd.NewImageWithPlatform(i.client, img, platform)
|
platformImg := containerd.NewImageWithPlatform(i.client, img, platform)
|
||||||
|
|
||||||
unpacked, err := platformImg.IsUnpacked(ctx, containerd.DefaultSnapshotter)
|
unpacked, err := platformImg.IsUnpacked(ctx, i.snapshotter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
|
// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
|
||||||
logrus.WithError(err).WithField("image", img.Name).Debug("failed to check if image is unpacked")
|
logrus.WithError(err).WithField("image", img.Name).Debug("failed to check if image is unpacked")
|
||||||
|
@ -61,7 +61,7 @@ func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outSt
|
||||||
}
|
}
|
||||||
|
|
||||||
if !unpacked {
|
if !unpacked {
|
||||||
err := platformImg.Unpack(ctx, containerd.DefaultSnapshotter)
|
err := platformImg.Unpack(ctx, i.snapshotter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
|
// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
|
||||||
logrus.WithError(err).WithField("image", img.Name).Warn("failed to unpack image")
|
logrus.WithError(err).WithField("image", img.Name).Warn("failed to unpack image")
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotter := i.client.SnapshotService(containerd.DefaultSnapshotter)
|
snapshotter := i.client.SnapshotService(i.snapshotter)
|
||||||
sizeCache := make(map[digest.Digest]int64)
|
sizeCache := make(map[digest.Digest]int64)
|
||||||
snapshotSizeFn := func(d digest.Digest) (int64, error) {
|
snapshotSizeFn := func(d digest.Digest) (int64, error) {
|
||||||
if s, ok := sizeCache[d]; ok {
|
if s, ok := sizeCache[d]; ok {
|
||||||
|
|
|
@ -13,13 +13,15 @@ import (
|
||||||
|
|
||||||
// ImageService implements daemon.ImageService
|
// ImageService implements daemon.ImageService
|
||||||
type ImageService struct {
|
type ImageService struct {
|
||||||
client *containerd.Client
|
client *containerd.Client
|
||||||
|
snapshotter string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService creates a new ImageService.
|
// NewService creates a new ImageService.
|
||||||
func NewService(c *containerd.Client) *ImageService {
|
func NewService(c *containerd.Client, snapshotter string) *ImageService {
|
||||||
return &ImageService{
|
return &ImageService{
|
||||||
client: c,
|
client: c,
|
||||||
|
snapshotter: snapshotter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ func (i *ImageService) Cleanup() error {
|
||||||
// StorageDriver returns the name of the default storage-driver (snapshotter)
|
// StorageDriver returns the name of the default storage-driver (snapshotter)
|
||||||
// used by the ImageService.
|
// used by the ImageService.
|
||||||
func (i *ImageService) StorageDriver() string {
|
func (i *ImageService) StorageDriver() string {
|
||||||
return ""
|
return i.snapshotter
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReleaseLayer releases a layer allowing it to be removed
|
// ReleaseLayer releases a layer allowing it to be removed
|
||||||
|
|
113
daemon/daemon.go
113
daemon/daemon.go
|
@ -833,22 +833,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var graphDriver string
|
|
||||||
if isWindows {
|
|
||||||
// On Windows we don't support the environment variable, or a user supplied graphdriver
|
|
||||||
graphDriver = "windowsfilter"
|
|
||||||
} else {
|
|
||||||
// Unix platforms however run a single graphdriver for all containers, and it can
|
|
||||||
// be set through an environment variable, a daemon start parameter, or chosen through
|
|
||||||
// initialization of the layerstore through driver priority order for example.
|
|
||||||
if drv := os.Getenv("DOCKER_DRIVER"); drv != "" {
|
|
||||||
graphDriver = drv
|
|
||||||
logrus.Infof("Setting the storage driver from the $DOCKER_DRIVER environment variable (%s)", drv)
|
|
||||||
} else {
|
|
||||||
graphDriver = config.GraphDriver // May still be empty. Layerstore init determines instead.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d.registryService = registryService
|
d.registryService = registryService
|
||||||
logger.RegisterPluginGetter(d.PluginStore)
|
logger.RegisterPluginGetter(d.PluginStore)
|
||||||
|
|
||||||
|
@ -938,27 +922,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
layerStore, err := layer.NewStoreFromOptions(layer.StoreOptions{
|
|
||||||
Root: config.Root,
|
|
||||||
MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"),
|
|
||||||
GraphDriver: graphDriver,
|
|
||||||
GraphDriverOptions: config.GraphOptions,
|
|
||||||
IDMapping: idMapping,
|
|
||||||
PluginGetter: d.PluginStore,
|
|
||||||
ExperimentalEnabled: config.Experimental,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure and validate the kernels security support. Note this is a Linux/FreeBSD
|
|
||||||
// operation only, so it is safe to pass *just* the runtime OS graphdriver.
|
|
||||||
if err := configureKernelSecuritySupport(config, layerStore.DriverName()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
imageRoot := filepath.Join(config.Root, "image", layerStore.DriverName())
|
|
||||||
|
|
||||||
d.volumes, err = volumesservice.NewVolumeService(config.Root, d.PluginStore, rootIDs, d)
|
d.volumes, err = volumesservice.NewVolumeService(config.Root, d.PluginStore, rootIDs, d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -972,23 +935,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
||||||
logrus.WithError(err).Warnf("unable to migrate engine ID; a new engine ID will be generated")
|
logrus.WithError(err).Warnf("unable to migrate engine ID; a new engine ID will be generated")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a single tag/reference store for the daemon globally. However, it's
|
|
||||||
// stored under the graphdriver. On host platforms which only support a single
|
|
||||||
// container OS, but multiple selectable graphdrivers, this means depending on which
|
|
||||||
// graphdriver is chosen, the global reference store is under there. For
|
|
||||||
// platforms which support multiple container operating systems, this is slightly
|
|
||||||
// more problematic as where does the global ref store get located? Fortunately,
|
|
||||||
// for Windows, which is currently the only daemon supporting multiple container
|
|
||||||
// operating systems, the list of graphdrivers available isn't user configurable.
|
|
||||||
// For backwards compatibility, we just put it under the windowsfilter
|
|
||||||
// directory regardless.
|
|
||||||
refStoreLocation := filepath.Join(imageRoot, `repositories.json`)
|
|
||||||
rs, err := refstore.NewReferenceStore(refStoreLocation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Couldn't create reference store repository: %s", err)
|
|
||||||
}
|
|
||||||
d.ReferenceStore = rs
|
|
||||||
|
|
||||||
// Check if Devices cgroup is mounted, it is hard requirement for container security,
|
// Check if Devices cgroup is mounted, it is hard requirement for container security,
|
||||||
// on Linux.
|
// on Linux.
|
||||||
//
|
//
|
||||||
|
@ -1019,14 +965,69 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
||||||
|
|
||||||
d.linkIndex = newLinkIndex()
|
d.linkIndex = newLinkIndex()
|
||||||
|
|
||||||
if d.UsesSnapshotter() {
|
// On Windows we don't support the environment variable, or a user supplied graphdriver
|
||||||
d.imageService = ctrd.NewService(d.containerdCli)
|
// Unix platforms however run a single graphdriver for all containers, and it can
|
||||||
|
// be set through an environment variable, a daemon start parameter, or chosen through
|
||||||
|
// initialization of the layerstore through driver priority order for example.
|
||||||
|
driverName := os.Getenv("DOCKER_DRIVER")
|
||||||
|
if isWindows {
|
||||||
|
driverName = "windowsfilter"
|
||||||
|
} else if driverName != "" {
|
||||||
|
logrus.Infof("Setting the storage driver from the $DOCKER_DRIVER environment variable (%s)", driverName)
|
||||||
} else {
|
} else {
|
||||||
|
driverName = config.GraphDriver
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.UsesSnapshotter() {
|
||||||
|
// Configure and validate the kernels security support. Note this is a Linux/FreeBSD
|
||||||
|
// operation only, so it is safe to pass *just* the runtime OS graphdriver.
|
||||||
|
if err := configureKernelSecuritySupport(config, driverName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
d.imageService = ctrd.NewService(d.containerdCli, driverName)
|
||||||
|
} else {
|
||||||
|
layerStore, err := layer.NewStoreFromOptions(layer.StoreOptions{
|
||||||
|
Root: config.Root,
|
||||||
|
MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"),
|
||||||
|
GraphDriver: driverName,
|
||||||
|
GraphDriverOptions: config.GraphOptions,
|
||||||
|
IDMapping: idMapping,
|
||||||
|
PluginGetter: d.PluginStore,
|
||||||
|
ExperimentalEnabled: config.Experimental,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure and validate the kernels security support. Note this is a Linux/FreeBSD
|
||||||
|
// operation only, so it is safe to pass *just* the runtime OS graphdriver.
|
||||||
|
if err := configureKernelSecuritySupport(config, layerStore.DriverName()); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
imageRoot := filepath.Join(config.Root, "image", layerStore.DriverName())
|
||||||
ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))
|
ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We have a single tag/reference store for the daemon globally. However, it's
|
||||||
|
// stored under the graphdriver. On host platforms which only support a single
|
||||||
|
// container OS, but multiple selectable graphdrivers, this means depending on which
|
||||||
|
// graphdriver is chosen, the global reference store is under there. For
|
||||||
|
// platforms which support multiple container operating systems, this is slightly
|
||||||
|
// more problematic as where does the global ref store get located? Fortunately,
|
||||||
|
// for Windows, which is currently the only daemon supporting multiple container
|
||||||
|
// operating systems, the list of graphdrivers available isn't user configurable.
|
||||||
|
// For backwards compatibility, we just put it under the windowsfilter
|
||||||
|
// directory regardless.
|
||||||
|
refStoreLocation := filepath.Join(imageRoot, `repositories.json`)
|
||||||
|
rs, err := refstore.NewReferenceStore(refStoreLocation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Couldn't create reference store repository: %s", err)
|
||||||
|
}
|
||||||
|
d.ReferenceStore = rs
|
||||||
|
|
||||||
imageStore, err := image.NewImageStore(ifs, layerStore)
|
imageStore, err := image.NewImageStore(ifs, layerStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -822,7 +822,7 @@ func configureKernelSecuritySupport(config *config.Config, driverName string) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if driverName == "overlay" || driverName == "overlay2" {
|
if driverName == "overlay" || driverName == "overlay2" || driverName == "overlayfs" {
|
||||||
// If driver is overlay or overlay2, make sure kernel
|
// If driver is overlay or overlay2, make sure kernel
|
||||||
// supports selinux with overlay.
|
// supports selinux with overlay.
|
||||||
supported, err := overlaySupportsSelinux()
|
supported, err := overlaySupportsSelinux()
|
||||||
|
|
|
@ -1045,8 +1045,17 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e
|
||||||
if daemon.configStore.Rootless {
|
if daemon.configStore.Rootless {
|
||||||
opts = append(opts, WithRootless(daemon))
|
opts = append(opts, WithRootless(daemon))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var snapshotter, snapshotKey string
|
||||||
|
if daemon.UsesSnapshotter() {
|
||||||
|
snapshotter = daemon.imageService.StorageDriver()
|
||||||
|
snapshotKey = c.ID
|
||||||
|
}
|
||||||
|
|
||||||
return &s, coci.ApplyOpts(context.Background(), nil, &containers.Container{
|
return &s, coci.ApplyOpts(context.Background(), nil, &containers.Container{
|
||||||
ID: c.ID,
|
ID: c.ID,
|
||||||
|
Snapshotter: snapshotter,
|
||||||
|
SnapshotKey: snapshotKey,
|
||||||
}, &s, opts...)
|
}, &s, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue