当前位置: 首页 > news >正文

Docker-存储

一、Docker存储概述

1.数据卷特性

  • Docker镜像由多个只读层构成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层
  • 如果运行中的容器修改了现有的一个只读的文件,该文件会从只读层复制到读写层,只读版本依旧存在,但已经被读写层的副本所覆盖了此即写时复制(copy-on-write)机制

  • 这个设计使得Docker可以提高镜像构建、存储和分发的效率,节省了时间和存储空间,然而也存在如下问题:
  1. 存在于联合文件系统中,不能在宿主机上很方便地对容器中的文件进行访问。

  2. 多个容器之间的数据无法共享。

  3. 当删除容器时,容器产生的数据将丢失

  • 为了解决这些问题,Docker引入了数据卷(volume)机制,此卷可以绕过联合文件系统,与宿主机上的目录绑定

2.数据卷结构

  • - volumes:  /var/lib/docker/volumes/ 卷的名字 
  • - bind mounts:宿主机任意位置目录或文件 
  • - tmpfs   :内存中空间,不会写入主机文件系统

3.数据卷优点

  • volume 在容器创建时就会初始化,在容器运行时就可以使用其中的文件
  • volume 能在不同的容器之间共享和重用
  • 对volume中数据的操作会马上生效
  • 对volume中数据的操作不会影响到镜像本身
  • volume 的生存周期独立于容器的生存周期,即使删除容器,volume 仍然会存在,没有任何容器使用的volume也不会被Docker删除

二、使用 Volume

1.创建 volume

# 删除所有容器和卷
[root@localhost ~]# docker rm $(docker ps -aq) -f
[root@localhost ~]# docker volume rm $(docker volume ls -q)# 创建volume
[root@localhost ~]# docker volume create  my-vol
my-vol
[root@localhost ~]# docker volume  ls
DRIVER    VOLUME NAME
local     my-vol
[root@localhost ~]# ll /var/lib/docker/volumes/
总用量 52
brw-------  1 root root 259, 3 11月 12 08:32 backingFsBlockDev
-rw-------. 1 root root  65536 11月 12 08:40 metadata.db
drwx-----x  3 root root     19 11月 12 08:40 my-vol

注:Docker当前并未对volume的大小提供配额管理;用户在创建volume时无法指定volume的大小

注:my_vol下还有一层目录,挂载的时候实际上是把这个目录挂载到容器中

其他创建方式:

# 如果没有创建卷,在启动容器时挂载,也会自动创建
[root@localhost ~]# docker run -d -v nginx-vol:/data nginx:1.22.1
d406b3a496d429452566de1d612edaed5bc493322fde1b8e8a683df028bb0c80
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     my-vol
local     nginx-vol# 匿名卷的创建方式,不选定挂载卷
$ docker run -d -v /data nginx:1.22.1# 启动mysql容器时,即便不手动挂载,也会自动挂载一个匿名卷
[root@localhost ~]# docker run -d -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0
DRIVER    VOLUME NAME
local     a54dc0b6a13954740884a4b15396e1341c73a8f123453e6e35610c012d53291c
local     my-vol
local     nginx-vol# 在启动mysql容器时,VOLUME [/var/lib/mysql]指令会在启动mysql容器时创建匿名卷并挂载到/var/lib/mysql目录下
[root@localhost ~]# docker history mysql:8.0
IMAGE          CREATED       CREATED BY                                       SIZE     <missing>      3 weeks ago   VOLUME [/var/lib/mysql]                          0B        buildkit.dockerfile.v0

注:一般情况下尽量不使用匿名卷,匿名卷多了之后我们是看不到是哪个容器在用它;启动mysql容器时也可以直接挂载新卷组覆盖匿名卷

[root@localhost ~]# docker run -d -e MYSQL_ROOT_PASSWORD=123456 -v mysql-vol:/var/lib/mysql mysql:8.0
30e6d41f8e92920c77c345076ecd423bf15b106ed4aa156b77b4471ee8daba3e
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     a54dc0b6a13954740884a4b15396e1341c73a8f123453e6e35610c012d53291c
local     my-vol
local     mysql-vol
local     nginx-vol

