Docker存储驱动之--overlay2

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker存储驱动之--overlay2相关的知识,希望对你有一定的参考价值。

参考技术A docker支持多种graphDriver,包括vfs、devicemapper、overlay、overlay2、aufs等等,其中最常用的就是aufs了,但随着linux内核3.18把overlay纳入其中,overlay的地位变得更重,最近也在自己的虚拟机上用overlay2作为docker存储驱动实验了一番,下面来做一个简单的笔记和总结。

docker默认的存储目录是 /var/lib/docker ,下面我们简单打印一下这个目录:

在这里,我们只关心 image 和 overlay2 就足够了。
做这个实验之前,我们应该先启动一个容器,在这里使用nginx作为实验:

可以看到新启动的nginx容器的id是 86b5733e54c7 ,我们继续往下看。

上面说了,我们只需要关心 /var/lib/docker/image 和 /var/lib/docker/overlay2 ,可以先到 /var/lib/docker/image 打印一下:

我们只能看到overlay2这个目录,想必聪明的你也猜到了,docker会在 /var/lib/docker/image 目录下按每个存储驱动的名字创建一个目录,如这里的 overlay2 。
接下来,使用 tree 命令浏览一下这个目录:

这里的关键地方是 imagedb 和 layerdb 目录,看这个目录名字,很明显就是专门用来存储元数据的地方,那为什么区分image和layer呢?因为在docker中,image是由多个layer组合而成的,换句话就是layer是一个共享的层,可能有多个image会指向某个layer。
那如何才能确认image包含了哪些layer呢?答案就在 imagedb 这个目录中去找。比如上面启动的nginx容器,我们可以先找到这个容器对应的镜像:

可以看到,imageID是 2bcb04bdb83f ,再次记住这个id,我们打印 /var/lib/docker/image/overlay2/imagedb/content/sha256 这个目录:

第一行的 2bcb04bdb83f7c5dc30f0edaca1609a716bda1c7d2244d4f5fbbdfef33da366c 正是记录我们 nginx 镜像元数据的文件,接下来cat一下这个文件,得到一个长长的json:

由于篇幅原因,我只展示最关键的一部分,也就是 rootfs 。可以看到rootfs的diff_ids是一个包含了3个元素的数组,其实这3个元素正是组成 nginx 镜像的3个layerID,从上往下看,就是底层到顶层,也就是说 5dacd731af1b0386ead06c8b... 是image的最底层。既然得到了组成这个image的所有layerID,那么我们就可以带着这些layerID去寻找对应的layer了。
接下来,我们返回到上一层的 layerdb 中,先打印一下这个目录:

在这里我们只管 mounts 和 sha256 两个目录,再打印一下 sha256 目录:

在这里,我们仅仅发现 5dacd731af1b038.. 这个最底层的layer,那么剩余两个layer为什么会没有呢?那是因为docker使用了chainID的方式去保存这些layer,简单来说就是chainID=sha256sum(H(chainID) diffid),也就是 5dacd731af1b038.. 的上一层的sha256 id是:

这个时候,你能看到 166d13b... 这个layer层的目录了吧?依次类推,我们就能找出所有的layerID的组合。
但是上面我们也说了, /var/lib/docker/image/overlay2/layerdb 存的只是元数据,那么真实的rootfs到底存在哪里呢?其中 cache-id 就是我们关键所在了。我们打印一下 /var/lib/docker/image/overlay2/layerdb/sha256/5dacd731af1b0386ead06c8b1feff9f65d9e0bdfec032d2cd0bc03690698feda/cache-id :

没错,这个id就是对应 /var/lib/docker/overlay2/dffe31c1db6055910b3cd49366a2989d9cd2f3460844437b2190de44807095fa 。因此,以此类推,更高一层的layer对应的cache-id也能找到对应的rootfs,当这些rootfs的diff目录通过联合挂载的方式挂载到某个目录,就能完整整个容器需要的rootfs了。

Centos7 为Docker配置overlay存储驱动

前提:

RHEL或CentOS 使用新的docker存储驱动(overlay or overlay2),需要升级系统内核版本到3.10.0-514以上版本。梳理步骤如下:

确认内核

3.10.0-514以上版本

uname -r        
3.10.0-514.++++.x86_64      

系统升级

sudo yum upgrade --assumeyes --tolerant    
sudo yum update --assumeyes        

确认内核是否加载 overlay模块

lsmod | grep overlay      

如果返回为空,需要配置模块加载

启用overlay

sudo tee /etc/modules-load.d/overlay.conf <<-‘EOF‘
overlay
EOF

重启系统

reboot

确认 overlay启用

lsmod | grep overlay      
overlay

准备Docker存储分区

强烈建议另外准备一块磁盘或者分区,加参数 -n ftype=1 格式化为 xfs 格式,然后将 /var/lib/docker 挂载上去:

原因解释

XFS文件系统格式化时必须加 -n ftype=1
参数:-n 不真正创建文件系统,只是显示创建的信息;
ftype = value 允许inode类型存储在目录结构中,以便readdir,getdents不需要查找inode就可知道inode类型。默认为0,不存在目录结构中。

格式化本地磁盘

注意确认,格式化本地磁盘是否正确;

mkfs.xfs -f -n ftype=1 /dev/sdg5

确认磁盘信息

lsblk -a -f 
NAME   FSTYPE LABEL UUID                                 MOUNTPOINT

├─sdg4                                                   
├─sdg5 xfs          71165973-9e3f-4d8e-9a4e-2c00c0e70efa     

配置磁盘开机挂载

more /etc/fstab         

UUID=71165973-9e3f-4d8e-9a4e-2c00c0e70efa /var/lib/docker                 xfs     defaults        0 0     

手动挂载磁盘

mount -a

查看磁盘挂载信息

lsblk   

├─sdg5   8:101  0  200G  0 part /var/lib/docker

修改docker启动文件,设置使用overlay 存储

more /etc/sysconfig/docker

# /etc/sysconfig/docker

# Modify these options if you want to change the way the docker daemon runs
OPTIONS=‘--storage-driver=overlay --selinux-enabled --log-driver=journald --signature-verification=false‘ 
if [ -z "${DOCKER_CERT_PATH}" ]; then
    DOCKER_CERT_PATH=/etc/docker
fi

或者

/etc/docker/daemon.json
{
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}

添加开机启动

systemctl daemon-reload
systemctl start docker
systemctl enable docker

验证docker 存储相关信息

$ docker info

Containers: 0
Images: 0
Storage Driver: overlay2
 Backing Filesystem: xfs
 Supports d_type: true        <<===重点确认
 Native Overlay Diff: true
<output truncated>

如果在不支持 d_typ 的 overlay/overlay 驱动下使用docker,也就意味着 docker 在操作文件的时候,可能会遇到一些错误,比如 无法删除某些目录或文件,设置文件或目录的权限或用户失败等等。这些都是不可预料的错误。举个具体的场景,就是,docker构建的时候,可能在构建过程中,删除文件等操作失败,导致构建停止。

以上是关于Docker存储驱动之--overlay2的主要内容,如果未能解决你的问题,请参考以下文章

DOCKER存储驱动之DEVICE MAPPER简介

Docker存储驱动之Device Mapper简介

Docker存储驱动之Btrfs简介

docker深入2-存储驱动之使用devicemapper(direct-lvm)模式

Docker存储驱动之OverlayFS简介

Docker存储驱动之ZFS简介