mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
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:
commit
661d75f398
4 changed files with 110 additions and 13 deletions
|
@ -35,7 +35,7 @@ import (
|
||||||
var (
|
var (
|
||||||
defaultDataLoopbackSize int64 = 100 * 1024 * 1024 * 1024
|
defaultDataLoopbackSize int64 = 100 * 1024 * 1024 * 1024
|
||||||
defaultMetaDataLoopbackSize int64 = 2 * 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
|
defaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors
|
||||||
defaultUdevSyncOverride = false
|
defaultUdevSyncOverride = false
|
||||||
maxDeviceID = 0xffffff // 24 bit, pool limit
|
maxDeviceID = 0xffffff // 24 bit, pool limit
|
||||||
|
@ -47,6 +47,7 @@ var (
|
||||||
driverDeferredRemovalSupport = false
|
driverDeferredRemovalSupport = false
|
||||||
enableDeferredRemoval = false
|
enableDeferredRemoval = false
|
||||||
enableDeferredDeletion = false
|
enableDeferredDeletion = false
|
||||||
|
userBaseSize = false
|
||||||
)
|
)
|
||||||
|
|
||||||
const deviceSetMetaFile string = "deviceset-metadata"
|
const deviceSetMetaFile string = "deviceset-metadata"
|
||||||
|
@ -1056,6 +1057,80 @@ func (devices *DeviceSet) setupVerifyBaseImageUUIDFS(baseInfo *devInfo) error {
|
||||||
return nil
|
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 {
|
func (devices *DeviceSet) setupBaseImage() error {
|
||||||
oldInfo, _ := devices.lookupDeviceWithLock("")
|
oldInfo, _ := devices.lookupDeviceWithLock("")
|
||||||
|
|
||||||
|
@ -1069,9 +1144,8 @@ func (devices *DeviceSet) setupBaseImage() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if devices.baseFsSize != defaultBaseFsSize && devices.baseFsSize != devices.getBaseDeviceSize() {
|
if err := devices.checkGrowBaseDeviceFS(oldInfo); err != nil {
|
||||||
logrus.Warnf("devmapper: Base device is already initialized to size %s, new value of base device size %s will not take effect",
|
return err
|
||||||
units.HumanSize(float64(devices.getBaseDeviceSize())), units.HumanSize(float64(devices.baseFsSize)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -2378,6 +2452,7 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
userBaseSize = true
|
||||||
devices.baseFsSize = uint64(size)
|
devices.baseFsSize = uint64(size)
|
||||||
case "dm.loopdatasize":
|
case "dm.loopdatasize":
|
||||||
size, err := units.RAMInBytes(val)
|
size, err := units.RAMInBytes(val)
|
||||||
|
|
|
@ -213,11 +213,23 @@ options for `zfs` start with `zfs`.
|
||||||
* `dm.basesize`
|
* `dm.basesize`
|
||||||
|
|
||||||
Specifies the size to use when creating the base device, which limits the
|
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
|
size of images and containers. The default value is 10G. Note, thin devices
|
||||||
are inherently "sparse", so a 100G device which is mostly empty doesn't use
|
are inherently "sparse", so a 10G device which is mostly empty doesn't use
|
||||||
100 GB of space on the pool. However, the filesystem will use more space for
|
10 GB of space on the pool. However, the filesystem will use more space for
|
||||||
the empty case the larger the device is.
|
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
|
This value affects the system-wide "base" empty filesystem
|
||||||
that may already be initialized and inherited by pulled images. Typically,
|
that may already be initialized and inherited by pulled images. Typically,
|
||||||
a change to this value requires additional steps to take effect:
|
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
|
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
||||||
xvda 202:0 0 8G 0 disk
|
xvda 202:0 0 8G 0 disk
|
||||||
└─xvda1 202:1 0 8G 0 part /
|
└─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
|
├─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
|
└─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.
|
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
|
#### dm.basesize
|
||||||
|
|
||||||
Specifies the size to use when creating the base device, which limits
|
Specifies the size to use when creating the base device, which limits
|
||||||
the size of images and containers. The default value is 100G. Note,
|
the size of images and containers. The default value is 10G. Note,
|
||||||
thin devices are inherently "sparse", so a 100G device which is mostly
|
thin devices are inherently "sparse", so a 10G device which is mostly
|
||||||
empty doesn't use 100 GB of space on the pool. However, the filesystem
|
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
|
will use more space for base images the larger the device
|
||||||
is.
|
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
|
This value affects the system-wide "base" empty filesystem that may already
|
||||||
be initialized and inherited by pulled images. Typically, a change to this
|
be initialized and inherited by pulled images. Typically, a change to this
|
||||||
value requires additional steps to take effect:
|
value requires additional steps to take effect:
|
||||||
|
|
Loading…
Reference in a new issue