2.添加 volume

[root@localhost ~]# docker run -d -v my-vol:/data nginx:1.22.1
06cbbfe23d1c5f6333414c60d4e153d88e55e7c41e4aa2269f2eed74b8f9f164
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS     NAMES
06cbbfe23d1c   nginx:1.22.1   "/docker-entrypoint.…"   15 seconds ago   Up 14 seconds   80/tcp    priceless_napier
[root@localhost ~]# docker exec -it 06cbbfe23d1c bash
root@06cbbfe23d1c:/# cd /data/
root@06cbbfe23d1c:/data## 宿主机中创建文件
[root@localhost _data]# touch host_file
# 容器中同样可以查看
root@06cbbfe23d1c:/data# ls
host_fileroot@06cbbfe23d1c:/data# touch docker-file
[root@localhost _data]# ll
总用量 0
-rw-r--r-- 1 root root 0 11月 12 08:49 docker-file
-rw-r--r-- 1 root root 0 11月 12 08:48 host_file

注:容器中的目录和宿主机中的/var/lib/docker/volumes/my-vol/_data是一样的

3.查看 volume

[root@localhost ~]# docker volume inspect mysql-vol
[{"CreatedAt": "2025-11-12T09:01:23+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/mysql-vol/_data","Name": "mysql-vol","Options": null,"Scope": "local"}
]

4.挂载宿主机目录

[root@localhost ~]# docker run -d -v /data/docker-volume:/data nginx:1.22.1
[root@localhost ~]# ll /data/
总用量 0
drwxr-xr-x 2 root root   6 11月 12 09:09 docker-volume
drwxr-xr-x 8 root root 100 11月  6 14:55 registry# 宿主机创建文件
[root@localhost ~]# cd /data/docker-volume/
[root@localhost docker-volume]# touch host-file[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED              STATUS              PORTS                 NAMES
1d8fe1c0e18d   nginx:1.22.1   "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp                exciting_maxwell
# 容器中查看
[root@localhost ~]# docker exec -it 1d8fe1c0e18d bash
root@1d8fe1c0e18d:/# cd /data/
root@1d8fe1c0e18d:/data# ls 
host-file

注:可以是宿主机的任意目录

5.挂载宿主机文件

[root@localhost ~]# docker run -d -v /data/docker-volume/host-file:/data/docker-volume.txt nginx:1.22.1# 在宿主机的目录下写入数据
[root@localhost docker-volume]# echo "hello world" >> host-file[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS         PORTS                 NAMES
5e33da3c14da   nginx:1.22.1   "/docker-entrypoint.…"   2 seconds ago   Up 2 seconds   80/tcp                naughty_herschel
# 启动容器查看
[root@localhost ~]# docker exec -it 5e33da3c14da bash
root@5e33da3c14da:/# cd /data/
root@5e33da3c14da:/data# cat docker-volume.txt 
hello world

注:文件必须使用绝对路径

6.指定挂载权限

# 设为只读模式
[root@localhost ~]# docker run -d -v /data/docker-volume:/data:ro nginx:1.22.1
d4bc2ac50d63be9cc9eb1dcb802950ba710ddfff90361bcbb3afd5c9cbdc792e
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS         PORTS     NAMES
d4bc2ac50d63   nginx:1.22.1   "/docker-entrypoint.…"   3 seconds ago   Up 2 seconds   80/tcp    zealous_chebyshev# 尝试创建目录,发现没有权限
[root@localhost ~]# docker exec -it d4bc2ac50d63 bash
root@d4bc2ac50d63:/# cd /data/
root@d4bc2ac50d63:/data# mkdir file
mkdir: cannot create directory 'file': Read-only file system

7.共享 Volume

注:在使用 docker run或docker create创建新容器时,可以使用 --volumes-from 标签使得容器与已有的容器共享volum

