Docker如今在后端是那么的火热..尤为当笔者了解了docker是什么、能作什么以后,真的是感受特别的exciting,便火烧眉毛的去实践部署一下. 可是在实际部署中,由于笔者使用的是阿里云ecs服务器,centos7系统,由于centos7与ubuntu的差别性,因此,须要本身把后端存储引擎devicemapper从loop_lvm模式配置为direct_lvm模式。在这其中又遇到了坑,因此以为颇有必要记录下来,作个备忘.html
ubuntu与contos的差别: 在Ubuntu/Debian上有UnionFS可使用,如aufs或者overlay2,而CentOS和RHEL的内核中没有相关驱动。linux
Docker的背景: Docker最早就是跑在Ubuntu和Debian上的,使用的就是aufs存储器.由于docker愈来愈流行,许多公司但愿在rhel上使用,可是上游内核中并无包括aufs,因此rhel不能使用aufs. 最终,开发者们开发了一个新的后端存储引擎devicemapper,基于已有的Device Mapper技术,而且使docker 支持可插拔,如今全世界有不少真实案例在生产环境中使用devicemapper. git
loop_lvm和direct_lvm区别:github
由于上述的缘由,对于centos/rhel这类没有相关驱动的系统,通常使用devicemapper驱动利用LVM的一些机制来模拟分层存储。这样的作法除了性能比较差以外,稳定性通常也很差,并且配置相对复杂。Docker安装在CentOS/RHEL 上后,会默认选择 devicemapper
,可是为了简化配置,其 devicemapper
是跑在一个稀疏文件模拟的块设备上,也被称为 loop-lvm
。这样的选择是由于不须要额外配置就能够运行 Docker,这是自动配置惟一能作到的事情。可是 loop-lvm
的作法很是很差,其稳定性、性能更差,不管是日志仍是 docker info
中都会看到警告信息。官方文档有明确的文章讲解了如何配置块设备给 devicemapper
驱动作存储层的作法,这类作法也被称为配置 direct-lvm
。docker
除了前面说到的问题外,devicemapper
+ loop-lvm
还有一个缺陷,由于它是稀疏文件,因此它会不断增加。用户在使用过程当中会注意到 /var/lib/docker/devicemapper/devicemapper/data
不断增加,并且没法控制。不少人会但愿删除镜像或者能够解决这个问题,结果发现效果并不明显。缘由就是这个稀疏文件的空间释放后基本不进行垃圾回收的问题。所以每每会出现即便删除了文件内容,空间却没法回收,随着使用这个稀疏文件一直在不断增加。json
对于 CentOS/RHEL 的用户来讲,在没有办法使用 UnionFS
的状况下,必定要配置 direct-lvm
给 devicemapper
,不管是为了性能、稳定性仍是空间利用率。ubuntu
或许有人注意到了 CentOS 7 中存在被 backports 回来的 overlay
驱动,不过 CentOS 里的这个驱动达不到生产环境使用的稳定程度,因此不推荐使用。后端
(参考自:Docker--从入门到实践)centos
比较easy,本身参考Docker--从入门到实践,在其中讲的有具体步骤,很详细了。本文的重点是direct_lvm模式的配置,这里就再也不细说。服务器
生产环境下应该使用direct_lvm,若是以前有镜像在loop_lvm模式下建立,须要切换,则须要把镜像作备份(push到hub或者私有registry).因此最好的作法,仍是: 在刚刚给centos服务器安装docker的时候,直接作好配置.
[root@srv00 ~]# systemctl stop docker
检查磁盘
[root@iZ28uvczcf6Z mapper]# fdisk -l <==检查下磁盘 Disk /dev/xvda: 107.4 GB, 107374182400 bytes, 209715200 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 label type: dos Disk identifier: 0x635e6c7d Device Boot Start End Blocks Id System /dev/xvda1 * 2048 209713151 104855552 8e Linux LVM Disk /dev/xvdb: 21.5 GB, 21474836480 bytes, 41943040 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 label type: dos Disk identifier: 0x021dd279 Device Boot Start End Blocks Id System /dev/xvdb1 2048 41943039 20970496 8e Linux LVM
建立pv
[root@srv00 ~]# pvcreate /dev/xvdb1 Physical volume "/dev/xvdb" successfully created
注意: pvcreate 指令后面配置的硬盘(此处为"xvdb1")必须为独立的挂载硬盘,而不能是系统盘,不然会报错,建立失败.
(关于挂载新硬盘后,如何对硬盘进行"初始化"、"分区" ,在本文最后会单独讲解。(好比在本代码中,把Disk "/dev/xvdb"初始化成一块分区 "/dev/xvdb1",大小等同于磁盘大小(约20G)。)
建立vg
[root@srv00 ~]# vgcreate vgdocker /dev/xvdb1 Volume group "vgdocker" successfully created
建立一个thin pool,名字叫thinpool
,先来建立逻辑卷
[root@srv00 ~]# lvcreate --wipesignatures y -n thinpool -l 95%VG vgdocker Logical volume "thinpool" created. [root@srv00 ~]# lvcreate --wipesignatures y -n thinpoolmeta -l 1%VG vgdocker Logical volume "thinpoolmeta" created. [root@srv00 ~]# lvscan ACTIVE '/dev/centos/swap' [4.00 GiB] inherit ACTIVE '/dev/centos/root' [35.47 GiB] inherit ACTIVE '/dev/vgdocker/thinpool' [28.50 GiB] inherit ACTIVE '/dev/vgdocker/thinpoolmeta' [304.00 MiB] inherit
"剩余的4%留给它们自动扩展"
转换成thin pool
[root@srv00 ~]# lvconvert -y --zero n -c 512K --thinpool vgdocker/thinpool --poolmetadata vgdocker/thinpoolmeta WARNING: Converting logical volume vgdocker/thinpool and vgdocker/thinpoolmeta to pool's data and metadata volumes. THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.) Converted vgdocker/thinpool to thin pool.
设置thinpool的自动扩展参数,并应用此profile
[root@srv00 ~]# vi /etc/lvm/profile/docker-thinpool.profile activation { thin_pool_autoextend_threshold=80 thin_pool_autoextend_percent=20 } [root@srv00 ~]# lvchange --metadataprofile docker-thinpool vgdocker/thinpool Logical volume "thinpool" changed.
"当空间大于80%时进行扩展.扩展的大小是空闲空间的20%"
查看thinpool是不是已监视状态
[root@srv00 ~]# lvs -o+seg_monitor LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert Monitor root centos -wi-ao---- 35.47g swap centos -wi-ao---- 4.00g thinpool vgdocker twi-a-t--- 28.50g 0.00 0.02 monitored
备份
$ mkdir /var/lib/docker.bk $ mv /var/lib/docker/* /var/lib/docker.bk
删除原存储目录
[root@srv00 ~]# rm -rf /var/lib/docker/*
"注意备份重要镜像等"
咱们经过systemd的drop-in方式修改,也是官方推荐的
编辑config文件
[root@srv00 ~]# mkdir /etc/systemd/system/docker.service.d [root@srv00 ~]# vi /etc/systemd/system/docker.service.d/daemon.conf [Service] ExecStart= ExecStart=/usr/bin/dockerd
"ExecStart=
第一行是空.不然启动会报错; "
实际启动时,是须要一些参数的,咱们把它配置在daemon.json文件中。文件的位置是/etc/docker/daemon.json 经过vi指令编辑、保存,便可. daemon.json文件内容以下:
{ "storage-driver": "devicemapper", "storage-opts": [ "dm.thinpooldev=/dev/mapper/vgdocker-thinpool", "dm.use_deferred_removal=true", "dm.use_deferred_deletion=true" ] }
从新reload
[root@srv00 ~]# systemctl daemon-reload
[root@srv00 ~]# systemctl start docker
"修改daemon参数须要reload"
能够看到,direct_lvm模式已经配置成功.
注: 由于笔者机器已经配置完毕,没法从新配置前面的步骤,因此前面的一些代码,均是从一篇他人的博客(点击访问)中粘贴过来的,并进行了一些整理。 不过差异只是硬盘名称不同,流程和输入指令彻底能够直接照搬.
[root@iZ28uvczcf6Z mapper]# docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 1 Server Version: 1.12.5 Storage Driver: devicemapper Pool Name: vgdocker-thinpool Pool Blocksize: 524.3 kB Base Device Size: 10.74 GB Backing Filesystem: xfs Data file: Metadata file: Data Space Used: 990.4 MB Data Space Total: 20.4 GB Data Space Available: 19.41 GB Metadata Space Used: 233.5 kB Metadata Space Total: 213.9 MB Metadata Space Available: 213.7 MB Thin Pool Minimum Free Space: 2.039 GB Udev Sync Supported: true Deferred Removal Enabled: true Deferred Deletion Enabled: true Deferred Deleted Device Count: 0 Library Version: 1.02.135-RHEL7 (2016-09-28) Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: null host bridge overlay Swarm: inactive Runtimes: runc Default Runtime: runc Security Options: seccomp Kernel Version: 3.10.0-514.2.2.el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 1 Total Memory: 991.2 MiB Name: iZ28uvczcf6Z ID: KJ44:XNL6:W5KM:VYDQ:WN4C:FDPF:U52P:27SJ:MCWA:Q6JA:D76Z:JXVC Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ WARNING: bridge-nf-call-iptables is disabled Insecure Registries: 127.0.0.0/8 [root@iZ28uvczcf6Z mapper]#
必定不能是系统盘
由于Docker 1.12的一些新变化,基于网上的一些博客、文章,在配置时,就要有一些改变,不然你可能会遇到错误:"no sockets found via socket activation: make sure the service was started by systemd"。这个错误的解决方式,感兴趣的能够自行查看此连接: "docker daemon -H fd://" fails with message "No sockets found" under Ubuntu 15.10 #22847
$ fdisk /dev/xvdb Command(m for help): n n以后,根据本身须要配置,也能够连着3次enter就能够完成配置,初始化为一块分区,分区大小=硬盘大小 Command (m for help): t t是个改类型的指令 Partition number (1-3,default 3): Partition type (type L to list all types): 8e 最好是给配置为支持LVM的8e类型 Command ( m for help): w 保存 partprobe 用partprobe可使kernel从新读取分区信息,从而避免重启 //如下的指令非必须,仅作一个备录 pvcreate /dev/sda3 vgextend vg00 /dev/sda3 vgdisplay lvextend -L +80G /dev/vg00/lv_root lvdisplay resize2fs /dev/vg00/lv_root df -h
笔者学习时也是参考了一些博客、文章, 在它们的基础上,作了整理,并修改掉过期的配置信息. 其中一些笔者本身以为说的挺清晰的,罗列在下面,方便参考:
Docker官方教程 : 官方教程,不用多说,只是英文阅读起来费些力气
Docker--从入门到实践 :gitbook书籍,讲的很详细
以及几篇不错的文章:
http://www.linuxtechi.com/thin-provisioned-logical-volumes-centos-7-rhel-7/
本文主要讲的是本身手动配置direct_lvm模式的方式,还有一种简单些的配置方式.如 Docker Device Mapper 使用direct_lvm,文章提到了一个工具: docker-storage-setup,貌似基于这个脚本能够比较便捷的进行配置,可是感受文中内容,笔者看的不是很明白,因此就没有继续了. docker-storage-setup的github网址,笔者也已经找到了:projectatomic/docker-storage-setup 。若是你感兴趣,研究有结果以后,欢迎回来在下方分享给笔者^_^。
本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利;
本文出自:博客园--别问是谁