写在前面

我们在上篇学习了容器网络,对容器网络驱动bridge工作原理做了较为详细的介绍,今天小作文一起看看容器中另一个关键域-存储。


容器的存储可以分为两大类:

一种是与镜像相关的即我们在《docker容器技术基础之联合文件系统OverlayFS》一文提到的容器层Copy-On-Write特性。默认情况下,在容器内创建的所有文件都存储在可写容器层上,这种直接将文件存储在容器层的方式数据难以持久化和共享,由于依赖存储驱动与使用直接写入主机文件系统的数据卷相比,这种额外的抽象会降低性能 。

另一中是宿主机存储即通过将宿主机目录绑定或挂在到容器中使用,容器停止后数据也能持久化。小作文主要介绍后者。


几种存储挂载方式

这里我们根据数据存储在 Docker 主机上的不同位置绘制如下图:

1.bind mounts

绑定挂载与卷相比,功能有限。使用绑定挂载时,主机上的文件或目录会挂载到容器中。文件或目录由其在主机上的完整路径引用。目录不需要已经存在于 Docker 主机上,如果不存在,docker会帮我们创建。注意一下,只能自动创建目录哦。

我们通过 -v 选项绑定挂载一个目录 /nginx/html 到容器中看看

docker run -dt -v /nginx/html:/usr/share/nginx/html --name nginx nginx

通过docker inspect nginx 查看容器 Mounts字段