[root@localhost ~]# ll /data/docker-volume/nginx-conf/
总用量 4
-rw-r--r-- 1 root root 398  2月 21  2025 nginx.repo[root@localhost ~]# docker run --name nginx-01 -d -v /data/docker-volume/nginx-conf/:/data nginx:1.22.1
d1c3edb2b260071d17f29c47188169bf4bc06133d78501f284b9c8b4dbfdd587
[root@localhost ~]# docker run --name nginx-02 -d --volumes-from nginx-01 nginx:1.22.1
aecc3eddc812c7202bb46ed778977137a7706fa299483c472bd106335f9d923a# 查看
[root@localhost ~]# docker exec nginx-01 ls /data
nginx.repo
[root@localhost ~]# docker exec nginx-02 ls /data
nginx.repo# 新创建的容器 nginx-02 与之前创建的容器 nginx-01 共享 volume

8.删除 Volume

在删除容器时一并删除volume有以下两种方法。

  • 使用 docker rm -v <container_name> 删除容器。

  • 在运行容器时使用 docker run --rm, --rm 标签会在容器停止运行时删除容器以及容器所挂载的volume。

注意:

  1. 在使用docker volume rm 删除 volume 时,只有在没有任何容器使用时,该 volume 才能成功删除。

  2. 两种方法只会删除未命名的 volume,而对用户指定名字的 volume 进行保留。

  3. 如果 volume 是从宿主机中挂载的,无论对容器进行任何操作都不会导致其在宿主机中被删除。

9.Docker&宿主机复制文件

# 宿主文件 nginx.repo 复制到容器中[root@localhost nginx-conf]# docker cp /data/docker-volume/nginx-conf/nginx.repo nginx-01:/tmp/
Successfully copied 2.05kB to nginx-01:/tmp/
[root@localhost nginx-conf]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS     NAMESd1c3edb2b260   nginx:1.22.1   "/docker-entrypoint.…"   6 minutes ago    Up 6 minutes    80/tcp    nginx-01[root@localhost nginx-conf]# docker exec -it d1c3edb2b260 bash
root@d1c3edb2b260:/# ls /tmp/
nginx.repo

10.-v vs --mount

挂载 Volume:

[root@localhost ~]# docker run -d \--name devtest \--mount type=volume,source=myvol2,target=/app \nginx:latest

挂载本地目录:

[root@localhost ~]# docker run -d \-it \--name devtest \--mount type=bind,source="$(pwd)"/target,target=/app \nginx:latest[root@localhost ~]# docker run -d \-it \--name devtest \--mount type=bind,source="$(pwd)"/target,target=/app,readonly \nginx:latest

挂载 tmpfs:

[root@localhost ~]# docker run -d \-it \--name tmptest \--mount type=tmpfs,destination=/app \nginx:latest

-v 和 --mount 的区别

  • -v 或 --volume:由三个字段组成,用冒号字符(:)分隔。这些字段必须按照正确的顺序,并且每个字段的含义不太清晰

  • --mount:由多个键值对组成,用逗号分隔,每个键值对由<key>=<value>组成。--mount 语法比 -v 或 --volume 更冗长,但键的顺序并不重要,并且该标志的值更易于理解

三、Docker 资源限制

1.cgroup 介绍

  • cgroup 是 Linux 内核提供的一种机制
  • cgroup 可以限制、记录进程组所使用的物理资源(包括 CPU、Memory、IO等)
  • 实现 cgroup 的主要目的是为不同用户层面的资源管理,提供一个统一化的接口

