docker的挂载和数据卷

Docker挂载允许将主机目录或文件系统挂载到容器中,实现数据共享和持久化。有两种方式:命名挂载(预创建数据卷)和匿名挂载。数据卷是持久化的存储,可用于多容器共享。在挂载MySQL容器时需注意提供密码选项,如MYSQL_ROOT_PASSWORD。DockerCompose可以方便地定义和管理数据卷。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Docker挂载(Mount)

一种将主机文件系统上的目录或文件系统挂载到Docker容器内的方式,可以让容器访问主机上的文件系统,也可以让容器之间共享数据。

Docker支持两种挂载方式:

命名挂载
命名挂载使用预先定义的数据卷进行挂载。首先需要使用docker volume create命令创建一个数据卷,然后使用–mount或-v选项将数据卷挂载到容器中。例如:

docker volume create mydata
docker run --mount source=mydata,target=/app/data myimage:latest

上述命令创建了一个名为mydata的数据卷,并将其挂载到容器中的/app/data目录中
使用 -v 挂载时,如果宿主机上没有指定文件不会报错,会自动创建指定文件;当使用 --mount时,如果宿主机中没有这个文件会报错找不到指定文件,不会自动创建指定文件
因此上述命令等价于:

docker volume create mydata
docker run -v mydata:/app/data myimage:latest

docker创建的数据卷默认是共享卷,即:可以挂载到多个容器,并且在一个容器里面的改动,在其他容器也会有体现

docker volume create myvolume
 docker run -d --name my-container -v myvolume:/data mysql

但是会报错:

2023-11-25 23:05:49 2023-11-25 15:05:49+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
2023-11-25 23:05:49     You need to specify one of the following as an environment variable:
2023-11-25 23:05:49     - MYSQL_ROOT_PASSWORD
2023-11-25 23:05:49     - MYSQL_ALLOW_EMPTY_PASSWORD
2023-11-25 23:05:49     - MYSQL_RANDOM_ROOT_PASSWORD

这是因为 MySQL 镜像在启动时检测到数据库未初始化,并且没有设置 MySQL root 用户密码。MySQL 镜像要求在启动容器时提供 root 用户密码,以确保安全性。

你可以通过以下几种方式之一解决这个问题:

设置 root 用户密码: 在 docker run 命令中,使用 -e 选项设置环境变量 MYSQL_ROOT_PASSWORD 来指定 root 用户的密码。

docker run -d --name my-container -v myvolume:/data -e MYSQL_ROOT_PASSWORD=mysecretpassword mysql

将 mysecretpassword 替换为你想要设置的实际密码。

允许空密码: 如果你希望 root 用户没有密码,可以使用 -e 选项设置环境变量 MYSQL_ALLOW_EMPTY_PASSWORD。

docker run -d --name my-container -v myvolume:/data -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql

随机生成 root 用户密码: 如果你希望 MySQL 在每次启动时为 root 用户生成一个随机密码,可以使用 -e 选项设置环境变量 MYSQL_RANDOM_ROOT_PASSWORD。

docker run -d --name my-container -v myvolume:/data -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql

创建两个容器并挂载同一个卷,就可以实现共享: docker exec -it my-container2 bash在一个容器里面修改卷内容,另一个容器也会有体现
在这里插入图片描述

匿名挂载

匿名挂载是一种将主机上的目录或文件系统挂载到容器内部的方式,不需要预先定义数据卷。可以使用–mount或-v选项指定要挂载的目录或文件系统。例如:

在这里插入图片描述

docker run -d --name my-container3 -v D:/temp_files/docker_file:/dockerfiles -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql将主机上的D:/temp_files/docker_file目录挂载到容器中的/docker_file目录中,然后就可以实现互通,任何一个目录的改动在另一个也会有相同的改动。

在使用挂载时,需要注意以下几点:

1.目标路径必须是容器内部的绝对路径。
2.如果要在多个容器之间共享数据,则需要使用相同的挂载路径和选项。
3.如果挂载了主机上的目录,则容器内的更改将反映在主机上,并且主机上的更改将反映在容器内。
4.如果挂载了数据卷,则数据将在容器停止和删除后仍然存在。
总之,使用挂载可以让容器访问主机上的文件系统,并可以在多个容器之间共享数据。

数据卷

Docker的数据卷是一种特殊的目录,可用于在容器和主机之间持久化和共享数据。它们允许容器中的数据在容器停止和删除后仍然存在,并允许多个容器共享同一卷,使用数据卷可以使容器中的数据持久化,并且可以在多个容器之间共享相同的数据。这使得容器更加灵活和可靠,同时也简化了容器的管理和部署。

使用数据卷有以下几个步骤:

创建数据卷:可以使用以下命令来创建数据卷:

docker volume create <volume-name>

将数据卷挂载到容器中:可以使用以下命令来挂载数据卷到容器中:

docker run -v <volume-name>:<container-path> <image-name>

其中,volume-name是数据卷的名称,container-path是容器中要挂载数据卷的路径,image-name是容器使用的镜像名称。

在容器中使用数据卷:可以在容器中的应用程序中使用挂载的数据卷。任何写入容器中挂载的路径的数据都将被持久化到数据卷中,并且在容器被删除时仍然存在。

共享数据卷:可以在多个容器之间共享数据卷。可以使用相同的数据卷名称和路径来挂载数据卷,从而使多个容器都能够访问相同的数据。

删除数据卷:可以使用以下命令来删除数据卷:

docker volume rm <volume-name>

如果数据卷当前正在被容器使用,则无法删除。要删除被容器使用的数据卷,必须先删除使用该数据卷的容器。

在Docker Compose中使用数据卷:

定义数据卷1(命名挂载)
在Docker Compose文件中,可以使用volumes关键字来定义数据卷。例如:

version: "3.9"
services:
  app:
    image: myapp:latest
    volumes:
      - mydata:/app/data
volumes:
  mydata:

上述代码定义了一个名为mydata的数据卷,并将其挂载到应用程序容器中的/app/data目录中。
定义数据卷2(匿名挂载)

version: "3"

services:
  db:
    image: mysql
    volumes:
      - /data/mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw

  web:
    build: .
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
    environment:
      DB_HOST: db
      DB_NAME: mydatabase
      DB_USER: root
      DB_PASSWORD: my-secret-pw

定义了两个服务:一个 MySQL 服务(名为 db),一个 Django 服务(名为 web)。我们还定义了两个 volumes,一个用于将本地的 /data/mysql 目录挂载到 MySQL 容器中的 /var/lib/mysql 目录上,另一个用于将当前目录(即 .)挂载到 Django 容器中的 /code 目录上。

在使用Compose时,如果没有手动创建数据卷,则Compose将自动创建它们。在数据卷的生命周期内,数据将保留在主机的文件系统中,并可以被多个容器共享。如果需要清除数据卷,则可以使用以下命令:

在运行 Docker Compose 时,我们可以使用如下命令:

docker-compose up

Docker Compose 会自动创建并启动两个容器,并将它们连接在一起。MySQL 容器中的数据会被保存到本地的 /data/mysql 目录中,而 Django 容器中的代码会被保存到本地的当前目录中。

docker-compose down --volumes

这将清除所有Compose中定义的数据卷。

数据卷的位置

在容器中,数据卷通常被挂载到容器的文件系统中的某个目录。Docker容器中的文件系统包括只读的镜像层和可写的容器层,数据卷属于容器层,可以被多个容器共享。Docker容器中挂载数据卷的路径通常是绝对路径,可以在启动容器时通过-v或–mount参数指定。

在主机上,Docker数据卷的位置取决于数据卷类型。Docker支持多种类型的数据卷,包括:

匿名卷
匿名卷是在Docker容器内部创建的卷,没有命名和标签。在主机上,匿名卷存储在Docker的数据目录下,通常是/var/lib/docker/volumes目录。

命名卷
命名卷是具有名称和标签的数据卷,可以在创建容器时手动创建或者在Docker Compose文件中定义。在主机上,命名卷也存储在Docker的数据目录下,但是路径包括了卷的名称和标签信息。例如,如果创建了一个名为mydata的数据卷,那么该卷在主机上的位置通常是/var/lib/docker/volumes/mydata/_data

绑定挂载
绑定挂载将主机上的目录或文件系统挂载到容器中,因此在主机上,挂载的位置就是绑定的目录或文件系统的位置。

挂载和数据卷

相比挂载,数据卷的优点是由于是 Docker 统一管理的,不存在由于权限不够引发的挂载问题,也不需要在不同服务器指定不同的路径;缺点是它不太适合单配置文件的映射。
和挂载一样,数据卷的生命周期脱离了容器,删除容器之后卷还是存在的。下次构建镜像时,指定卷的名称就可以继续使用了。

### 相同卷不能同时作为源目标的原因 在存储复制过程中,如果尝试将同一个卷既设置为目标又设为源,则会遇到逻辑上的冲突。这是因为数据同步机制依赖于区分清楚的源端与目的端角色来确保一致性[^1]。 当一个卷被指定为复制的目标时,该卷通常处于只读状态或受到写入限制,以便接收来自源卷的数据更新而不影响其自身的稳定性。而一旦这个卷又被设定成另一个复制操作中的源,它就需要支持正常的读取写入活动以供其他设备从中获取最新版本的信息。这种双重身份使得在同一时间点内难以维持两个方向上的一致性准确性,从而可能导致数据丢失或损坏的风险增加。 此外,在某些情况下,硬件层面的设计也可能不允许这样的配置存在,因为这违反了厂商设计初衷所遵循的最佳实践原则,即保持清晰分离的角色定义有助于提高系统的可靠性性能表现[^2]。 ### 解决方案 为了克服上述挑战并实现灵活高效的备份策略,建议采取以下措施之一: #### 方法一:创建额外副本 最直接的方法是在现有环境中引入新的物理磁盘空间或者利用快照功能生成临时性的第二份拷贝用于反向传输过程。这样做不仅能够绕开原始问题带来的局限性,而且还可以进一步增强整体架构的安全等级服务质量保障水平。 ```bash # 创建LVM快照示例命令 lvcreate --name snap_volume /dev/vg/lv_original ``` 这种方法适用于那些拥有充足资源冗余度的企业环境;然而对于小型企业来说可能意味着较高的成本支出。 #### 方法二:使用第三方软件工具 另一种可行的选择是借助专业的第三方应用程序来进行异步镜像处理工作。这些程序往往具备更高级别的抽象层面上的操作灵活性,允许管理员自定义复杂的双向同步流程而不会破坏底层基础设施稳定运行的状态。 例如,Veritas NetBackup 或 Dell EMC Avamar 这样的商业产品提供了强大的恢复管理特性,能够在不影响生产效率的前提下完成复杂场景下的迁移任务。 #### 方法三:调整业务需求规划 最后也是最容易实施的方式就是重新审视当前的工作负载模式及其对应的SLA (服务水平协议),进而合理安排哪些部分应该优先考虑单向流动方式,哪些地方可以通过定期全量/增量转储手段达到近似效果即可满足实际运营要求。 通过这种方式不仅可以简化运维管理工作负担,同时也降低了因过度追求技术完美而导致不必要的风险隐患。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值