前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >拿捏docker+k8s系列--docker存储

拿捏docker+k8s系列--docker存储

作者头像
微客鸟窝
发布2022-05-24 13:08:37
5870
发布2022-05-24 13:08:37
举报
文章被收录于专栏:Go语言指北Go语言指北

Docker 为容器提供了两种存放数据的资源:

  • storage driver 管理的镜像层和容器层
  • Data Volume

storage driver

容器由最上面一个可写的容器层 + 若干只读的镜像层组成,容器的数据就存放在这些层中。

这样分层的特性就是 Copy-on-Write:

  • (1)新数据会直接存放在最上面的容器层。
  • (2)修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变。
  • (3)如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件。

分层结构使镜像和容器的创建、共享以及分发变得非常高效,而这些都要归功于 Docker storage driver。storage driver实现了多层数据的堆叠并为用户提供一个单一的合并之后的统一视图。

Docker 支持多种storage driver,有 AUFS、Device Mapper、Btrfs、OverlayFS、VFS 和 ZFS。它们都能实现分层的架构,同时又有各自的特性。Docker官方推荐优先使用 Linux 发行版默认的 storage driver.

Docker 安装时会根据当前系统的配置选择默认的 driver。默认driver 经过了严格的测试,具有最好的稳定性。

使用 docker info 命令可以查看默认的 driver:

Ubuntu 默认 driver用的是 AUFS,底层文件系统是 exts,各层数据存放在 /var/lib/docker/aufs。

❝对于那些无状态的应用容器,直接将数据放在由 storage driver 维护的层中是很好的选择,无状态意味着容器没有需要持久化的数据,随时可以从镜像直接创建,不需要保存数据供以后使用,使用完直接退出,容器删除时存放在容器层中的工作数据也一起被删除。 ❞

对于有状态的容器,有持久化数据的需求,容器在启动时需要加载已有的数据,销毁的时候需要保留产生的新数据,就需要使用 「Data Volume」 存储机制。

Data Volume

Data Volume 是Docker Host 文件系统中的目录或文件,能够直接被 mount 到容器的文件系统中。

Data Volume 的特点:

  • Data Volume 是目录或文件,而非没有格式化的磁盘(块设备)。
  • 容器可以读写 volume 中的数据。
  • 「volume 数据可以被永久地保存,即使使用它的容器已经销毁」

volume 是docker host 文件系统的一部分,所以 volume 的容量取决于文件系统当前未使用的空间,在具体的使用上,docker 提供了两种类型的 volume: bind mount 和 docker managed volume。

bind mount

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

运行容器时,使用 -v 来 mount 到容器上。

  • -v 的格式:<host path>:<container path>

例如,将 ~/data 挂载到 httpd 容器上,如下:

由于 /usr/local/apache2/htdocs 已经存在,原有的数据会被隐藏起来,使用的是挂载的 host 上的 ~/data/ 中的数据。我们修改 host 上的内容,再次查看,发现 bind mount 可以让 host 与容器共享数据,如下:

将容器销毁,可以看到 bind mount 也还存在,「bind mount 不会随着容器的销毁而删除」,如下:

读写权限

bind mount 还可以指定数据的读写权限,默认是可读可写,可以指定为只读:

docker run -d -p 8080:80 -v ~/data:/usr/local/apache2/htdocs:ro httpd

  • ro:设置了只读权限,在容器中便无法对 bind mount 数据进行修改。

docker managed volume

❝bind mount 不足的地方:bind mount 需要指定 host 文件系统的特定路径,这就限制了容器的可移植性,当需要将容器迁移到其他 host, 而该 host 没有要 mount 的数据或者数据不在相同的路径时,操作会失败。 移植性更好的方式是使用 docker managed volume。 ❞

docker managed volume 不需要指定 mount 源,指明 mount point 就可以了,同样使用 -v ,告诉 docker 需要一个 data volume,并 mount 到 /usr/local/apache2/htdocs :

docker run -d -p 8080:80 -v /usr/local/apache2/htdocs httpd

data volume 具体在哪?我们可以执行 docker inspect 命令在容器的配置信息中找到,如下(其他信息已省略):

其中 Mounts 这部分会显示容器当前使用的所有 data volume,包括 bind mount 和 docker managed volume。

「Source 就是该 volume 在 host 上的目录」 当容器申 请 mount docker manged volume 时,docker 都会在var/lib/docker/volumes 下生成一个目录(如:/var/lib/docker/volumes/b3ed2d6d09750f5b8ef4ea613ba38f2511ba1c122ff3db339a061c0ed0d6d41d/_data),这个日录就是 mount 源。 同时,如果 mount point 指向的是已有的目录(如上/usr/local/apache2/htdocs),原有的数据会被复制到 volume 中,所以我们 host 上生成的目录中的内容,会和 /usr/local/apache2/htdocs 中完全一致。 ❞