"Mounts": [
{
"Type": "bind",
"Source": "/nginx/html",
"Destination": "/usr/share/nginx/html",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],

接着我们在docker主机上创建一个index.html并写入hello nginx,然后访问容器IP,显然我们的挂载已经生效了。

[root@localhost ~]# echo "hello nginx" >  /nginx/html/index.html
[root@localhost ~]# curl 172.17.0.4
hello nginx

这里有一个问题,我们可以通过docker主机修改文件使容器内文件生效,反过来也一样,容器可以修改、创建和删除主机文件系统上的内容。处理这个问题我们可以在创建容器的时候配置挂载目录的权限,比如下面的只读权限:

docker run -dt -v /nginx/html:/usr/share/nginx/html:ro --name nginx nginx

所以在我们使用绑定挂载的时候,你操作的是主机文件系统,你必须清楚如下:

  • 你挂载的目录包含哪些内容,以免对其他应用造成影响。
  • 你的容器是否应该有权操作这些目录。

2.volumes

volume存储卷由 Docker 创建和管理,我们可以使用该docker volume create命令显式的创建卷,或者在容器创建时创建卷。

[root@localhost ~]# docker volume create nginx_volume
nginx_volume
[root@localhost volumes]# docker inspect nginx_volume
[
{
"CreatedAt": "2021-08-12T01:58:04-04:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx_volume/_data",
"Name": "nginx_volume",
"Options": {},
"Scope": "local"
}
]

可以看到挂载点处于docker的根目录/var/lib/docker/volumes下

通过docker volume rm/prune 清除单个或所有未再使用的卷,可以通过docker 命令来管理卷是对比绑定挂载的一个优势。

[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local owncloud-docker-server_files
local owncloud-docker-server_mysql
local owncloud-docker-server_redis
[root@localhost ~]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
owncloud-docker-server_files
owncloud-docker-server_mysql
owncloud-docker-server_redis Total reclaimed space: 199.4MB

在创建容器时如果未指定容器挂载的源则docker会自动为我们创建一个匿名卷,同样位于docker根目录下。

[root@localhost volumes]# docker run -dt -v /usr/share/nginx/html --name nginx_with_volume nginx
d25bdfce9c7ac7bde5ae35067f6d9cf9f0cd2c9cbea6d1bbd7127b3949ef5ac6
[root@localhost volumes]# docker volume ls
DRIVER VOLUME NAME
local d8e943f57d17a255f8a4ac3ecbd6471a735aa64cc7a606c52f61319a6c754980
local nginx_volume
[root@localhost volumes]# ls /var/lib/docker/volumes/
backingFsBlockDev d8e943f57d17a255f8a4ac3ecbd6471a735aa64cc7a606c52f61319a6c754980 metadata.db nginx_volume

当我们创建挂载卷之后,此时的存储与bind mounts是一致,不过当 docker 主机不能保证具有给定的目录或文件结构时,卷可帮助我们将 docker 主机的配置与容器运行时分离。这样一来当我们需要将数据从一台 Docker 主机备份、还原或迁移到另一台时,卷就很方便了,可以脱离host path的限制。

在使用绑定挂载和卷时我们要注意下面传播覆盖原则:

挂载一个空卷时:容器内目录的内容会传播(复制)到卷中。

绑定挂载或非空卷时:容器内目录的内容会被卷或绑定的主机目录覆盖。


3.tmpfs mount

tmpfs挂载仅适用于linux主机,当我们使用tmpfs挂载创建容器时,容器可以在容器的可写层之外创建文件。将数据保留在内存中,当容器停止时,写入的数据也将被移除。主要用于临时存储不想保留在主机或容器可写层中的敏感文件。

通过--tmpfs选项挂载一个内存块。

docker run -dt --name busybox_tmpfs --tmpfs /etc/running busybox

通过--mount的方式带上参数,指定临时存储大小。

docker run -dt --name busybox_tmpfs2 --mount type=tmpfs,tmpfs-size=2048,destination=/etc/running busybox

存储数据共享

在容器之间共享数据主要有两种方法,第一种比较简单,只需要将目录或者volume挂载到多个容器中即可。这里不做赘述,我们来看一下通过中间容器实现共享的方式。

我们创建一个中间容器,包含绑定挂载目录和一个卷。

docker create -v /share:/volume1 -v /volume2  --name volume_share  busybox

在我们需要共享的容器中通过选项--volumes-from拿过来用即可

docker run -d -t --volumes-from volume_share  --name container1  busybox

我们inspect检查一下Mounts字段,此时container1已经挂载到了一个bind目录和一个volume

"Mounts": [
{
"Type": "bind",
"Source": "/share",
"Destination": "/volume1",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "volume",
"Name": "21605e49a0ba90a1b952a32c1b3f0d42735da8bfe718f0dc76c37e91f1e51c0e",
"Source": "/var/lib/docker/volumes/21605e49a0ba90a1b952a32c1b3f0d42735da8bfe718f0dc76c37e91f1e51c0e/_data",
"Destination": "/volume2",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],

关于docker容器存储我们先学习到这,希望这篇小作文在你需要时对你有点用。

blog:iqsing.github.io

您可以随意转载、修改、发布本文章,无需经过本人同意。

docker容器存储的更多相关文章

  1. docker容器dockerfile详解

    docker公司在容器技术发展中提出了镜像分层的理念,可以说也是这个革命性的理念让原本只不过是整合linux内核特性的容器,开始野蛮生长. docker通过UnionFS联合文件系统将镜像的分层实现合 ...

  2. Swarm 如何存储数据?- 每天5分钟玩转 Docker 容器技术(103)

    service 的容器副本会 scale up/down,会 failover,会在不同的主机上创建和销毁,这就引出一个问题,如果 service 有要管理的数据,那么这些数据应该如何存放呢? 选项一 ...

  3. CentOS7更改Docker默认镜像和容器存储位置

    图片出处:https://bobcares.com/wp-content/uploads/docker-change-directory.jpg 一.Why? 通常,当你开始使用docker时,我们并 ...

  4. Hyperledger Fabric服务器配置及修改Docker容器卷宗存储根目录/位置

    Hyperledger Fabric节点服务器对存储空间的消耗还是比较大的,在我实际生产体验的过程中,每一条请求数据大概仅2K左右,但实际占用空间远不止这点,每个节点都会对Block及链进行保存维护, ...

  5. docker (2)---存储、网络(利用docker容器上线静态网站)

    一.docker底层依赖的核心技术 1.命名空间 (Namespaces) 2.控制组 (Control Groups) 3.联合文件系统 (Union File System) 4.Linux 虚拟 ...

  6. docker容器存放目录磁盘空间满了,转移数据修改Docker默认存储位置

    原文:docker容器存放目录磁盘空间满了,转移数据修改Docker默认存储位置 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_3767485 ...

  7. docker容器的持久化存储:Volume

    独立于docker容器的持久化存储: 法(1):自动将服务器文件夹挂载到容器内部文件夹/usr/share/nginx/html,这样只修改服务器文件夹下的内容即可对应修改容器内部文件夹的内容 将服务 ...

  8. 修改 Docker容器 自动启动/不自动启动,挂载路径,存储位置

    有时候创建容器时忘了添加参数 --restart=always,当 Docker 重启时,容器未能自动启动, 现在要添加该参数怎么办呢,方法有二: 1.Docker 命令修改 docker conta ...

  9. 利用谷歌开源工具cAdvisor 结合influxdb存储+Grafana前端展示进行Docker容器的监控

    一.Docker 监控方式 1.利用docker 的 docker stats API 命令: docker stats [容器ID/容器名称] [root@docker ~]# docker sta ...

随机推荐

  1. IDEA打开文件时,关闭SonarLint自动扫描

    操作步骤 1 打开 Preferences mac快捷键:command+, 2 搜索 SonarLint,取消勾选Automatically trigger analysis,保存设置

  2. Could not connect to 'xxx.xx.xx.xxx' (port 22): Connection failed.

    刚刚使用xshell好好的,突然注销账号,准备重新连接突然连不上了. 这就很尴尬了,对我这种linux菜鸟只能去百度了,终于解决了,赶紧记录下这个坑 1.先登陆虚拟机,输入这段命令 查看ssh服务是否 ...

  3. 刷算法,这些api不可不知!

    大家好,我是老三,最近在刷算法,发现有些api记得不熟,所以整理了一波,如果你也在刷题,赶紧收藏吧! 集合 在刷题中,各种数据结构是我们常常用到的,例如栈实现迭代.哈希存储键值对等等,我们来看看常用集 ...

  4. Vmware 恢复flat.vmdk和delta.vmdk

    背景: 一次客户现场突然掉电,导致虚拟机文件夹里面的文件丢失,只剩余-flat.vmdk和-delta.vmdk文件,其他文件全部丢失,文件格式原本为"文件"格式.新建虚拟机无法直 ...

  5. java编译通过,运行却提示找不到或无法加载主类

    问题: HelloWorld.java 1 package myP101; 2 3 public class HelloWorld { 4 public static void main(String ...

  6. 实验 2 Scala 编程初级实践

    实验 2 Scala 编程初级实践 一.实验目的 1.掌握 Scala 语言的基本语法.数据结构和控制结构: 2.掌握面向对象编程的基础知识,能够编写自定义类和特质: 3.掌握函数式编程的基础知识,能 ...

  7. [刘阳Java]_easyui-draggable拖动组件_第4讲

    easyui-draggable的拖动组件还是比较好用的,它能够快速地实现网页中元素的拖动效果 实现easyui-draggable拖动组件有两种方式:纯HTML方式和JS方式 纯HTML方式实现拖动 ...

  8. 高性能内存图数据库RedisGraph(二)

    这篇文章主要介绍用一下RedisGraph的历史和现状. 2018年5月,Redis Labs发布了RedisGraph的预览/测试版.6个月后,在Redis Labs和开源社区的开发者们的共同努力下 ...

  9. CSS 样式清单整理

    1.文字超出部分显示省略号 单行文本的溢出显示省略号(一定要有宽度) p{ width:200rpx; overflow: hidden; text-overflow:ellipsis; white- ...

  10. 大疆M3508、M2006必备CAN总线知识与配置方法

    使用大疆M3508.M2006的CAN总线知识与配置方法 目录 使用大疆M3508.M2006的CAN总线知识与配置方法 前言: 0x00 需要额外的CAN收发器!!! 0x01 硬件层面分析 为什么 ...