欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Docker存储、数据共享、Volume生命周期管理

程序员文章站 2022-05-11 14:14:19
...

Storage driver

  • Copy-on-Write:
  1. 新数据会直接存放在最上面的容器层。
  2. 修改现有数据会从镜像层将数据复制到容器层,修改后的数据直接保存在容器层,镜像层保持不变。
  3. 如果多个层中有命名相同的文件,用户只能看到最上面层的文件。
  • Storage driver实现了多层数据的堆叠并为用户提供一个单一的合并之后的统一视图。

  • Docker支持多种storage driver,有AUFS,Device Mapper,Btrfs,OverlayFS,VFS和ZFS
    通过docker info |grep Storage查看类型
    Docker存储、数据共享、Volume生命周期管理

Data Volume

Data Volume本质上是Docker Host文件系统中的目录或文件,能够直接被mount到容器的文件系统中。
Data Volume特点:
1 Data Volume是目录或者文件,而非没有格式化的磁盘(块设备)。
2 容器可以读写Volume中的数据。
3 Volume数据可以永久的保存,即使容器已被销毁

bind mount

bind mount是将host上已存在的目录或文件挂载到容器。

  • 实验举例:
  mkdir -p /root/htdocs
  vim /root/htdocs/index.html
  <html><body><h1>This is a web in host file system!</h1></body></html>
  docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs httpd

登录网页即可查看:
Docker存储、数据共享、Volume生命周期管理

-v格式为:<host path>:<container path>
/usr/local/apache2/htdocs是Apache Server存取静态文件的地方。原有数据就会被隐藏起来,取而代之的就是host上的~/htdocs的数据。
我们可以更新一下数据,刷新网页查看一下:
echo "<h1>update host web!</h1>" > ~/htdocs/index.html

Docker存储、数据共享、Volume生命周期管理

  • bind mount可以使容器与host共享数据,这样更有利于管理。
  • 容器销毁则不会对bind mount产生影响。
#bind mount还可以指定数据的读写权限默认是可读可写,我们可以通过ro设置为只读:
docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs:ro httpd
docker exec -it cae183d0c6ba /bin/bash
echo "hello world" > htdocs/index.html
  • 总结bind mount优缺点:
  • 优点:直观高效,易于理解
  • 缺点:需要指定host文件系统特定路径,移植性差

docker managed volume

  • 与bind mount最大的区别就是不需要指定mount源,指定mount point就可以了。
  #实验举例:
  docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
  • 这个data volume在哪呢?我们可以通过docker inspect查找:
    Docker存储、数据共享、Volume生命周期管理
    Docker存储、数据共享、Volume生命周期管理
  • 我们只需要看Mounts里面的内容就可以了,Source就是volume在host上的目录
  • volume的内容和容器/usr/local/apache2/htdocs里面的内容完全一样,因为mount point指向的是已有目录,原有数据会被复制到volume中。/usr/local/apache2/htdocs不再是storage driver管理的数据了,而是data volume,我们可以和bind mount一样操作。
 echo "<h1>hello web.</h1>" > /var/lib/docker/volumes/2212275f044d0cc76177b9709aeb654d77e0b0927579bccb3492e439aa5cf603/_data/index.html

Docker存储、数据共享、Volume生命周期管理

  • docker volume创建过程:
    1 容器启动时,简单告诉docker“我需要一个volume存放数据”,帮我挂载到目录/dir。
    2 docker在/var/lib/docker/volumes/下随机生成一个目录作为挂载源。
    3 如果/dir已存在则会将数据复制到挂载源。
    4 将volume挂载到/dir。

  • 查看volume
    Docker存储、数据共享、Volume生命周期管理

两者区别

相同点:两者都是host文件系统的某个路径
不同点:见下表

不同点 bind mount docker managed volume
volume位置 可任意指定 /var/lib/docker/volumes/…
对已有mount point影响 隐藏并替换volume 原有数据复制到volume
是否支持单个文件 支持 不支持,只是目录
权限控制 可以设置为只读,默认读写 不可以,均为读写
移植性 移植性弱,与host path绑定 移植性强,无需指定host目录

数据共享

数据共享是volume的关键特性。

容器与host共享数据

  • 有两种类型的data volume均可以实现在容器与host之间共享数据,但是方式有所区别。
  • bind mount:直接将要共享的目录mount到容器。
  • docker managed volume:由于volume位于host中的目录,是在容器启动时才生成,所以需要将共享数据复制到volume。
    Docker存储、数据共享、Volume生命周期管理

容器之间共享数据

#创建三个httpd容器组成的Web server群集。
docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
docker run --name web2 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
docker run --name web3 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd

Docker存储、数据共享、Volume生命周期管理

  • 查看当前主页内容
    Docker存储、数据共享、Volume生命周期管理

  • 修改volume主页文件,再次查看并确认所有容器使用了新容器
    Docker存储、数据共享、Volume生命周期管理

Volume Container

  • Volume container是专门为其他容器提供volume的容器。它提供的卷可以是bind mount也可以是docker managed volume。
  1. 创建一个volume container
    Docker存储、数据共享、Volume生命周期管理
    bind mount,存放web静态页面
    docker managed volume存放实用工具
  2. 使用docker inspect vol_con查看
    Docker存储、数据共享、Volume生命周期管理
  • 其他容器可以通过–volumes-from使用vol_con。

  • volume container特点:

  1. 与bind mount相比,不必为每个容器指定host path,所有path都在Volume container中定义好了。容器只需与volume container关联,实现了容器与host解耦。
  2. 使用volume container的容器,其mount point是一致的,有利于配置的规范化和标准化,但也带来了一定的局限。
  • 如何将数据完全放到volume container中,同时也能与其他容器共享呢?
  • 这种容器我们称为docker-packed volume container,通过Dockerfile实现

Docker存储、数据共享、Volume生命周期管理
Docker存储、数据共享、Volume生命周期管理
Docker存储、数据共享、Volume生命周期管理

  • data-packed不依赖host提供数据,具有很强的移植性,非常适合静态数据场景。

Volume生命周期管理

备份

  • volume实际上是host文件系统中的目录和文件,所以volume的备份实际上是对文件系统的备份。
  • 所有的本地镜像都保存在host的/myregistry目录中,我们要定期备份这个目录。

恢复

  • volume恢复也很简单,如果数据损坏了,直接用之前备份的数据复制到/myregistry中。

迁移

  • 如果我们需要使用更新版本的Registry,就需要数据迁移。
  1. docker stop 当前Registry容器
  2. 启动新版本容器并mount原有volume
docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:latest
  • 在启动新容器前要确保新版本默认数据路径是否发生变化

销毁

  • 可以删除不再需要的volume,但一定要确保自己在做什么,volume删除后数据是找不回来的。
  • docker不会销毁bind mount,删除只能由host负责。对于docker managed volume,执行docker rm时,加上-v 参数,docker会讲容器使用到的volume一并删除,但前提是没有其它容器挂载到该volume,目的是保护数据。
  • 如果不加-v就会产生孤儿volume
  • 如何批量删除孤儿容器?
docker volume rm $(docker volume ls -q)