将Docker的/var/lib/docker目录移动

由于现在使用的云根磁盘只有15GB,所以使用Docker Compose启动多个容器进行开发很快就会出现容量不足的问题。在开发过程中,由于经常产生垃圾数据,所以需要定期重新创建/var/lib/docker目录,但是我计划添加一个稍微大一些的磁盘并将其迁移过去。最初因为/etc/fstab的描述错误而不得不进入恢复模式启动。而且还忘记了root密码,只能进入单用户模式启动,所以在进行操作时需要格外小心。

我参考了以下的网站。最初我阅读的那个网站给出的mount的bind选项的用法是错误的,让我感到困惑。

    • Moving docker images location to different partition

 

    Moving Docker “stuff” to a Different Drive

版本环境

首先,我们需要确认工作环境的Docker和操作系统版本。

Docker的版本

$ docker version
Client version: 1.6.2
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): 7c8fca2
OS/Arch (client): linux/amd64
Server version: 1.6.2
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): 7c8fca2
OS/Arch (server): linux/amd64

内核 hé)

$ cat /proc/version
Linux version 3.13.0-33-generic (buildd@tipua) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #58-Ubuntu SMP Tue Jul 29 16:45:05 UTC 2014

Ubuntu 14.04.2 可供选择。

$ cat /etc/lsb-release
NAME="Ubuntu"
VERSION="14.04.2 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.2 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

添加磁盘

这是作业前磁盘的使用情况。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        15G  4.1G  9.9G  29% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            2.0G  4.0K  2.0G   1% /dev
tmpfs           395M  816K  394M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            2.0G  476K  2.0G   1% /run/shm
none            100M     0  100M   0% /run/user

我已经添加了一个容量为40GB的硬盘。虽然这是在云上进行的,但是我可以通过fdisk命令看到设备已被识别。目前还未创建任何分区。

$ sudo fdisk -l

Disk /dev/sda: 16.1 GB, 16106127360 bytes
255 heads, 63 sectors/track, 1958 cylinders, total 31457280 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000db9c4

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048    31455231    15726592   83  Linux

Disk /dev/sdb: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders, total 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/sdb doesn't contain a valid partition table

创建分区

使用fdisk命令创建分区。对应的命令为n、p、[Enter]重复三次,然后输入w。

$ sudo fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0xef0c9f8a.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-83886079, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-83886079, default 83886079):
Using default value 83886079

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

确认创建分区。/dev/sdb1已创建。

$ sudo fdisk -l


Disk /dev/sda: 16.1 GB, 16106127360 bytes
255 heads, 63 sectors/track, 1958 cylinders, total 31457280 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000db9c4

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048    31455231    15726592   83  Linux

Disk /dev/sdb: 42.9 GB, 42949672960 bytes
171 heads, 5 sectors/track, 98112 cylinders, total 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xef0c9f8a

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    83886079    41942016   83  Linux

创建文件系统

由于现有的文件系统是ext4,因此使用相同类型进行创建。

$ df -T
Filesystem     Type     1K-blocks    Used Available Use% Mounted on
/dev/sda1      ext4      15348720 4212380  10333628  29% /
none           tmpfs            4       0         4   0% /sys/fs/cgroup
udev           devtmpfs   2009748       4   2009744   1% /dev
tmpfs          tmpfs       404100     820    403280   1% /run
none           tmpfs         5120       0      5120   0% /run/lock
none           tmpfs      2020484     476   2020008   1% /run/shm
none           tmpfs       102400       0    102400   0% /run/user

创建ext4文件系统。

$ sudo mkfs.ext4 /dev/sdb1
mke2fs 1.42.9 (4-Feb-2014)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
2621440 inodes, 10485504 blocks
524275 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
320 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
    4096000, 7962624

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

挂载分区

首先,我们会停止 Docker,并将/var/lib/docker 目录挂载到新的分区上。

$ sudo service docker stop
docker stop/waiting