docker managed volume 创建过程:

  • 容器启动时,使用 -v ,告诉 docker 需要一个 data volume,并 mount 到 /a :。
  • docker 在var/lib/docker/volumes 中生成一个随机目录作为 mount源。
  • 如果/a 已经存在,则将数据复制到 mount 源。
  • 将 volume mount 到 /a。

数据共享

容器与 host 共享数据

  1. bind mount

例如前面的 httpd 例子,可直接将需要共享的目录 mount 到容器。

  1. docker managed volume

这种类型的 data volume 是在容器启动的时候才生成的,所以需要将共享的数据复制到 volume 中,如:

上面我们使用的是 docker cp ,我们还可以直接通过 linux 的 cp 命令复制到 /var/lib/docker/volumes/...中。

容器之间共享数据

1. bind mount

将共享数据放在 bind mount 中,然后将其 mount 到多个容器。

2. volume container

volume container 是专门为了给其他容器提供 volume 的容器,它提供的卷可以是 bind mount,也可以是 docker managed volume。

我们创建(docker create ...)一个名为 vc_data 的容器,vc 是 volume container 的缩写。创建容器,但不运行,因为 此容器只是提供数据,并不需要运行,如下:

容器 mount 两个 volume:

  • bind mount
  • docker managed volume

docker inspect 看下俩 volume:

--volumes-from

其他容器通过 --volumes-from 来使用 vc_data 这个 volume container :

以 httpd1 为例,看下 volume:

数据共享效果:

3. data-packed volume container

上面的 volume container 的数据其实还是在 host 里,而 data-packed volume container 是将数据打包到镜像中,再通过 docker managed volume 共享。

通过如下 Dockerfile 构建镜像 datapacked :

❝ADD 将静态文件添加到容器目录 usr/local/apache2/htdocs. VOLUME 的作用与 -v 等效,用来创建 docker managed volume,mount point为 usr/local/apache2/htdocs,因为这个目录就是 ADD 添加的目录,所以会将已有数据复制到volume中。 ❞

用新镜像创建 data-packed volume container:

Dockerfile 中我们使用了 VOLUME 指令,这里就不需要指定 volume 的mount point 了。启动 httpd 容器并使用 data-packed volume container:

❝容器能够正确读取volume中的数据。data-packed volume container 是自包含的,不依赖 host,具有很强的移植性,非常适合只使用静态数据的场景,比如应用的配置信息、Web server的静态文件等。 ❞

Data Volume 管理

Data Volume 中存放的是重要的应用数据,我们应该重视对 volume 的备份、恢复、销毁等操作。

备份

volume 其实就是 host 文件系统中的资源,备份的话实际上就是对文件系统的备份。

恢复

volume 的恢复,只需要将之前备份数据复制到 volume 中即可。

销毁

需要注意的是,volume 删除后数据便找不回来了。

  1. bind mount

docker 不会销毁 bind mount,删除数据的工作只能由 host负责。

  1. docker managed

在执行docker rm 删除容器时使用 -v 参数,docker会将容器使用到的 volume 一起删除,「前提是该 volume 没有其他容器使用」,这样可以做到对数据的保护。

如果没有使用 -v 参数,那么就会产生孤儿 volume,后期我们可以使用 docker volume 命令对其维护。

  • docker volume create :创建一个卷
  • docker volume inspect :显示一个或多个卷的详细信息
  • docker volume ls :列出卷
  • docker volume prune :删除所有未使用的卷
  • docker volume rm :删除一个或多个卷
    • docker volume rm $(docker volume ls -q) :批量删除孤儿 volume

❝删除一个或多个卷。无法删除容器正在使用的卷。 ❞

总结

  • storage driver : 容器内的存储,管理镜像层和容器层
    • docker info 命令:查看系统默认的 driver
  • Data Volume :容器外的存储
    • bind mount :手动挂载目录
    • docker managed volume :docker 启动时自动生成目录
  • docker volume 命令:管理卷
  • docker inspect 命令:查看容器的配置信息

图片及部分相关技术知识点来源于网络搜索,侵权删!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微客鸟窝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • storage driver
  • Data Volume
    • bind mount
      • docker managed volume
      • 数据共享
        • 容器与 host 共享数据
          • 容器之间共享数据
          • Data Volume 管理
            • 备份
              • 恢复
                • 销毁
                • 总结
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档