docker 的btrfs存储驱动–/var/lib/docker/btrfs文件夹占用过大

最近有个私有服务,每隔一段时间就存储满了,开始是因为docker镜像太多,然后就docker image prune 清理了一下未使用的缓存,但是效果不好。后面使用du -h --max-depth=1 一点点找这个占用磁盘的文件夹,终于找到了一个/var/lib/docker/btrfs 占用了90G

btrfs

这是一个文件系统(B-tree filesystem 用于linux里面,对于docker来说它的很多优点很符合docker 的要求

  1. 复制功能:Btrfs支持文件和目录的快速复制,无论文件大小如何,都可以在瞬间完成。这对于创建快照、备份和克隆非常有用。

  2. 写时复制(Copy-on-Write):Btrfs使用写时复制技术来提高性能和数据一致性。当文件需要修改时,Btrfs会将修改后的数据写入新的位置,而不会直接修改原始数据。这样可以避免数据污染和数据丢失的风险。

  3. 快照:Btrfs支持快照功能,可以在文件系统的任意时间点创建快照。这些快照可以用于备份、版本控制和恢复数据。快照只记录文件系统中的差异,因此可以在较短的时间内创建大量的快照。

docker 使用了btrfs的哪些功能

  1. 快照 docker save能保存容器的运行时数据,就主要用了这个
  2. 复制和克隆:Btrfs支持快速复制和克隆文件和目录。Docker可以利用Btrfs的复制功能来快速创建镜像和容器的副本,而无需实际复制所有的数据。这样可以节省存储空间,并且可以在瞬间创建多个相同的镜像或容器。这个是docker 在一个机器上实现快速实例化的技术保证
  3. 分层:btrfs支持写时复制,docker镜像分成了镜像层和可写容器层,在镜像层就可以底层共享,可写容器层cow

docker 使用btrfs 读写数据流程

Docker使用Btrfs进行容器读写操作的流程大致如下:

读取操作:当启动一个容器时,Docker实际上会创建一个快照。这个快照中的元数据指向存储池中的实际数据块。因此,当读取容器中的数据时,Docker会通过这个快照来访问实际的数据。

写入操作:向容器写入数据有两种主要情况。首先,当向容器中写入新文件时,Docker会执行按需分配操作,为新数据分配数据块,并将文件写入这个新的数据块中。其次,当修改容器中的现有文件时,Docker执行写时复制操作。它会从文件当前所在的层读取原始数据,只有修改后的数据块会被写入容器的可写层。之后,Btrfs驱动程序会更新快照中的文件系统元数据以指向这个新数据。

docker 如何使用的btrfs呢

首先既然是个文件系统,那肯定不能和真实服务器上的文件系统混着用,所以就其实走的还是新建存储区写上btrfs系统,然后挂载到一个文件夹的流程

mount 直接能看到
/dev/sda3 on /var/lib/docker/btrfs type btrfs (rw,relatime,ssd,space_cache,subvolid=259,subvol=/@/.snapshots/1/snapshot/var/lib/docker/btrfs)
用mount 把我sda3磁盘里面的一个btrfs文件系统的给挂载到/var/lib/docker/btrfs 上了

为啥会有文件会过大

看到上面的流程就知道了,不写的数据类似镜像层是快照,然后容器里面加日志啥的是可写层,这样就说明容器太多,删除了容器没有回收这个容器对应的/var/lib/docker/btrfs/subvolumes 下面的快照层可写层。这个其实也是因为容器配置的不好,容器更新的时候用的命令不对,清理子券docker image prune


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注