创建用于挂载分区的目录。在Ubuntu中,通常在/media目录下创建。

$ sudo mkdir /media/data

由于编辑/etc/fstab可能有风险,所以必须备份数据。

$ sudo cp -ip /etc/fstab{,.`date +%Y%m%d`}

可以使用blkid命令来确认分区的UUID。

$ sudo  blkid | grep sdb1
/dev/sdb1: UUID="d45eaaab-e223-4162-96b3-fefea9392cad" TYPE="ext4"}}}

将新分区的UUID添加到/etc/fstab文件中。

UUID=ed7bdb81-136d-458b-8121-2c4e5d3f569f /               ext4    errors=remount-ro 0       1
/dev/fd0        /media/floppy0  auto    rw,user,noauto,exec,utf8 0       0

UUID=d45eaaab-e223-4162-96b3-fefea9392cad /media/data ext4 defaults 0  2

每次都会忘记,但是我已经将第4、5、6列设置如下。

    • 4列目: デフォルト

 

    • 5列目: 0: dumpする

 

    6列目: 2: fsckする

重新挂载/etc/fstab的设置。

$ sudo mount -a

/dev/sdb1 设备已挂载。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        15G  4.1G  9.9G  29% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            2.0G  8.0K  2.0G   1% /dev
tmpfs           395M  792K  394M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            2.0G     0  2.0G   0% /run/shm
none            100M     0  100M   0% /run/user
/dev/sdb1        40G   48M   38G   1% /media/data

搬移/var/lib/docker

使用rsync命令复制目录

使用rsync命令将/var/lib/docker目录下的文件复制到新的目录中。

$ sudo mkdir /media/data/docker
$ sudo rsync -aXS /var/lib/docker/. /media/data/docker/

rsync完成后,/var/lib/docker和/media/data/docker的内容已经相同了。

