1.先了解一下LVM

        LVM是 Logical Volume Manager,逻辑的概念,Linux用户安装Linux操作系统时遇到的一个常见的难以决定的问题就是如何正确地评估各分区大小,以分配合适的硬盘空间。普通的磁盘分区管理方式在逻辑分区划分好之后就无法改变其大小,当一个逻辑分区存放不下某个文件时,这个文件因为受上层文件系统的限制,也不能跨越多个分区来存放,所以也不能同时放到别的磁盘上。而遇到出现某个分区空间耗尽时,解决的方法通常是使用符号链接,或者使用调整分区大小的工具,但这只是暂时解决办法,没有从根本上解决问题。随着Linux的逻辑卷管理功能的出现,这些问题都迎刃而解,用户在无需停机的情况下可以方便地调整各个分区大小

        PV,VG,LV构成了一种易于管理拥有一个或多个硬盘的主机的文件系统,这些硬盘可能只有一个分区也可能有多个。通过将这些物理存在的分区(或称为卷)PV(physical volume)进行整合,组成一个分区(卷)组VG(volume group),进而再次进行分配形成逻辑分区(卷)LV(logical volume)。创建成功的逻辑分区对于操作系统来说会想普通分区无异,其好处是可以动态调整分区大小。管理PV,VG,LV的工具称为逻辑卷管理器LVM(logical volume manager)。如下图所示:

        docker的loop-lvm和direct-lvm

        需要指出的是,在某个物理卷在加入卷组时,会将物理卷的最小存储单元设定为一个固定的值,这个值称为PE(physical extent)。这个值的创建,是为了保证用统一的最小分配单元来创建逻辑卷,不至于因为分配单元大小不同而造成空间浪费。举个例子:用于远洋运输的集装箱的设计是是有着统一标准的,最重要一点是集装箱大小完全相同,这样做的好处是集装箱相互堆叠在一起不会留下多余的空隙,完全利用了空间,且便于管理。设定PE的原因也与此相同。LVM以最小分配单元来创建逻辑卷,该最小分配单元的值称为LE(logical extent)。一般来说PE=LE,PE的大小是可配置的,默认为4MB。

 

 

2.常用命令

  • pvcreate: 创建PV

  • pvdisplay: 查看已创建的PV

  • vgcreate: 创建VG

  • vgdisplay: 查看VG

  • lvcreate: 创建LV

  • lvdisplay: 查看LV

 

以下参考:https://blog.csdn.net/qq_26923057/article/details/52351731

3.devicemapper介绍

      Device Mapper是Linux系统中基于内核的高级卷管理技术框架。Docker的devicemapper存储驱动就是基于该框架的精简置备和快照功能来实现镜像和容器的管理。

              注:Device Mapper是Linux的一种技术框架,而devicemapper是Docker Engine基于Device Mapper提供的一种存储驱动。

      早期的Docker运行在Ubuntu和Debian Linux上并使用AUFS作为后端存储。Docker流行之后,越来越多的的公司希望在Red Hat Enterprise Linux这类企业级的操作系统上面运行Docker,但可惜的是RHEL的内核并不支持AUFS。

      这个时候红帽公司出手了,决定和Docker公司合作去开发一种基于Device Mapper技术的后端存储,也就是现在的devicemapper。

      devicemapper驱动将每一个Docker镜像和容器存储在它自身的具有精简置备(thin-provisioned)、写时拷贝(copy-on-write)和快照功能(snapshotting)的虚拟设备上。由于Device Mapper技术是在块(block)层面而非文件层面,所以Docker Engine的devicemapper存储驱动使用的是块设备来存储数据而非文件系统。

      devicemapper是RHEL下Docker Engine的默认存储驱动,它有两种配置模式:loop-lvm和direct-lvm。

loop-lvm是默认的模式,它使用OS层面离散的文件来构建精简池(thin pool)。也就是用一个稀疏文件来当成一个块设备,给devicemapper用。该模式主要是设计出来让Docker能够简单的被”开箱即用(out-of-the-box)”而无需额外的配置。但如果是在生产环境的部署Docker,官方明文不推荐使用该模式。我们使用docker info命令可以看到以下警告:

      docker的loop-lvm和direct-lvm

direct-lvm是Docker推荐的生产环境的推荐模式,他使用块设备来构建精简池来存放镜像和容器的数据。

 

4.配置direct-lvm模式

 (1)查看当前为devicemapper模式

          注意Pool Name是docker自己生成的;Deferred Deletion Enabled是false

docker的loop-lvm和direct-lvm

 

(1)停止docker(如果还没装docker就跳过这步吧)

最好是先部署direct-lvm,再安装docker。

分配裸设备

本例以Nutanix的ABS功能来分配一块iSCSI盘到docker宿主机,推荐使用外部共享存储的设备但不局限于此种方式,可根据自己的环境决定。

创建一个Volume Group

添加50GB的盘

将Volume Group挂给docker宿主机

 

查看设备,局方提供了一块sdb盘,50G。

docker的loop-lvm和direct-lvm

 

(2)创建PV

docker的loop-lvm和direct-lvm

 

(3)创建VG 

docker的loop-lvm和direct-lvm

 

 查看VG信息

