docker -v 到底和那个一样?type=volume还是type=bind的解释

bash 复制代码
逐行通俗详细的解释下这个代码"#!/usr/bin/env bash
#
# This script will automatically pull docker image from DockerHub, and start a daemon container to run the Qwen-Chat web-demo.

IMAGE_NAME=qwenllm/qwen:2-cu121
QWEN_CHECKPOINT_PATH=/path/to/Qwen-Instruct
PORT=8901
CONTAINER_NAME=qwen2

function usage() {
    echo '
Usage: bash docker/docker_web_demo.sh [-i IMAGE_NAME] -c [/path/to/Qwen-Instruct] [-n CONTAINER_NAME] [--port PORT]
'
}

while [[ "$1" != "" ]]; do
    case $1 in
        -i | --image-name )
            shift
            IMAGE_NAME=$1
            ;;
        -c | --checkpoint )
            shift
            QWEN_CHECKPOINT_PATH=$1
            ;;
        -n | --container-name )
            shift
            CONTAINER_NAME=$1
            ;;
        --port )
            shift
            PORT=$1
            ;;
        -h | --help )
            usage
            exit 0
            ;;
        * )
            echo "Unknown argument ${1}"
            exit 1
            ;;
    esac
    shift
done

if [ ! -e ${QWEN_CHECKPOINT_PATH}/config.json ]; then
    echo "Checkpoint config.json file not found in ${QWEN_CHECKPOINT_PATH}, exit."
    exit 1
fi

sudo docker pull ${IMAGE_NAME} || {
    echo "Pulling image ${IMAGE_NAME} failed, exit."
    exit 1
}