2.cgroup 功能

  • 资源限制:cgroup 可以对任务使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出 OOM(Out of Memory)提示。

  • 优先级分配:通过分配的CPU时间片数量及磁盘IO带宽大小,实际上就相当于控制了任务运行的优先级。

  • 资源统计:cgroup 可以统计系统的资源使用量,如CPU使用时长、内存用量等

  • [root@localhost ~]# cd /sys/fs/cgroup
    [root@localhost cgroup]# mkdir example
    [root@localhost cgroup]# cd example/
    [root@localhost example]# ls
    cgroup.controllers      cpu.max.burst                    hugetlb.1GB.events        io.bfq.weight        memory.oom.group        misc.events
    cgroup.events           cpuset.cpus                      hugetlb.1GB.events.local  io.latency           memory.peak             misc.events.local
    cgroup.freeze           cpuset.cpus.effective            hugetlb.1GB.max           io.max               memory.reclaim          misc.max
    cgroup.kill             cpuset.cpus.exclusive            hugetlb.1GB.numa_stat     io.stat              memory.stat             misc.peak
    cgroup.max.depth        cpuset.cpus.exclusive.effective  hugetlb.1GB.rsvd.current  io.weight            memory.swap.current     pids.current
    cgroup.max.descendants  cpuset.cpus.partition            hugetlb.1GB.rsvd.max      memory.current       memory.swap.events      pids.events
    cgroup.procs            cpuset.mems                      hugetlb.2MB.current       memory.events        memory.swap.high        pids.events.local
    cgroup.stat             cpuset.mems.effective            hugetlb.2MB.events        memory.events.local  memory.swap.max         pids.max
    cgroup.subtree_control  cpu.stat                         hugetlb.2MB.events.local  memory.high          memory.swap.peak        pids.peak
    cgroup.threads          cpu.stat.local                   hugetlb.2MB.max           memory.low           memory.zswap.current    rdma.current
    cgroup.type             cpu.weight                       hugetlb.2MB.numa_stat     memory.max           memory.zswap.max        rdma.max
    cpu.idle                cpu.weight.nice                  hugetlb.2MB.rsvd.current  memory.min           memory.zswap.writeback
    cpu.max                 hugetlb.1GB.current              hugetlb.2MB.rsvd.max      memory.numa_stat     misc.current
    

    任务控制:cgroup 可以对任务执行挂起、恢复等操作

3.查看当前cgroup版本

[root@localhost ~]# mount  | grep cgroup 
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)
[root@localhost ~]# cd /sys/fs/cgroup
# 创建一个目录 example ,这个目录表示一个进程组
[root@localhost cgroup]# mkdir example
[root@localhost cgroup]# cd example/# 在 example 进程组中会有各种配置文件 
[root@localhost example]# ls
cgroup.controllers      cpu.max.burst                    hugetlb.1GB.events        io.bfq.weight        memory.oom.group        misc.events
cgroup.events           cpuset.cpus                      hugetlb.1GB.events.local  io.latency           memory.peak             misc.events.local
cgroup.freeze           cpuset.cpus.effective            hugetlb.1GB.max           io.max               memory.reclaim          misc.max
cgroup.kill             cpuset.cpus.exclusive            hugetlb.1GB.numa_stat     io.stat              memory.stat             misc.peak
cgroup.max.depth        cpuset.cpus.exclusive.effective  hugetlb.1GB.rsvd.current  io.weight            memory.swap.current     pids.current
cgroup.max.descendants  cpuset.cpus.partition            hugetlb.1GB.rsvd.max      memory.current       memory.swap.events      pids.events
cgroup.procs            cpuset.mems                      hugetlb.2MB.current       memory.events        memory.swap.high        pids.events.local
cgroup.stat             cpuset.mems.effective            hugetlb.2MB.events        memory.events.local  memory.swap.max         pids.max
cgroup.subtree_control  cpu.stat                         hugetlb.2MB.events.local  memory.high          memory.swap.peak        pids.peak
cgroup.threads          cpu.stat.local                   hugetlb.2MB.max           memory.low           memory.zswap.current    rdma.current
cgroup.type             cpu.weight                       hugetlb.2MB.numa_stat     memory.max           memory.zswap.max        rdma.max
cpu.idle                cpu.weight.nice                  hugetlb.2MB.rsvd.current  memory.min           memory.zswap.writeback
cpu.max                 hugetlb.1GB.current              hugetlb.2MB.rsvd.max      memory.numa_stat     misc.current

4.限制进程CPU资源

先启动一个占用 CPU 的程序,找到程序的进程号
# ps -ef | grep busyloop​
root      155677  115803 99 16:14 pts/2    00:01:06 ./busyloop​
​
# 把进程号添加到 cgroup.procs 文件 中​
# echo 155677 >> cgroup.procs​
​
# v2 版本限制cpu的文件使用 cpu.max, 这样会限制 155677 进程最多使用 1 核 CPU.​
# echo "100000 100000" > cpu.max

