docker存储

docker存储

文章目录

Docker 两种存放数据资源

  1. 由 storage driver 管理的镜像层和容器层。
    • 容器由最上面一个可写的容器层,以及若干只读的镜像层组成,容器的数据就存放在这些层中。这样的分层结构最大的特性是 Copy-on-Write。对于某些容器,直接将数据放在由 storage driver 维护的层中是很好的选择,比如那些无状态的应用。无状态意味着容器没有需要持久化的数据,随时可以从镜像直接创建。
  2. Data Volume。
    • 是目录或文件,而非没有格式化的磁盘。数据可以被永久的保存,即使使用它的容器已经销毁。
bash 复制代码
#查看CentOS的默认 driver
[root@docker ~]# docker info

#CentOS Stream 8 用的overlay2,底层文件系统是xfs,各层数据存放在 /var/lib/docker。

Data Volume

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

bind mount

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

bash 复制代码
#例如 docker host 上有目录 $HOME/htdocs:
[root@docker ~]# pwd
/root
[root@docker ~]# mkdir htdocs
[root@docker ~]# cd htdocs/
[root@docker htdocs]# touch index.html
[root@docker htdocs]# vim index.html
<html><body><h1>This is a file in host file system !</h1></body></html>
[root@docker htdocs]# cd ..
[root@docker ~]# cat htdocs/index.html
<html><body><h1>This is a file in host file system !</h1></body></html>

#通过 -v 将其 mount 到 httpd 容器:
[root@docker ~]# docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs httpd

[root@docker ~]# curl 127.0.0.1:80
<html><body><h1>This is a file in host file system !</h1></body></html>

[root@docker ~]# echo "updated index page!" > ~/htdocs/index.html
[root@docker ~]# curl 127.0.0.1:80
updated index page!

#容器销毁
[root@docker ~]# docker stop 883f8a22b2be
883f8a22b2be
[root@docker ~]# docker rm 883f8a22b2be
883f8a22b2be
[root@docker ~]# cat ~/htdocs/index.html
updated index page!

#指定数据的读写权限,默认是可读可写,可指定为只读
[root@docker ~]# docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs:ro 
httpd
bf1f526ddde7a7babb29adc091eef039628ba2eb288e6db33c9ccd946cc5d5f1
[root@docker ~]# docker exec -it bf1f526ddde7 bash
root@bf1f526ddde7:/usr/local/apache2# echo "do some changes" > htdocs/index.html
bash: htdocs/index.html: Read-only file system

#单独指定一个文件

#删除上一个容器不然80端口冲突
[root@docker ~]# docker rm - f bf1f526ddde7
#运行新容器用单独文件绑定
[root@docker ~]# docker run -d -p 80:80 -v 
~/htdocs/index.html:/usr/local/apache2/htdocs/new_index.html httpd
643e8820e98a17b977a984903ddfa6f37dcae3d705d45b624d0fce5c94fecb0c
[root@docker ~]# curl 127.0.0.1:80
<html><body><h1>It works!</h1></body></html>
[root@docker ~]# curl 127.0.0.1:80/new_index.html
updated index page!

#使用 bind mount 单个文件的场景是:只需要向容器添加文件,不希望覆盖整个目录。

docker managed volume

docker managed volume 与 bind mount 在使用上的最大区别是不需要指定 mount 源,指明 mount point 就行。

创建过程
  1. 容器启动时,简单的告诉 docker "我需要一个 volume 存放数据,帮我 mount 到目录 /abc"。
  2. docker 在 /var/lib/docker/volumes 中生成一个随机目录作为 mount 源。
  3. 如果 /abc 已经存在,则将数据复制到 mount 源。
  4. 将 volume mount 到 /abc
bash 复制代码
[root@docker ~]# docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd

#查找data volume具体位置
[root@docker ~]# docker inspect c75f36c4bf32 #docker inspect后面跟的是容器ID

[root@docker ~]# ls -l 
/var/lib/docker/volumes/1cc915096121dea197bbbb93fc90e6491d530e0c9e2ace1de07e2a635
e569d16/_data
total 4
-rw-r--r-- 1 501 ftp 26 Sep 17 21:08 index.html
[root@docker ~]#
[root@docker ~]# curl 127.0.0.1:80
<html><body><h1>It works!</h1></body></html>

#如果 mount point 指向的是已有目录,原有数据会被复制到 volume 中。

#它已经是一个 data volume。我们可以像 bind mount 一样对数据进行操作,更新数据。

#除了通过 docker inspect 查看 volume,我们也可以用 docker volume 命令

[root@docker ~]# docker volume ls
DRIVER   VOLUME NAME
local     1cc915096121dea197bbbb93fc90e6491d530e0c9e2ace1de07e2a635e569d16
[root@docker ~]#
[root@docker ~]# docker volume inspect 1cc915096121dea197bbbb93fc90e6491d530e0c9e2ace1de07e2a635e569d16

