зеркало из https://github.com/microsoft/docker.git
Merge pull request #19123 from shishir-a412ed/rootfs_size_configurable
daemon option (--storage-opt dm.basesize) for increasing the base device size on daemon restart
This commit is contained in:
Коммит
661d75f398
|
@ -35,7 +35,7 @@ import (
|
|||
var (
|
||||
defaultDataLoopbackSize int64 = 100 * 1024 * 1024 * 1024
|
||||
defaultMetaDataLoopbackSize int64 = 2 * 1024 * 1024 * 1024
|
||||
defaultBaseFsSize uint64 = 100 * 1024 * 1024 * 1024
|
||||
defaultBaseFsSize uint64 = 10 * 1024 * 1024 * 1024
|
||||
defaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors
|
||||
defaultUdevSyncOverride = false
|
||||
maxDeviceID = 0xffffff // 24 bit, pool limit
|
||||
|
@ -47,6 +47,7 @@ var (
|
|||
driverDeferredRemovalSupport = false
|
||||
enableDeferredRemoval = false
|
||||
enableDeferredDeletion = false
|
||||
userBaseSize = false
|
||||
)
|
||||
|
||||
const deviceSetMetaFile string = "deviceset-metadata"
|
||||
|
@ -1056,6 +1057,80 @@ func (devices *DeviceSet) setupVerifyBaseImageUUIDFS(baseInfo *devInfo) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (devices *DeviceSet) checkGrowBaseDeviceFS(info *devInfo) error {
|
||||
|
||||
if !userBaseSize {
|
||||
return nil
|
||||
}
|
||||
|
||||
if devices.baseFsSize < devices.getBaseDeviceSize() {
|
||||
return fmt.Errorf("devmapper: Base device size cannot be smaller than %s", units.HumanSize(float64(devices.getBaseDeviceSize())))
|
||||
}
|
||||
|
||||
if devices.baseFsSize == devices.getBaseDeviceSize() {
|
||||
return nil
|
||||
}
|
||||
|
||||
info.lock.Lock()
|
||||
defer info.lock.Unlock()
|
||||
|
||||
devices.Lock()
|
||||
defer devices.Unlock()
|
||||
|
||||
info.Size = devices.baseFsSize
|
||||
|
||||
if err := devices.saveMetadata(info); err != nil {
|
||||
// Try to remove unused device
|
||||
delete(devices.Devices, info.Hash)
|
||||
return err
|
||||
}
|
||||
|
||||
return devices.growFS(info)
|
||||
}
|
||||
|
||||
func (devices *DeviceSet) growFS(info *devInfo) error {
|
||||
if err := devices.activateDeviceIfNeeded(info, false); err != nil {
|
||||
return fmt.Errorf("Error activating devmapper device: %s", err)
|
||||
}
|
||||
|
||||
defer devices.deactivateDevice(info)
|
||||
|
||||
fsMountPoint := "/run/docker/mnt"
|
||||
if _, err := os.Stat(fsMountPoint); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(fsMountPoint, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(fsMountPoint)
|
||||
}
|
||||
|
||||
options := ""
|
||||
if devices.BaseDeviceFilesystem == "xfs" {
|
||||
// XFS needs nouuid or it can't mount filesystems with the same fs
|
||||
options = joinMountOptions(options, "nouuid")
|
||||
}
|
||||
options = joinMountOptions(options, devices.mountOptions)
|
||||
|
||||
if err := mount.Mount(info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options); err != nil {
|
||||
return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), fsMountPoint, err)
|
||||
}
|
||||
|
||||
defer syscall.Unmount(fsMountPoint, syscall.MNT_DETACH)
|
||||
|
||||
switch devices.BaseDeviceFilesystem {
|
||||
case "ext4":
|
||||
if out, err := exec.Command("resize2fs", info.DevName()).CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Failed to grow rootfs:%v:%s", err, string(out))
|
||||
}
|
||||
case "xfs":
|
||||
if out, err := exec.Command("xfs_growfs", info.DevName()).CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Failed to grow rootfs:%v:%s", err, string(out))
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Unsupported filesystem type %s", devices.BaseDeviceFilesystem)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (devices *DeviceSet) setupBaseImage() error {
|
||||
oldInfo, _ := devices.lookupDeviceWithLock("")
|
||||
|
||||
|
@ -1069,9 +1144,8 @@ func (devices *DeviceSet) setupBaseImage() error {
|
|||
return err
|
||||
}
|
||||
|
||||
if devices.baseFsSize != defaultBaseFsSize && devices.baseFsSize != devices.getBaseDeviceSize() {
|
||||
logrus.Warnf("devmapper: Base device is already initialized to size %s, new value of base device size %s will not take effect",
|
||||
units.HumanSize(float64(devices.getBaseDeviceSize())), units.HumanSize(float64(devices.baseFsSize)))
|
||||
if err := devices.checkGrowBaseDeviceFS(oldInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -2378,6 +2452,7 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userBaseSize = true
|
||||
devices.baseFsSize = uint64(size)
|
||||
case "dm.loopdatasize":
|
||||
size, err := units.RAMInBytes(val)
|
||||
|
|
|
@ -213,11 +213,23 @@ options for `zfs` start with `zfs`.
|
|||
* `dm.basesize`
|
||||
|
||||
Specifies the size to use when creating the base device, which limits the
|
||||
size of images and containers. The default value is 100G. Note, thin devices
|
||||
are inherently "sparse", so a 100G device which is mostly empty doesn't use
|
||||
100 GB of space on the pool. However, the filesystem will use more space for
|
||||
size of images and containers. The default value is 10G. Note, thin devices
|
||||
are inherently "sparse", so a 10G device which is mostly empty doesn't use
|
||||
10 GB of space on the pool. However, the filesystem will use more space for
|
||||
the empty case the larger the device is.
|
||||
|
||||
The base device size can be increased at daemon restart which will allow
|
||||
all future images and containers (based on those new images) to be of the
|
||||
new base device size.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker daemon --storage-opt dm.basesize=50G
|
||||
|
||||
This will increase the base device size to 50G. The Docker daemon will throw an
|
||||
error if existing base device size is larger than 50G. A user can use
|
||||
this option to expand the base device size however shrinking is not permitted.
|
||||
|
||||
This value affects the system-wide "base" empty filesystem
|
||||
that may already be initialized and inherited by pulled images. Typically,
|
||||
a change to this value requires additional steps to take effect:
|
||||
|
|
|
@ -249,11 +249,11 @@ You can use the `lsblk` command to see the device files created above and the `p
|
|||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||
xvda 202:0 0 8G 0 disk
|
||||
└─xvda1 202:1 0 8G 0 part /
|
||||
xvdf 202:80 0 100G 0 disk
|
||||
xvdf 202:80 0 10G 0 disk
|
||||
├─vg--docker-data 253:0 0 90G 0 lvm
|
||||
│ └─docker-202:1-1032-pool 253:2 0 100G 0 dm
|
||||
│ └─docker-202:1-1032-pool 253:2 0 10G 0 dm
|
||||
└─vg--docker-metadata 253:1 0 4G 0 lvm
|
||||
└─docker-202:1-1032-pool 253:2 0 100G 0 dm
|
||||
└─docker-202:1-1032-pool 253:2 0 10G 0 dm
|
||||
|
||||
The diagram below shows the image from prior examples updated with the detail from the `lsblk` command above.
|
||||
|
||||
|
|
|
@ -271,12 +271,22 @@ Example use: `docker daemon --storage-opt dm.thinpooldev=/dev/mapper/thin-pool`
|
|||
#### dm.basesize
|
||||
|
||||
Specifies the size to use when creating the base device, which limits
|
||||
the size of images and containers. The default value is 100G. Note,
|
||||
thin devices are inherently "sparse", so a 100G device which is mostly
|
||||
empty doesn't use 100 GB of space on the pool. However, the filesystem
|
||||
the size of images and containers. The default value is 10G. Note,
|
||||
thin devices are inherently "sparse", so a 10G device which is mostly
|
||||
empty doesn't use 10 GB of space on the pool. However, the filesystem
|
||||
will use more space for base images the larger the device
|
||||
is.
|
||||
|
||||
The base device size can be increased at daemon restart which will allow
|
||||
all future images and containers (based on those new images) to be of the
|
||||
new base device size.
|
||||
|
||||
Example use: `docker daemon --storage-opt dm.basesize=50G`
|
||||
|
||||
This will increase the base device size to 50G. The Docker daemon will throw an
|
||||
error if existing base device size is larger than 50G. A user can use
|
||||
this option to expand the base device size however shrinking is not permitted.
|
||||
|
||||
This value affects the system-wide "base" empty filesystem that may already
|
||||
be initialized and inherited by pulled images. Typically, a change to this
|
||||
value requires additional steps to take effect:
|
||||
|
|
Загрузка…
Ссылка в новой задаче