多个docker 挂载VOLUME的心得

本文详细介绍了Docker中数据卷的使用方法,包括如何通过不同的命令行参数实现数据的持久化,以及如何利用数据卷容器实现数据共享。还探讨了不同场景下数据迁移的情况。

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

假如有一个mysql镜像

在Dockerfile中制定VOLUME /var/lib/mysql

那么当执行:

docker run -d -e MYSQL_ROOT_PASSWORD=root --name=hzbtest 172.16.71.199/common/mysql:5.6

1)上面没有指定 -v,新建的容器会自动在主机上建立一目录来挂载/var/lib/mysql

docker inspect hzbtest"Mounts": [  
        {  
            "Name": "6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134",  
            "Source": "/var/lib/docker/volumes/6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134/_data",  
            "Destination": "/var/lib/mysql",  
            "Driver": "local",  
            "Mode": "",  
            "RW": true  
        }  
    ]

2)当执行-v,只指定容器内部的目录

docker run -d -e MYSQL_ROOT_PASSWORD=root --name=hzbtest2 -v /var/lib/mysql 172.16.71.199/common/mysql:5.6

这种方式的效果和1)的效果一样。

3)当执行:

docker run -d -e MYSQL_ROOT_PASSWORD=root --name=hzbtest3 -v /root/data:/var/lib/mysql 172.16.71.199/common/mysql:5.6

这种情况,容器启动后会把/var/lib/mysql里面的文件迁移到宿主机的/root/data目录下

4)当执行:

docker run -d -e MYSQL_ROOT_PASSWORD=root --name=hzbtest4 -v /root/data:/var/log 172.16.71.199/common/mysql:5.6

由于容器的镜像的dockerfile并没有给/var/log指定volume,所以,容器内的/var/log/里面的文件并不会迁移到/root/data里面,相反/var/log/的文件会变成/root/data里面的所有文件。

可以用多个 -v标签为容器添加多个volume,还可以使用:ro指定该volume为只读。

docker run -d -e MYSQL_ROOT_PASSWORD=root --name=hzbtest4 -v /root/data:/var/log:ro 172.16.71.199/common/mysql:5.6

 

现在假如再有一个mongoDB的镜像

在Dockerfile中制定VOLUME /data/db,这个文件夹本身带有文件.

当执行:

docker run -d -e MYSQL_ROOT_PASSWORD=root --name=hzbtest5 -v /root/data:/data/db 172.16.71.199/common/mongodb:3.0.9

这种情形hzbtest5的/data/db的文件会迁移到/root/data/文件夹下,这时候/roo/data里面就会同时有mysql挂载过来的/var/lib/mysql和mongodb挂载过来的/data/db里面的文件。

hzbtest3的/var/lib/mysql目录和hzbtest5的/data/db目录都能看到/root/data里面的全部文件。

5)使用Dockerfile添加volume

FROM mysql:latest  
RUN useradd root   
VOLUME /data   
RUN touch /data/aa  
RUN chown -R root:root /data 

这种情况和docker run -v /data是一样的。注意,dockerfile中使用volume是不能挂载宿主机中指定的文件夹。这时为了保证Dockerfile的可移植性,因为不能保证所有的宿主机都有对应的文件夹。

6)共享volume/数据卷容器(--volumes-from)

首先创建一个数据卷容器,在/root/data下面放一个文件test.txt

docker run -it -v /root/data --name=dbdata mysql:latest /bin/bash

创建一个容器testa引用这个卷

docker run -it --name=testa --volumes-from dbdata mysql:latest /bin/bash

创建一个容器testb引用这个卷

docker run -it --name=testb --volumes-from dbdata mysql:latest /bin/bash

可以看到testa和testb的/root/data目录下都会有test.txt文件

当在testb的/root/data下新增aa.txt文件时,testb的/root/data下也将看到aa.txt文件,说明他们是共用的一个数据卷。

 

