关于docker容器存储问题

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

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

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

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挂载到多个容器中即可。这里不做赘述,我们来看一下通过中间容器实现共享的方式。

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

在容器之间共享数据主要有两种方法,第一种比较简单,只需要将目录或者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": ""
    }
],

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Docker容器是一种轻量级容器化技术,它通过隔离和封装应用程序及其依赖环境,将应用程序打包为一个独立的容器,使其可以在任何环境中快速、可移植地运行,实现了应用程序的快速部署和可扩展性。 云计算中的Docker容器工作架构主要包括以下几个关键组件: 1. Docker Daemon:Docker守护进程,负责管理和运行Docker容器。它监听来自Docker客户端的命令,并根据配置和指令创建、启动、停止、重启和销毁容器。 2. Docker客户端:用户与Docker Daemon进行交互的工具。通过Docker客户端,用户可以使用命令行或API发送指令来管理Docker容器的创建、启动、停止等操作。 3. Docker镜像:Docker容器运行的基础,是一个只读的模板,包含了完整的应用程序运行所需的文件系统、库文件、配置等。用户可以通过Docker镜像创建Docker容器,一个镜像可以创建多个容器。 4. Docker容器:基于Docker镜像创建的可运行实例,每个容器都是相互隔离的环境,并且具有自己的文件系统、进程空间和网络接口。容器中运行的应用程序可以与宿主机和其他容器进行通信。 5. Docker仓库:用于存储和分享Docker镜像的集中式存储库。Docker仓库分为公共仓库(如Docker Hub)和私有仓库。用户可以将自己创建的镜像推送到仓库,并从仓库中拉取他人分享的镜像。 6. Docker网络:Docker可以创建多种类型的网络,如桥接网络、主机网络和覆盖网络,用于连接和通信不同的容器。它还可以通过端口映射将宿主机的端口映射到容器内部,实现容器和外部网络的通信。 在云计算中使用Docker容器,可以实现应用程序的快速部署、弹性伸缩和资源利用的最大化。通过Docker容器,用户可以将应用程序和其依赖环境打包为一个可移植的单元,并在云平台中轻松部署和管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值