我的笔记本电脑(本地主机)上有一个大文件。我想将此文件复制到位于远程服务器上的 Docker 容器。我知道如何分两步执行此操作,即首先将文件复制到远程服务器,然后将文件从远程服务器复制到 docker 容器。但是,出于显而易见的原因,我想避免这种情况。
这里介绍了一个具有复杂答案的类似问题:从远程 Docker 容器复制文件
但是在这个问题中,方向相反,文件从远程容器复制到本地主机。
附加请求:此上传是否可以分段完成,或者在网络故障的情况下我可以从停止的位置恢复上传,而不必再次上传整个文件?我问是因为文件相当大,~13GB。
来自 https://docs.docker.com/engine/reference/commandline/cp/#corner-cases 和 https://www.cyberciti.biz/faq/howto-use-tar-command-through- Network-over-ssh-session/ 你只需这样做:
tar Ccf $(dirname SRC_PATH) - $(basename SRC_PATH) | ssh you@host docker exec -i CONTAINER tar Cxf DEST_PATH -
或
tar Ccf $(dirname SRC_PATH) - $(basename SRC_PATH) | ssh you@host docker cp - CONTAINER:DEST_PATH
或未经测试,不知道这是否有效:
DOCKER_HOST=ssh://you@host docker cp SRC_PATH CONTAINER:DEST_PATH
如果您正在运行 *nix 服务器和带有 ssh 服务器的 docker,这将起作用。
您可以按照以下步骤在远程服务器上创建本地隧道:
mkfifo host_to_docker
netcat -lkp your_public_port < host_to_docker | nc docker_ip_address 22 > host_to_docker &
第一个命令将创建一个管道,您可以使用
file host_to_docker
检查它。
第二个是有史以来最伟大的网络效用,即
netcat
。它只是接受一个 tcp 连接并将其转发到另一个 netcat 实例,接收底层 ssh 消息并将其转发到在 docker 上运行的 ssh 服务器,并将其响应写入我们创建的管道。
最后一步是:
scp -P your_public_port payload.tar.gz user@remote_host:/dest/folder
您可以使用
DOCKER_HOST
环境变量和 rsync
来存档您的目标。
首先,您设置
DOCKER_HOST
,这会导致您的 docker 客户端(即 docker
CLI util)通过 SSH 连接到远程服务器的 docker 守护进程。这可能需要您为目标服务器创建 ssh-config 条目。
export DOCKER_HOST="ssh://<your-host-name>"
接下来,您可以将
docker exec
与 rsync
结合使用,将数据复制到目标容器中。这需要您通过例如docker ps
获取容器ID。注意,rsync
必须安装在容器中。
#
rsync -ar -e 'docker exec -i' <local-source-path> <container-id>:/<destintaion-in-the-container>
由于使用了
rsync
,这也将允许您在稍后的某个时刻恢复(如果使用了适当的标志)上传。
我用这个单行复制较小的文件:
cat text.txt | ssh -q user@remote_host 'docker exec -i container_name /bin/cat > text.txt'
但不确定它是否应该用于大文件。
-q
将抑制来自 ssh 的可能的诊断消息/bin/cat >
是将 STDIN 中的数据写入 text.txt
文件,该文件位于容器内的工作目录中。