<think>首先,用户的问题是:“我想在使用Docker运行容器时如何挂载多个目录 请问docker run mount multiple volumes”。这涉及到Docker命令中挂载多个目录的方法。 从系统级指令中,我需要: - 所有行内数学表达式用$...$格式。 - 独立公式用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,如[^1]。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考站内引用:有[^1]、[^2]、[^3]。 用户提供的引用: - [^1]: 关于Docker数据卷挂载命令volume(-v)与mount的总结。提到--mount可以挂载volume、bind mount和tmpfs。示例:docker run --name $CONTAINER_NAME -it --mount type=bind,source=$PWD/$CONTAINER_NAME/app,destination=/app --mount source=${CONTAINER_NAME}-data,destination=/data,readonly avocado-cloud:latest /bin/bash - [^2]: docker run命令。提到volume参数,可以在Managing data in containers查看详细说明。USER和WORKDIR相关。 - [^3]: docker run命令详解。列出了一些命令如docker ps, docker inspect等。 用户的问题是关于在docker run命令中挂载多个目录。所以,我需要解释如何使用-v或--mount选项来挂载多个目录。 关键点: - Docker支持挂载多个卷或目录。 - 有两种主要方式:使用-v(简写)或--mount(更详细)。 - 引用[^1]中提到了--mount可以用于挂载多个卷。 步骤: 1. **理解挂载类型**: - Bind mount:挂载主机上的目录到容器。 - Volume:使用Docker管理的卷。 - Tmpfs:内存中的挂载。 2. **使用多个挂载**: - 在docker run命令中,可以多次指定-v或--mount选项。 - 例如:docker run -v /host/path:/container/path -v /another/host:/another/container image - 或使用--mount:docker run --mount type=bind,source=/host/path,target=/container/path --mount type=volume,source=vol_name,target=/container/vol image 3. **参考引用**: - 从[^1]的示例:--mount type=bind,source=...,destination=... --mount source=...,destination=... - 这表明可以多次使用--mount。 - [^2]提到volume参数,但未具体说多个。 - [^3]是命令列表,不直接相关。 结构化回答: - 介绍:简要解释如何挂载多个目录。 - 步骤:分步说明方法。 - 示例:提供实际命令示例。 - 引用:在相关部分添加引用标识。 - 结尾:生成相关问题。 确保中文回答。</think>### 如何在Docker运行容器时挂载多个目录 在Docker运行容器时挂载多个目录是常见的需求,例如将主机上的多个目录映射到容器内部,用于数据持久化或配置共享。Docker提供了两种主要方式:简写选项`-v`(或`--volume`)和详细选项`--mount`。两种方式都支持在同一个`docker run`命令中多次指定,以实现多个挂载点。下面我将逐步解释方法,并提供实际示例。 #### 1. **理解挂载选项** - **`-v` 选项**:简写形式,语法为`-v <主机路径>:<容器路径>:<选项>`。适合快速挂载,但不支持所有高级功能。 - **`--mount` 选项**:更详细且灵活,语法为`--mount type=<类型>,source=<主机路径>,target=<容器路径>,<选项>`。支持三种类型: - `bind`:挂载主机目录(类似`-v`)。 - `volume`:使用Docker管理的卷(推荐用于数据持久化)。 - `tmpfs`:内存中的临时挂载。 - 关键优势:`--mount` 支持更细粒度的控制,如只读挂载或卷标签,而`-v`在多个挂载时更简洁[^1][^2]。 #### 2. **挂载多个目录的步骤** 在`docker run`命令中,通过重复添加`-v`或`--mount`选项来实现多个挂载。以下是具体步骤: **步骤 1: 准备主机目录** - 确保主机上的目录存在(如`/home/user/app`和`/home/user/data`),否则Docker会创建卷但不会创建目录。 - 如果使用命名卷(volume),先创建卷:`docker volume create my-volume`。 **步骤 2: 使用`-v`选项挂载多个目录** - 语法:`docker run -v <主机路径1>:<容器路径1> -v <主机路径2>:<容器路径2> ... <镜像>` - 示例:挂载两个主机目录到容器内部路径。 ```bash docker run -it \ -v /host/path/app:/container/app \ -v /host/path/data:/container/data:ro \ ubuntu:latest /bin/bash ``` - 这里: - `/host/path/app` 映射到容器的 `/container/app`。 - `/host/path/data` 映射到 `/container/data`,并设为只读(`ro`选项)。 - 优点:命令简洁,适合简单场景。 **步骤 3: 使用`--mount`选项挂载多个目录(推荐)** - 语法:`docker run --mount type=...,source=...,target=... --mount type=...,source=...,target=... ... <镜像>` - 示例:挂载一个bind mount和一个volume。 ```bash docker run -it --name my-container \ --mount type=bind,source=$(pwd)/app,destination=/app \ --mount type=volume,source=my-data,destination=/data,readonly \ ubuntu:latest /bin/bash ``` - 这里: - 第一个挂载:类型为`bind`,将当前目录下的`app`子目录映射到容器的`/app`。 - 第二个挂载:类型为`volume`,使用名为`my-data`的卷映射到`/data`,并设为只读。 - 优点:`--mount` 支持更多选项,如`type`、`readonly`,且可读性更强[^1][^2]。 - 注意:如果卷不存在,Docker会自动创建(但bind mount的主机路径必须存在)。 **步骤 4: 验证挂载** - 运行容器后,使用`docker inspect my-container`查看挂载详情。 - 在容器内部,执行`ls /container/path`检查目录内容。 #### 3. **注意事项** - **权限问题**:容器内的用户(默认为root)需要有访问挂载目录的权限。如果主机目录权限不足,会导致错误。可以通过`USER`指令或`-u`选项指定用户[^2]。 - **性能**:bind mount适合开发环境,但volume在性能和数据管理上更优,尤其用于生产环境[^1]。 - **错误处理**:如果挂载失败,检查主机路径是否存在,或使用`docker logs <容器ID>`查看日志(容器日志可能包含挂载错误信息)[^3]。 - **最佳实践**:优先使用`--mount`,因为它更符合现代Docker标准,且支持所有挂载类型。例如,引用[^1]中的示例展示了多挂载的灵活应用。 #### 4. **完整示例** 假设您要运行一个Nginx容器,挂载: - 主机目录`/home/user/nginx/config`到容器的`/etc/nginx`(用于配置文件)。 - 一个名为`nginx-data`的卷到`/usr/share/nginx/html`(用于网页数据)。 命令如下: ```bash docker run -d --name nginx-server \ --mount type=bind,source=/home/user/nginx/config,destination=/etc/nginx \ --mount type=volume,source=nginx-data,destination=/usr/share/nginx/html \ nginx:latest ``` - 解释:`-d`表示后台运行,`source`可以是主机路径或卷名,`destination`是容器内部路径。 通过以上方法,您可以灵活地在单个`docker run`命令中挂载任意数量的目录。确保参考Docker官方文档(如"Managing data in containers")以获取更多细节[^2]。 ### 相关问题 1. Docker卷和bind mount有什么区别?哪种更适合生产环境? 2. 如何在Dockerfile中预定义多个挂载点? 3. Docker挂载目录时如何处理文件权限问题? [^1]: Docker数据卷挂载命令volume(-v)与mount的总结。参数--mount默认情况下用来挂载volume,但也可以用来创建bind mount和tmpfs。如果不指定type选项,则默认为挂载volumevolume是一种更为灵活的数据管理方式,volume可以通过docker volume命令集被管理。示例: docker run --name $CONTAINER_NAME -it \ --mount type=bind,source=$PWD/$CONTAINER_NAME/app,destination=/app \ --mount source=${CONTAINER_NAME}-data,destination=/data,readonly \ avocado-cloud:latest /bin/bash。 [^2]: docker run命令。 关于volume参数,可以在Managing data in containers查看详细说明,需要注意的是开发人员可以在Dockerfile中设定多个volume,但是只能由运维人员设置容器直接的volume访问。USER 容器中默认的用户是root,但是开发人员创建新的用户之后,这些新用户也是可以使用的。开发人员可以通过Dockerfile的USER设定默认的用户,并通过"-u "来覆盖这些参数。  WORKDIR 容器中默认的工作目录是根目录(/)。开发人员可以通过Dockerfile的WORKDIR来设定默认工作目录,操作人员可以通过"-w"来覆盖默认的工作目录。 [^3]: docker run 命令详解。①docker ps XXX 显示当前正在运行的容器②docker ps -a XXX 显示所有的容器③docker inspect XXX 显示容器详情,基本所有信息都有④docker logs XXX 显示容器的启动日志(这个特别强调,除了我们说的把容器日志挂载出来还可以查看这个日志。区别:挂载出来的是程序自己的日志,这个是容器的启动日志,小编有好几次线上出bug都是通过这个命令找到原因!)⑤docker images 显示日志列表⑥docker stop XXX 停止容器⑦docker start XX 开启容器⑧docker restart XXX 重启容器⑨ docker rm XXX 删除已经停止的容器(正在运行的删不了)⑩docker rm -f XXX 删除容器(停止、运行的容器)⑪docker exec -it XXX /bin/bash 进入容器内部⑫docker cp XXX:要拷贝的文件在容器里面的路径 要拷贝到宿主机的相应路径(从容器里拷贝文件到主机)⑬docker cp 要拷贝到宿主机的相应路径 XXX:要拷贝的文件在容器里面的路径(从主机拷贝文件到容器里)⑭docker export XXX > test.tar 导出容器⑮sudo docker import - test/tomcat:1.0.1 导入容器⑯docker search tomcat 查找tomcat的docker官方镜像⑰docker pull 镜像名 (拉取镜像)⑱docker tag 镜像ID 名字:版本 (修改镜像名字)⑲docker events --since="1467302400" (查看docker时间,since按时间戳,f按条件,)⑳docker push 镜像名:版本 推送你的镜像到你的仓库或者github上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值