共享数据

容器与 host 共享数据

docker cp 可以在容器和 host 之间拷贝数据,当然我们也可以直接通过 Linux 的 cp 命令复制到 /var/lib/docker/volumes/xxx。

bash 复制代码
#docker managed volume 

[root@docker ~]# docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
889b9d5309bd12499f8e4ee78a491d9ba7acef5660be00f30cda6569c9974c6f
[root@docker ~]#
[root@docker ~]# curl 127.0.0.1:80
<html><body><h1>It works!</h1></body></html>
[root@docker ~]#
[root@docker ~]# docker cp ~/htdocs/index.html 889b9d5309bd:/usr/local/apache2/htdocs  #将host os的/root/htdocs/index.html拷贝到容器中的/usr/local/apache2/htdocs目录下
Successfully copied 2.05kB to 889b9d5309bd:/usr/local/apache2/htdocs
[root@docker ~]#
[root@docker ~]# curl 127.0.0.1:80
updated index page!
[root@docker ~]#
容器之间共享数据
bash 复制代码
[root@docker ~]# docker run --name web1 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
994e75ef90a80365d7ea7733c727c3b1d24e5423d59a74185304462b7137d774
[root@docker ~]#
[root@docker ~]# docker run --name web2 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
28ff7c72d18b30123ff7e383db211890a0007e48817cdc73e7f50e9f2233eee6
[root@docker ~]#
[root@docker ~]# docker run --name web3 -d -p 80 -v ~/htdocs:/usr/local/apache2/htdocs httpd
160d823d985bad0ce7c27a0d301956f3c7ab4e9ca34c5be2601b3374fa30f6f1
[root@docker ~]#