[root@docanix ~]# vgdisplay docker

  --- Volume group ---

  VG Name               docker

  System ID            

  Format                lvm2

  Metadata Areas        1

  Metadata Sequence No  1

  VG Access             read/write

  VG Status             resizable

  MAX LV                0

  Cur LV                0

  Open LV               0

  Max PV                0

  Cur PV                1

  Act PV                1

  VG Size               50.00 GiB

  PE Size               4.00 MiB

  Total PE              12799

  Alloc PE / Size       0 / 0  

  Free  PE / Size       12799 / 50.00 GiB

  VG UUID               bXJkQH-qSJc-t5JT-f1GL-reTR-XBVf-ylCEFY

 

(4)创建thinpool,首先创建2个pool

docker的loop-lvm和direct-lvm

数据LV大小为VG的95%,元数据LV大小为VG的1%,剩余的空间用来自动扩展。 作为meta的pool大小不能超过16GB。这是为什么???

 

(5)将pool转化为thinpool

[root@docanix ~]# lvconvert -y --zero n -c 512K --thinpool docker/thinpool --poolmetadata docker/thinpoolmeta

  WARNING: Converting logical volume docker/thinpool and docker/thinpoolmeta to pool's data and metadata volumes.

  THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)

  Converted docker/thinpool to thin pool.

 将pool转换为thin-pool同时将thinpool lv的chunksize改为512KB,并且将前 4KB 字节清零。

 

(6)配置thinpool

 

配置池的自动扩展

docker的loop-lvm和direct-lvm

 

加载上一步文件配置,应用配置变更(文件名称要对应哦)

docker的loop-lvm和direct-lvm

 

监控检查磁盘,一定要执行,否则磁盘不会自动扩展。

docker的loop-lvm和direct-lvm

 

列出块设备信息

[root@hps4 profile]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 20G 0 disk
└─sdb1 8:17 0 20G 0 part
├─docker-thinpool_tmeta 253:3 0 204M 0 lvm
│ └─docker-thinpool 253:5 0 19G 0 lvm
└─docker-thinpool_tdata 253:4 0 19G 0 lvm
└─docker-thinpool 253:5 0 19G 0 lvm

 

(7)配置docker,修改服务配置文件

ExecStart=/usr/bin/docker daemon  --insecure-registry 0.0.0.0/0 -H unix:///var/run/docker.sock  --storage-driver=devicemapper --storage-opt=dm.thinpooldev=/dev/mapper/docker-thinpool --storage-opt=dm.use_deferred_removal=true --storage-opt=dm.use_deferred_deletion=true

 

(8)清除docker以前的数据,下图是举个例子,具体删的目录要看安装配置

docker的loop-lvm和direct-lvm

不清除以前数据可能会有如下报错:

Error starting daemon: error initializing graphdriver: devmapper: Base Device UUID and Filesystem verification failed: devicemapper: Error running deviceCreate (ActivateDevice) dm_task_run failed

 

(9)重启docker 即可。再看docker info

docker的loop-lvm和direct-lvm

        查看docker info

docker的loop-lvm和direct-lvm

红色部分说明已经是direct-lvm模式了,除了红色框框内的变化,Data file 和Metadata file是空的.

 

(10)测试

pull一个镜像看是否数据会写到thinpool里

docker的loop-lvm和direct-lvm

 

docker的loop-lvm和direct-lvm

可以看到Data%在pull一个busybox镜像后使用率由0.04变为0.08,说明direct-lvm配置成功且正常工作。 

 

If you reboot the host and find that the docker service failed to start, look for the error, “Non existing device”. You need to re-activate the logical volumes with this command:

    sudo lvchange -ay docker/thinpool

 

附官网如何配置这两种模式

https://docs.docker.com/storage/storagedriver/device-mapper-driver/#configure-loop-lvm-mode-for-testing

 

补充:

如果局方磁盘只有一块vdb盘,那么我们要把vdb盘分成两个盘,一块正常挂载存放应用和日志等,另一块盘用来做lvs。

 

2T以下的磁盘分区可以使用fdisk工具,步骤如下:

(1)分区

[root@RLSB02 ~]# fdisk /dev/vdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0xa33a833f.

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): 1
First sector (2048-838860799, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-838860799, default 838860799): 204800000
Partition 1 of type Linux and of size 97.7 GiB is set

Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p): p
Partition number (2-4, default 2): 2
First sector (204800001-838860799, default 204802048):
Using default value 204802048
Last sector, +sectors or +size{K,M,G} (204802048-838860799, default 838860799):
Using default value 838860799
Partition 2 of type Linux and of size 302.4 GiB is set

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

Calling ioctl() to re-read partition table.

docker的loop-lvm和direct-lvm

这样我们可以拿vdb1正常挂载,vdb2做lvs

 

(2)别忘了初始化两块磁盘:

mkfs.ext4  /dev/vdb1

mkfs.ext4  /dev/vdb2

 

(3)挂载vdb1盘

mkdir /data

在/etc/fstab后面添加下面记录

/dev/vdb1   /data    ext4 noatime,defaults 1 1

保存后,执行mount -a

然后df -h看下磁盘vdb1已经被挂载上了,vdb2就不赘述了,按照前面步骤做吧