$ sudo du -sch /var/lib/docker/*
2.1G    /var/lib/docker/aufs
140K    /var/lib/docker/containers
808K    /var/lib/docker/graph
15M /var/lib/docker/init
12K /var/lib/docker/linkgraph.db
4.0K    /var/lib/docker/repositories-aufs
4.0K    /var/lib/docker/tmp
8.0K    /var/lib/docker/trust
44K /var/lib/docker/volumes
2.2G    total
$ sudo du -sch /media/data/docker/*
2.1G    /media/data/docker/aufs
140K    /media/data/docker/containers
808K    /media/data/docker/graph
15M /media/data/docker/init
12K /media/data/docker/linkgraph.db
4.0K    /media/data/docker/repositories-aufs
4.0K    /media/data/docker/tmp
8.0K    /media/data/docker/trust
44K /media/data/docker/volumes
2.1G    total

目錄的掛載

为了安全起见,我们将原始的/var/lib/docker目录进行重命名并备份。然后我们将清空该目录并重新创建。

$ sudo mv /var/lib/docker /var/lib/docker.bak
$ sudo mkdir /var/lib/docker

/var/lib/docker目录是空的。

$ ls /media/data/docker/
aufs        graph  linkgraph.db       tmp    volumes
containers  init   repositories-aufs  trust
$ ls /var/lib/docker

将/media/data/docker使用bind选项挂载到/var/lib/docker上。我们可以通过BIND选项来详细解释mount功能。通过使用mount的bind选项,我们可以将任意目录作为独立的文件系统进行挂载。需要注意的是,该目录所在的设备分区必须已经被挂载。

$ sudo mount -o bind  /media/data/docker /var/lib/docker
$ sudo du -sch /var/lib/docker/*
2.1G    /var/lib/docker/aufs
140K    /var/lib/docker/containers
808K    /var/lib/docker/graph
15M /var/lib/docker/init
12K /var/lib/docker/linkgraph.db
4.0K    /var/lib/docker/repositories-aufs
4.0K    /var/lib/docker/tmp
8.0K    /var/lib/docker/trust
44K /var/lib/docker/volumes
2.1G    total

/media/data/docker目录已挂载到/var/lib/docker目录下。最初我错误地将其反向写入了fstab文件,导致无法启动。

$ df -ha
Filesystem       Size  Used Avail Use% Mounted on
/dev/sda1            15G  4.1G  9.9G  29% /
...
/dev/sdb1            40G  2.2G   36G   6% /media/data
/media/data/docker   40G  2.2G   36G   6% /var/lib/docker

編輯 /etc/fstab 檔案並在重新啟動後讓其生效。

/media/data/docker /var/lib/docker  none bind 0 0

我会重新载入mount。

$ sudo mount -a

从移动位置启动并确认Docker。

只有aufs在旧目录中才会增加。

启动Docker。

$ sudo service docker start
docker start/running, process 4276

仅/var/lib/docker/aufs已增加至4.3G。/media/data/docker/aufs未发生变化。aufs仍保持在先前位置。在此状态下,即使拉取新镜像docker pull,/var/lib/docker也不会增加。

$ sudo du -sch /var/lib/docker/*
4.3G    /var/lib/docker/aufs
168K    /var/lib/docker/containers
808K    /var/lib/docker/graph
15M /var/lib/docker/init
12K /var/lib/docker/linkgraph.db
4.0K    /var/lib/docker/repositories-aufs
4.0K    /var/lib/docker/tmp
8.0K    /var/lib/docker/trust
44K /var/lib/docker/volumes
4.3G    total
$ sudo du -sch /media/data/docker/*
2.1G    /media/data/docker/aufs
168K    /media/data/docker/containers
808K    /media/data/docker/graph
15M /media/data/docker/init
12K /media/data/docker/linkgraph.db
4.0K    /media/data/docker/repositories-aufs
4.0K    /media/data/docker/tmp
8.0K    /media/data/docker/trust
44K /media/data/docker/volumes
2.1G    total

由于docker-compose.yml文件中的服务设置为”restart: always”,导致aufs增加。因此,在Docker启动时启动了这些服务。已经创建的容器只使用”bind”选项无法正确移动。

$ docker-compose ps
      Name             Command             State              Ports
-------------------------------------------------------------------------
meshblucompose_m   npm start          Up                 0.0.0.0:1883->18
eshblu_1                                                 83/tcp, 9000/tcp
meshblucompose_m   /entrypoint.sh     Up                 27017/tcp
ongo_1             mongod
meshblucompose_o   nginx -c /etc/ng   Up
penresty_run_1     inx/nginx. ...
meshblucompose_r   /entrypoint.sh     Up                 6379/tcp
edis_1             redis-server

将其添加到DOCKER_OPTS中

需要在Docker选项中指定新的/var/lib/docker目录。在停止Docker后,将其添加到配置文件中。

DOCKER_OPTS="-g /media/data/docker"

我要启动Docker。

$ sudo service docker start
docker start/running, process 5786

终于,/var/lib/docker的大小没有增加,而是增加了/media/data/docker/目录中的aufs大小。成功迁移了/var/lib/docker。

$ sudo du -sch /var/lib/docker/*
2.1G    /var/lib/docker/aufs
180K    /var/lib/docker/containers
808K    /var/lib/docker/graph
15M /var/lib/docker/init
12K /var/lib/docker/linkgraph.db
4.0K    /var/lib/docker/repositories-aufs
4.0K    /var/lib/docker/tmp
8.0K    /var/lib/docker/trust
44K /var/lib/docker/volumes
2.1G    total
$ sudo du -sch /media/data/docker/*
4.3G    /media/data/docker/aufs
180K    /media/data/docker/containers
808K    /media/data/docker/graph
15M /media/data/docker/init
12K /media/data/docker/linkgraph.db
4.0K    /media/data/docker/repositories-aufs
4.0K    /media/data/docker/tmp
8.0K    /media/data/docker/trust
44K /media/data/docker/volumes
4.3G    total
广告
将在 10 秒后关闭
bannerAds