5.限制容器CPU资源

# 运行一个容器,限制可以使用1个cpu,使用 stress 占用2个cpu
[root@localhost example]# docker run -it --rm --cpus=1 registry.cn-beijing.aliyuncs.com/xxhf/stress /bin/bash# top 查看PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                     4668 root      20   0    3704    384    384 R  51.5   0.0   1:40.96 stress                                                                      4667 root      20   0    3704    256    256 R  49.8   0.0   1:41.11 stress  

6.限制容器内存资源

[root@localhost example]# docker run -it --rm -m 300M  registry.cn-beijing.aliyuncs.com/xxhf/stress /bin/bash
root@243450f7f7e1:/# stress --vm 1 --vm-bytes 300M
stress: info: [11] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [11] (416) <-- worker 12 got signal 9
stress: WARN: [11] (418) now reaping child worker processes
stress: FAIL: [11] (452) failed run completed in 48sroot@243450f7f7e1:/# stress --vm 1 --vm-bytes 290M
stress: info: [13] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd# 使用 docker stats 命令 可以查看容器资源使用情况
[root@localhost /]# docker stats 243450f7f7e1
CONTAINER ID   NAME              CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O         PIDS
243450f7f7e1   naughty_haslett   126.49%   292.2MiB / 300MiB   97.40%    866B / 0B   5.75GB / 7.73GB   3
  • 如果操作系统有swap 分区,容器会使用swap分区来保存内存文件,需要使用 'stress --vm 1 --vm-bytes 600M' 才会触发限制。
  • 或者加一个参数 --memory-swap=300M,表示 可以使用的内存和交换空间的总和
http://www.dtcms.com/a/600684.html

相关文章:

  • wap手机网站模板上饶网站建设3ao cc专业a
  • 【Nginx】Nginx 多协议负载均衡实战:StarRocks 与 MinIO 代理配置全解析
  • 域名注册和网站设计服务如何做贴吧类网站多钱
  • python+uniapp基于微信小程序的垃圾分类信息系统
  • C语言编译器安卓版 | 强大功能助力编程学习与实践
  • STM32使用金属探测传感器自制金属探测仪
  • vmware嵌套安装esxi7.0.3扩容vmfs
  • 使用 BR 备份 TiDB 到 AWS S3 存储
  • 【OpenCV + VS】OpenCV 绘图:绘制矩形、圆形、椭圆形、线条等
  • 易语言反编译工具 - 高效破解易语言程序的利器
  • 11年始终专注营销型网站提供网站建设小程序制作
  • AOSP Android13 Launcher3——TransformParams 类
  • 网站推广问题推广公司网站有哪些方式
  • 成都网站建设公司电话美食网站建设多少钱
  • 【把Linux“聊”明白】进程的概念与状态
  • GIT版本管理工具轻松入门 | TortoiseGit,本地 Git 仓库和 Git 概念,笔记02
  • 什么是美颜sdk?美型功能开发与用户体验优化实战
  • 在 React 项目中使用 Ky 与 TanStack Query 构建现代化数据请求层
  • 计算机网络---传输层安全 SSL与TLS
  • 【Linux篇】信号机制深度剖析:从信号捕捉到SIGCHLD信号处理
  • C语言编译软件选择及优化建议
  • Linux 之 【冯诺依曼体系结构与操作系统的简介】
  • 潍坊建设gc局网站windows优化软件
  • Java虚拟机(JVM)面试题(51道含答案)
  • [27] cuda 应用之 核函数实现图像通道变换
  • Aurora RDS MySQL The table ‘/rdsdbdata/tmp/#sql14b_df16d_1bd‘ is full
  • 手机响应式网站怎么做how to use wordpress
  • 网易云音乐回应“不适配鸿蒙”:推动相关部门加快步伐
  • C语言在线编译练习 | 提高编程技能与实战能力
  • 人工智能分支——深度学习、机器学习与神经网络初概览