[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                                     NAMES
160d823d985b   httpd     "httpd-foreground"   13 seconds ago   Up 12 seconds   0.0.0.0:32770->80/tcp, :::32770->80/tcp   web3
28ff7c72d18b   httpd     "httpd-foreground"   19 seconds ago   Up 18 seconds   0.0.0.0:32769->80/tcp, :::32769->80/tcp   web2
994e75ef90a8   httpd     "httpd-foreground"   29 seconds ago   Up 27 seconds   0.0.0.0:32768->80/tcp, :::32768->80/tcp   web1
[root@docker ~]#
[root@docker ~]# curl 127.0.0.1:32770                #这个32770端口是host os映射到web3的duan'k
updated index page!
[root@docker ~]# curl 127.0.0.1:32769
updated index page!
[root@docker ~]# curl 127.0.0.1:32768
updated index page!
[root@docker ~]#

[root@docker ~]# echo "This is a new index page for web cluster" > ~/htdocs/index.html
[root@docker ~]#
[root@docker ~]# curl 127.0.0.1:32770
This is a new index page for web cluster
[root@docker ~]# curl 127.0.0.1:32769
This is a new index page for web cluster
[root@docker ~]# curl 127.0.0.1:32768
This is a new index page for web cluster
[root@docker ~]#
用volume container共享数据

容器只需与 volume container 关联,实现了容器与 host 的解耦

容器 mount 了两个 volume:

  1. bind mount,存放 web server 的静态文件。
  2. docker managed volume,存放一些实用工具(当然现在是空的,这里只是做个示例)。
bash 复制代码
[root@docker ~]# docker create --name vc_data \
 -v ~/htdocs/:/usr/local/apache2/htdocs \
 -v /other/userful/tools \
 busybox
bb4a33bf34aa7817ea752db83079aff15a5dfd77c23363f2e8dd3096d1cb910f

[root@docker ~]# docker inspect vc_data
...
        "Mounts": [
            {
                "Type": "volume",
                "Name": "4500300655eb8e32a5d88174395a61ea394e17266fbde60f224d815a7a9557e0",
                "Source": "/var/lib/docker/volumes/4500300655eb8e32a5d88174395a61ea394e17266fbde60f224d815a7a9557e0/_data",
                "Destination": "/other/userful/tools",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "bind",
                "Source": "/root/htdocs",
                "Destination": "/usr/local/apache2/htdocs",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
...

#其他容器可以通过 `--volumes-from` 使用 `vc_data` 这个 volume container

[root@docker ~]# docker run --name web1 -d -p 80 --volumes-from vc_data httpd
362f039b562e4bf0020c38839a69bfd62733f27fda5481eb5b58178f41318ffe
[root@docker ~]#
[root@docker ~]# docker run --name web2 -d -p 80 --volumes-from vc_data httpd
217c1a243bb9a1f32ccae9ae2792e3720263d36402bbac58f43cfb068bc21e66
[root@docker ~]#
[root@docker ~]# docker run --name web3 -d -p 80 --volumes-from vc_data httpd
ce00b5fa458fc1af01e82ce8b43e8c072c858a669c1298add8053cbc7ac9f49b
[root@docker ~]#
data-packed volume container

data-packed volume container 是自包含的,不依赖 host 提供数据,具有很强的移植性,非常适合 只使用 静态数据的场景,比如应用的配置信息、web server 的静态文件等。

bash 复制代码
[root@docker ~]# vim Dockerfile
FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs

[root@docker ~]# echo "This content is from a data packed volume container!" > htdocs/index.html

[root@docker ~]# docker build -t datapacked .

[root@docker ~]# docker create --name vc_data datapacked
55dc035deeb31907830ea45f7af5e209c7e48078d59732798c529e7445d2a196

[root@docker ~]# docker run -d -p 80:80 --volumes-from vc_data httpd
98db78fc661441ec7ce0a2b76d62675fccf3389b7768cc9744b852645323c33b
[root@docker ~]#
[root@docker ~]# curl 127.0.0.1:80
This content is from a data packed volume container!

volume生命周期管理

备份

bash 复制代码
[root@docker ~]# docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
1cc3d825d8b2: Pull complete
85ab09421e5a: Pull complete
40960af72c1c: Pull complete
e7bb1dbb377e: Pull complete
a538cc9b1ae3: Pull complete
Digest: sha256:ac0192b549007e22998eb74e8d8488dcfe70f1489520c3b144a6047ac5efbe90
Status: Downloaded newer image for registry:2
a8214201171f28a13803c647ef84acdc982465c230cb5c6a034bd05574948408
[root@docker ~]#

#所有的本地镜像都存在 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 一并删除,但前提是没有其他容器 mount 该 volume,目的是保护数据。

如果删除容器时没有带 -v ,这样就会产生孤儿 volume,好在 docker 提供了 volume 子命令可以对 docker managed volume 进行维护。

bash 复制代码
[root@docker ~]# docker volume ls
DRIVER    VOLUME NAME
[root@docker ~]#
[root@docker ~]# docker run --name bbox -v /test/data busybox
[root@docker ~]#
[root@docker ~]# docker volume ls
DRIVER    VOLUME NAME
local     8645b8e2edb91820799e6e8807d8b3476f1c5cec40beb14240b0e5143050e5e1

[root@docker ~]# docker rm bbox
bbox
[root@docker ~]# docker volume ls
DRIVER    VOLUME NAME
local     8645b8e2edb91820799e6e8807d8b3476f1c5cec40beb14240b0e5143050e5e1
[root@docker ~]#

[root@docker ~]# docker volume rm 8645b8e2edb91820799e6e8807d8b3476f1c5cec40beb14240b0e5143050e5e1
8645b8e2edb91820799e6e8807d8b3476f1c5cec40beb14240b0e5143050e5e1
[root@docker ~]#
[root@docker ~]# docker volume ls
DRIVER    VOLUME NAME
[root@docker ~]#

#批量删除
docker volume rm $(docker volume ls -q)

4240b0e5143050e5e1

root@docker \~\]# \[root@docker \~\]# docker volume rm 8645b8e2edb91820799e6e8807d8b3476f1c5cec40beb14240b0e5143050e5e1 8645b8e2edb91820799e6e8807d8b3476f1c5cec40beb14240b0e5143050e5e1 \[root@docker \~\]# \[root@docker \~\]# docker volume ls DRIVER VOLUME NAME \[root@docker \~\]# #批量删除 docker volume rm $(docker volume ls -q) ``` ```

相关推荐
风向决定发型丶2 分钟前
K8S PDB介绍
云原生·容器·kubernetes
Agent产品评测局8 分钟前
图片生成智能体哪家好?2026年企业级视觉创作与自动化选型全景横评
运维·人工智能·ai·自动化
猫头虎-人工智能12 分钟前
ToDesk ToClaw AI自动化实测:零门槛玩转日常自动化,告别折腾与硬件损耗
运维·人工智能·架构·开源·自动化·aigc·ai编程
实在智能RPA12 分钟前
Agent 能做流程的自动化监控吗?——深度拆解2026年AI智能体在企业级闭环监控中的技术实践
运维·人工智能·ai·自动化
翱翔-蓝天22 分钟前
WSL + Docker + GPU 安装 video-subtitle-remover 完整文档
运维·docker·容器
云飞云共享云桌面25 分钟前
研发部门使用SolidWorks和ug,cad,设计共享云桌面应该怎么选?
运维·服务器·网络·人工智能·3d
江湖有缘26 分钟前
PanCheck 容器化部署:自建网盘链接检测服务全流程
docker
麦聪聊数据30 分钟前
数据库安全与运维管控(五):基于AST的SQL拦截与动态审批
运维·数据库·sql
亚空间仓鼠32 分钟前
OpenEuler系统常用服务(十)
linux·运维·服务器·网络
艾莉丝努力练剑32 分钟前
【Linux线程】Linux系统多线程(四):线程ID及进程地址空间布局,线程封装
java·linux·运维·服务器·c语言·c++·学习