Merge pull request #4643 from dcantah/feedback-lcow-snapshotter

Optimize Windows and LCOW snapshotters to only create scratch layer on the final snapshot
This commit is contained in:
Michael Crosby 2020-12-01 10:38:02 -05:00 committed by GitHub
commit b9092fae15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 56 deletions

View File

@ -123,7 +123,7 @@ func applyLayers(ctx context.Context, layers []Layer, chain []digest.Digest, sn
)
for {
key = fmt.Sprintf("extract-%s %s", uniquePart(), chainID)
key = fmt.Sprintf(snapshots.UnpackKeyFormat, uniquePart(), chainID)
// Prepare snapshot with from parent, label as root
mounts, err = sn.Prepare(ctx, key, parent.String(), opts...)

View File

@ -330,12 +330,22 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
for _, o := range opts {
o(&snapshotInfo)
}
// IO/disk space optimization
//
// We only need one sandbox.vhd for the container. Skip making one for this
// snapshot if this isn't the snapshot that just houses the final sandbox.vhd
// that will be mounted as the containers scratch. Currently the key for a snapshot
// where a layer.vhd will be extracted to it will have the string `extract-` in it.
// If this is changed this will also need to be changed.
//
// We save about 17MB per layer (if the default scratch vhd size of 20GB is used) and of
// course the time to copy the vhd per snapshot.
if !strings.Contains(key, snapshots.UnpackKeyPrefix) {
var sizeGB int
if sizeGBstr, ok := snapshotInfo.Labels[rootfsSizeLabel]; ok {
i32, err := strconv.ParseInt(sizeGBstr, 10, 32)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse annotation %q=%q", rootfsSizeLabel, sizeGBstr)
return nil, errors.Wrapf(err, "failed to parse label %q=%q", rootfsSizeLabel, sizeGBstr)
}
sizeGB = int(i32)
}
@ -346,10 +356,6 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
}
defer scratchSource.Close()
// TODO: JTERRY75 - This has to be called sandbox.vhdx for the time
// being but it really is the scratch.vhdx. Using this naming convention
// for now but this is not the kubernetes sandbox.
//
// Create the sandbox.vhdx for this snapshot from the cache.
destPath := filepath.Join(snDir, "sandbox.vhdx")
dest, err := os.OpenFile(destPath, os.O_RDWR|os.O_CREATE, 0700)
@ -363,6 +369,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
return nil, errors.Wrap(err, "failed to copy cached scratch.vhdx to sandbox.vhdx in snapshot")
}
}
}
if err := t.Commit(); err != nil {
return nil, errors.Wrap(err, "commit failed")

View File

@ -26,6 +26,10 @@ import (
)
const (
// UnpackKeyPrefix is the beginning of the key format used for snapshots that will have
// image content unpacked into them.
UnpackKeyPrefix = "extract"
UnpackKeyFormat = UnpackKeyPrefix + "-%s %s"
inheritedLabelsPrefix = "containerd.io/snapshot/"
labelSnapshotRef = "containerd.io/snapshot.ref"
)

View File

@ -326,6 +326,20 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
}
if kind == snapshots.KindActive {
log.G(ctx).Debug("createSnapshot active")
// Create the new snapshot dir
snDir := s.getSnapshotDir(newSnapshot.ID)
if err := os.MkdirAll(snDir, 0700); err != nil {
return nil, err
}
// IO/disk space optimization
//
// We only need one sandbox.vhdx for the container. Skip making one for this
// snapshot if this isn't the snapshot that just houses the final sandbox.vhd
// that will be mounted as the containers scratch. Currently the key for a snapshot
// where a layer will be extracted to will have the string `extract-` in it.
if !strings.Contains(key, snapshots.UnpackKeyPrefix) {
parentLayerPaths := s.parentIDsToParentPaths(newSnapshot.ParentIDs)
var parentPath string
@ -346,7 +360,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
if sizeGBstr, ok := snapshotInfo.Labels[rootfsSizeLabel]; ok {
i32, err := strconv.ParseInt(sizeGBstr, 10, 32)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse annotation %q=%q", rootfsSizeLabel, sizeGBstr)
return nil, errors.Wrapf(err, "failed to parse label %q=%q", rootfsSizeLabel, sizeGBstr)
}
sizeGB = int(i32)
}
@ -358,6 +372,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
}
}
}
}
if err := t.Commit(); err != nil {
return nil, errors.Wrap(err, "commit failed")

View File

@ -138,7 +138,7 @@ EachLayer:
for try := 1; try <= 3; try++ {
// Prepare snapshot with from parent, label as root
key = fmt.Sprintf("extract-%s %s", uniquePart(), chainID)
key = fmt.Sprintf(snapshots.UnpackKeyFormat, uniquePart(), chainID)
mounts, err = sn.Prepare(ctx, key, parent.String(), opts...)
if err != nil {
if errdefs.IsAlreadyExists(err) {