sudo docker run --gpus all -d --restart always --name ${CONTAINER_NAME} \
    -v /var/run/docker.sock:/var/run/docker.sock -p ${PORT}:80 \
    --mount type=bind,source=${QWEN_CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-Instruct \
    -it ${IMAGE_NAME} \
    python web_demo.py --server-port 80 --server-name 0.0.0.0 -c /data/shared/Qwen/Qwen-Instruct/ && {
    echo "Successfully started web demo. Open 'http://localhost:${PORT}' to try!
Run \`docker logs ${CONTAINER_NAME}\` to check demo status.
Run \`docker rm -f ${CONTAINER_NAME}\` to stop and remove the demo."
}"
当然,以下是对该脚本代码的逐行解释:

#!/usr/bin/env bash
这行是脚本的首行,称为"shebang"。它告诉系统这个脚本应该使用哪个解释器来执行,这里是使用bash。
#
# This script will automatically pull docker image from DockerHub, and start a daemon container to run the Qwen-Chat web-demo.
这些行是注释,用#开头。它们描述了脚本的功能,即从DockerHub拉取Docker镜像,并启动一个守护进程容器来运行Qwen-Chat的web演示。
IMAGE_NAME=qwenllm/qwen:2-cu121
QWEN_CHECKPOINT_PATH=/path/to/Qwen-Instruct
PORT=8901
CONTAINER_NAME=qwen2
这里定义了四个变量:IMAGE_NAME是Docker镜像的名称,QWEN_CHECKPOINT_PATH是Qwen-Instruct检查点的路径,PORT是映射到容器内部的端口,CONTAINER_NAME是容器的名称。
function usage() {
    echo '
Usage: bash docker/docker_web_demo.sh [-i IMAGE_NAME] -c [/path/to/Qwen-Instruct] [-n CONTAINER_NAME] [--port PORT]
'
}
这是一个名为usage的函数,它打印出脚本的用法说明。
while [[ "$1" != "" ]]; do
这是一个while循环,它将持续运行,直到没有更多的命令行参数(即$1为空)。
    case $1 in
开始一个case语句,用于匹配不同的命令行参数。
        -i | --image-name )
            shift
            IMAGE_NAME=$1
            ;;
如果命令行参数是-i或--image-name,则将下一个参数(通过shift移动到$1)赋值给IMAGE_NAME变量。
        -c | --checkpoint )
            shift
            QWEN_CHECKPOINT_PATH=$1
            ;;
类似地,如果参数是-c或--checkpoint,则更新QWEN_CHECKPOINT_PATH。
        -n | --container-name )
            shift
            CONTAINER_NAME=$1
            ;;
如果参数是-n或--container-name,则更新CONTAINER_NAME。
        --port )
            shift
            PORT=$1
            ;;
如果参数是--port,则更新PORT。
        -h | --help )
            usage
            exit 0
            ;;
如果参数是-h或--help,则调用usage函数打印帮助信息,并退出脚本。
        * )
            echo "Unknown argument ${1}"
            exit 1
            ;;
如果参数不匹配上述任何情况,则打印未知参数信息并退出。
    esac
    shift
done
结束case语句,并移动到下一个命令行参数。
if [ ! -e ${QWEN_CHECKPOINT_PATH}/config.json ]; then
    echo "Checkpoint config.json file not found in ${QWEN_CHECKPOINT_PATH}, exit."
    exit 1
fi
检查config.json文件是否存在,如果不存在,则打印消息并退出。
sudo docker pull ${IMAGE_NAME} || {
    echo "Pulling image ${IMAGE_NAME} failed, exit."
    exit 1
}
使用sudo docker pull命令从DockerHub拉取指定的Docker镜像,如果失败则打印消息并退出。
sudo docker run --gpus all -d --restart always --name ${CONTAINER_NAME} \
    -v /var/run/docker.sock:/var/run/docker.sock -p ${PORT}:80 \
    --mount type=bind,source=${QWEN_CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-Instruct \
    -it ${IMAGE_NAME} \
    python web_demo.py --server-port 80 --server-name 0.0.0.0 -c /data/shared/Qwen/Qwen-Instruct/ && {
    echo "Successfully started web demo. Open 'http://localhost:${PORT}' to try!
Run \`docker logs ${CONTAINER_NAME}\` to check demo status.
Run \`docker rm -f ${CONTAINER_NAME}\` to stop and remove the demo."
}
使用sudo docker run命令启动一个新的Docker容器,映射端口、挂载卷,并运行web演示脚本。如果成功,则打印消息
用户_SMITHj
sudo docker run --gpus all -d --restart always --name ${CONTAINER_NAME} \
    -v /var/run/docker.sock:/var/run/docker.sock -p ${PORT}:80 \
    --mount type=bind,source=${QWEN_CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-Instruct \
    -it ${IMAGE_NAME} \
    python web_demo.py --server-port 80 --server-name 0.0.0.0 -c /data/shared/Qwen/Qwen-Instruct/ && {
    echo "Successfully started web demo. Open 'http://localhost:${PORT}' to try!
Run \`docker logs ${CONTAINER_NAME}\` to check demo status.
Run \`docker rm -f ${CONTAINER_NAME}\` to stop and remove the demo."
};以上语句每个参数都详细解释下
当然,以下是sudo docker run命令及其参数的详细解释:

sudo docker run
docker run:这是Docker命令行工具的一个命令,用于启动一个新的容器实例。
--gpus all
--gpus all:此参数指示Docker运行时将所有可用的GPU设备暴露给容器。这意味着容器可以使用宿主机上的所有GPU资源。
-d
-d:此参数表示以守护进程(detached)模式运行容器,即容器将在后台运行,不占用当前终端。
--restart always
--restart always:设置容器的重启策略为"always",这意味着如果容器退出,它将自动重新启动。
--name ${CONTAINER_NAME}
--name ${CONTAINER_NAME}:为容器设置一个名称,这里使用之前定义的变量CONTAINER_NAME。
-v /var/run/docker.sock:/var/run/docker.sock
-v /var/run/docker.sock:/var/run/docker.sock:将宿主机的Docker套接字文件挂载到容器内部,使得容器可以执行Docker命令。
-p ${PORT}:80
-p ${PORT}:80:将宿主机的端口映射到容器内部的端口。这里将宿主机的变量PORT指定的端口映射到容器的80端口。
--mount type=bind,source=${QWEN_CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-Instruct
--mount type=bind,source=${QWEN_CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-Instruct:使用bind挂载将宿主机的路径QWEN_CHECKPOINT_PATH挂载到容器内部的路径/data/shared/Qwen/Qwen-Instruct。
-it ${IMAGE_NAME}
-it:这是两个参数的简写,-i表示保持标准输入打开,-t表示分配一个伪终端。这两个参数通常一起使用,以提供一个交互式的shell环境。
${IMAGE_NAME}:指定要启动的容器使用的Docker镜像的名称,这里使用之前定义的变量IMAGE_NAME。
python web_demo.py --server-port 80 --server-name 0.0.0.0 -c /data/shared/Qwen/Qwen-Instruct/
python web_demo.py --server-port 80 --server-name 0.0.0.0 -c /data/shared/Qwen/Qwen-Instruct/:这是在容器内部运行的命令,使用Python解释器执行名为web_demo.py的脚本,并传递相应的参数来配置web演示服务。
&& {
    echo "Successfully started web demo. Open 'http://localhost:${PORT}' to try!
Run \`docker logs ${CONTAINER_NAME}\` to check demo status.
Run \`docker rm -f ${CONTAINER_NAME}\` to stop and remove the demo."
}
&&:这是一个逻辑与运算符,用于在docker run命令成功执行后执行后续的命令。
{ ... }:这是shell脚本中的代码块,包含要执行的命令。
echo "Successfully started web demo. Open 'http://localhost:${PORT}' to try! ...":如果容器启动成功,则打印出成功的消息,并提供了如何访问web演示、检查状态和停止/删除容器的指令。
用户_SMITHj
--mount type=bind,source=${QWEN_CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-Instruct
--mount type=bind,source=${QWEN_CHECKPOINT_PATH},target=/data/shared/Qwen/Qwen-Instruct:使用bind挂载将宿主机的路径QWEN_CHECKPOINT_PATH挂载到容器内部的路径/data/shared/Qwen/Qwen-Instruct。;上面这个不是很清晰和明白,请再详细解释描述下,展开通俗的说一说
当然,我会尽量以更通俗的方式解释--mount type=bind这个Docker命令参数。

首先,想象一下你的电脑(宿主机)和Docker容器就像是两个独立的房间。每个房间都有自己的文件柜(文件系统),而且一般情况下,这两个房间的文件柜是分开的,互相看不到对方里面的文件。

现在,假设你在电脑上的一个特定文件夹(比如C:\myfolder或/home/user/myfolder)里有一些重要的文件,你需要在Docker容器里使用这些文件。这就好比你的房间里有一份重要的文件,而你需要让另一个房间的人也能看到和使用这份文件。

--mount type=bind就是用来实现这个目标的。它就像是一条特殊的传送带,可以将宿主机上的一个文件夹(源)直接"传送"到Docker容器里的一个特定位置(目标)。具体来说:

type=bind:告诉Docker你想要使用的是"绑定挂载"类型。这是一种特殊的挂载方式,允许容器直接访问宿主机的文件系统。
source=${QWEN_CHECKPOINT_PATH}:这是你宿主机上的路径,也就是你想要"传送"的文件夹。在脚本中,这个路径是用变量QWEN_CHECKPOINT_PATH表示的,比如它可能指向/path/to/Qwen-Instruct。
target=/data/shared/Qwen/Qwen-Instruct:这是容器内的路径,也就是你想要把宿主机的文件夹"传送"到的地方。在容器内部,当你访问/data/shared/Qwen/Qwen-Instruct这个路径时,实际上你看到的是宿主机上QWEN_CHECKPOINT_PATH这个路径下的文件。
所以,当你运行这个Docker命令时,宿主机上的QWEN_CHECKPOINT_PATH文件夹就像被"复制"到了容器内的/data/shared/Qwen/Qwen-Instruct位置。但实际上,并没有真正的复制发生,这只是两个位置之间的映射。你在宿主机上对这个文件夹所做的任何更改都会立即反映到容器内,反之亦然。

这种挂载方式在需要从宿主机向容器传递数据,或者需要容器访问宿主机上的文件时非常有用。但需要注意的是,使用绑定挂载时要小心,因为它可能会带来安全风险,因为它允许容器直接访问宿主机的文件系统。

用户_SMITHj
这个指令和-v是不是一样的意思?
是的,--mount type=bind和-v或--volume在Docker中基本上是完成相同任务的两种不同语法形式。它们都用于将宿主机的文件或目录挂载到容器中。

以下是两者之间的对比:

-v 或 --volume:这是Docker的传统方式来指定挂载卷。例如:
-v /path/on/host:/path/in/container
--mount:这是Docker 17.06及以上版本引入的新语法,提供了一种更明确和灵活的方式来指定挂载选项。例如:
--mount type=bind,source=/path/on/host,target=/path/in/container
尽管它们在功能上相似,但--mount语法提供了更多的灵活性,因为它允许你指定更多的挂载类型和选项。例如,你可以使用--mount来指定卷驱动程序选项,这在-v语法中是不容易做到的。

下面是两个语法形式的一个简单对比:

使用 -v 或 --volume:

docker run -d -v /path/on/host:/path/in/container myimage
使用 --mount:

docker run -d --mount type=bind,source=/path/on/host,target=/path/in/container myimage
在这两个例子中,/path/on/host是宿主机的路径,/path/in/container是容器内的路径。myimage是你要运行的Docker镜像。

总的来说,如果你使用的是较新版本的Docker,并且需要更复杂的挂载选项,--mount可能是一个更好的选择。对于简单的挂载,-v仍然是一个有效的选择,并且由于它更简洁,可能在某些情况下更受欢迎。

用户_SMITHj
--mount type=bind,这个type到底有多少种类型?
在Docker中,--mount参数的type关键字后面可以跟随多种不同的类型,以指定挂载卷的类型。以下是一些常见的挂载类型:

bind:绑定挂载,允许你将宿主机上的文件或目录直接挂载到容器中。
volume:Docker管理卷,这是Docker推荐用于持久化数据的挂载类型。与绑定挂载不同,卷是由Docker管理的,并且不受宿主机文件系统布局的影响。
tmpfs:挂载一个tmpfs(RAM磁盘),适用于不需要持久化的数据,因为tmpfs是临时的,并且数据在容器停止时会被清除。
npipe:在Windows上,用于挂载命名管道。
以下是一些示例:

绑定挂载:
--mount type=bind,source=/path/on/host,target=/path/in/container
Docker管理卷:
--mount type=volume,source=myvolume,target=/path/in/container
tmpfs挂载:
--mount type=tmpfs,destination=/run/user
命名管道挂载(Windows):
--mount type=npipe,source=\\.\pipe\docker_engine,destination=\\.\pipe\docker_engine
volume类型通常是最常用的,因为它提供了一些优势,如易于备份、迁移和管理,以及独立于宿主机文件系统的优点。绑定挂载通常用于开发或测试,因为它们提供了对宿主机文件系统的直接访问,但这可能会导致一些潜在的安全问题,尤其是在生产环境中。

这些挂载类型提供了不同的功能和用例,你可以根据你的具体需求选择合适的类型。

用户_SMITHj
还是不太明白,请通俗的解释,让小白也能看懂
系统稍微有点忙,请您再尝试一次~
用户_SMITHj
还是不太明白,请通俗的解释,让小白也能看懂
当然,我会尽量用简单的比喻来解释这些挂载类型:

绑定挂载(bind mount):
想象一下,你有一本书(宿主机上的文件或目录),你想让朋友(容器)也能看到这本书的内容。你可以直接把这本书带到朋友家(容器内部),这样朋友就能直接翻阅了。如果你在家(宿主机)修改了书的内容,朋友那里的书也会同步更新。这就是绑定挂载,它直接把宿主机的文件或目录"带"到容器里。
Docker管理卷(volume):
现在想象你有一个特殊的书架(Docker管理卷),你可以把书放在这个书架上,然后告诉朋友书架的位置。朋友可以随时来看书,但是书架是独立于你家的,也就是说,即使你搬家(宿主机重装或文件系统变化),书架(卷)和书(数据)仍然在那里。Docker管理卷更安全,也更便于管理。
tmpfs挂载:
tmpfs挂载就像是一个临时的白板。你可以把信息写在白板上,但是一旦你离开房间(容器停止),白板就会被擦干净。也就是说,tmpfs挂载的数据不会持久化,它在容器重启后就会消失。
命名管道挂载(npipe):
命名管道挂载比较特殊,它就像是两个房间之间的秘密通道。你可以通过这个通道传递消息(数据),但是这个通道只在你和朋友(容器和宿主机)之间有效。这在Windows系统中比较常见,用于进程间的通信。
总结一下:

绑定挂载:直接把宿主机的文件或目录"拿"到容器里。
Docker管理卷:使用Docker提供的独立书架来存放文件,更安全,便于管理。
tmpfs挂载:临时白板,用完即擦,不保留数据。
命名管道挂载:两个房间之间的秘密通道,用于特殊的数据传递。
用户_SMITHj
Docker管理卷(volume):和-v是不是就是一回事?
是的,Docker管理卷(volume)与使用 -v 或 --volume 参数基本上是一回事。这两个都是用来在Docker容器中创建和管理数据卷的方式。

以下是两者之间的关系:

-v 或 --volume:这是Docker的传统方式来指定数据卷。当你使用 -v 参数时,Docker会在背后为你创建一个管理卷,除非你明确指定一个绑定挂载。
--mount:这是Docker 17.06及以上版本引入的新语法,它提供了更明确的挂载选项。使用 --mount 参数时,你可以指定卷的类型,比如 type=volume 表示创建一个Docker管理卷。
以下是两个语法形式的一个简单对比:

使用 -v 或 --volume 创建Docker管理卷:

docker run -d -v myvolume:/path/in/container myimage
使用 --mount 创建Docker管理卷:

docker run -d --mount type=volume,source=myvolume,target=/path/in/container myimage
在这两个例子中,myvolume 是卷的名称,/path/in/container 是容器内部的路径,myimage 是你要运行的Docker镜像。在第一个例子中,Docker会自动创建一个名为 myvolume 的卷,并将其挂载到容器内部的 /path/in/container 路径。

所以,当你使用 -v 或 --volume 时,默认就是创建一个Docker管理卷,除非你指定了宿主机的路径,这时它将创建一个绑定挂载。而使用 --mount 时,你需要明确指定 type=volume 来创建一个Docker管理卷。

用户_SMITHj
-v 到底和那个一样?type=volume还是type=bind
-v 或 --volume 参数在Docker中的行为取决于你如何使用它。默认情况下,如果不指定宿主机的路径,-v 会创建一个Docker管理卷(type=volume)。如果你指定了宿主机的路径,那么 -v 将创建一个绑定挂载(type=bind)。

以下是如何区分的:

当你使用 -v 并且只提供卷名(不指定宿主机的路径),它相当于 type=volume:
docker run -d -v myvolume:/path/in/container myimage
在这个例子中,myvolume 是Docker管理卷的名称,它会被创建并挂载到容器内的 /path/in/container。
当你使用 -v 并且指定了宿主机的路径,它相当于 type=bind:
docker run -d -v /path/on/host:/path/in/container myimage
在这个例子中,/path/on/host 是宿主机的路径,/path/in/container 是容器内的路径,这会创建一个绑定挂载。
所以,总结来说:

-v 只提供卷名时,相当于 type=volume。
-v 提供宿主机路径时,相当于 type=bind。
使用 --mount 语法时,你需要明确指定 type 来指明是哪种挂载类型。
相关推荐
绵绵细雨中的乡音10 分钟前
Linux进程学习【基本认知】
linux·运维·学习
matrixlzp20 分钟前
K8S Service 原理、案例
云原生·容器·kubernetes
GnixAij1 小时前
Docker SSH端口转发
docker·ssh
珹洺1 小时前
Linux操作系统从入门到实战(三)Linux基础指令(上)
linux·运维·服务器
剁椒排骨1 小时前
win11什么都不动之后一段时间黑屏桌面无法显示,但鼠标仍可移动,得要熄屏之后才能进入的四种解决方法
运维·windows·经验分享·计算机外设·win11·win10
angushine1 小时前
让Docker端口映射受Firewall管理而非iptables
运维·docker·容器
归寻太乙2 小时前
Linux环境变量
linux·运维·服务器
m0Java门徒2 小时前
面向对象编程核心:封装、继承、多态与 static 关键字深度解析
java·运维·开发语言·intellij-idea·idea
Sapphire~2 小时前
Linux-06 ubuntu 系统截图软件使用简单记录
linux·运维·ubuntu
高级IT技术专家secops9982 小时前
在统信UOS/麒麟Kylin OS操作系统中配置APT和GIT代理
运维·服务器·git·系统安全·kylin