docker 如何在中断时恢复下载图像?

de90aj5v  于 2023-06-05  发布在  Docker
关注(0)|答案(4)|浏览(520)

如何在断开连接时恢复pull?每次在断开连接后再次运行docker pull some-image时,pull进程总是从头开始。我的连接是如此不稳定,即使下载只是一个100MB的图像需要这么长的时间,几乎每次都失败。所以,我几乎不可能拉一个更大的图像。那么,如何恢复拉取过程?

qmelpv7a

qmelpv7a1#

更新:

现在,pull进程将根据已下载的图层自动恢复。这是用https://github.com/moby/moby/pull/18353实现的。

旧:

目前还没有resume功能。然而,有discussions围绕这个功能正在实现与docker的下载管理器。

vdzxcuhz

vdzxcuhz2#

Docker的代码并不像github上的moby那样更新。多年来,人们一直在讨论与此有关的问题。我曾尝试手动使用几个补丁,这些补丁还没有在上游,没有一个工作得很好。
moby的github仓库(docker的开发仓库)有一个名为download-frozen-image-v2.sh的脚本。这个脚本通过命令行使用bash、curl和其他类似JSON解释器的东西。它将检索一个docker令牌,然后将所有层下载到本地目录。然后,您可以使用'docker load'插入本地docker安装。
不过,这并不适合简历。它在脚本中有一些关于'curl -C'不工作的注解。我已经找到并解决了这个问题。我做了一个修改,它使用一个“.headers”文件来检索最初,它总是返回一个302,而我一直在监测,然后检索最终使用curl(+恢复支持)到层tar文件。它还必须在调用函数上循环,该函数检索有效的令牌,不幸的是,该令牌仅持续约30分钟。
它将循环该过程,直到它接收到416,该416指出由于它的范围已经被满足,因此不可能恢复。它还根据curl头检索验证大小。我已经能够检索使用此修改后的脚本所需的所有图像。Docker有更多与检索相关的层,并且有远程控制进程(Docker客户端),这使得它更难以控制,他们认为这个问题只会影响一些连接不好的人。
我希望这个脚本可以帮助你,就像它帮助我一样:
更改:fetch_blob函数在第一次连接时使用临时文件。然后它从中检索30 x HTTP重定向。它尝试在最终URL上进行头检索,并检查本地副本是否具有完整的文件。否则,它将开始恢复curl操作。传递有效令牌的调用函数有一个循环来检索令牌,fetch_blob确保获得完整的文件。
唯一的其他变化是带宽限制变量,可以在顶部设置,或通过“BW:10”命令行参数。我需要这一点,让我的连接是可行的其他业务。
对于修改后的脚本,单击here
将来,如果docker的内部客户端能够正确执行恢复,那就太好了。增加令牌验证的时间量将有很大的帮助。
变更代码的简要视图:

#loop until FULL_FILE is set in fetch_blob.. this is for bad/slow connections
            while [ "$FULL_FILE" != "1" ];do
                local token="$(curl -fsSL "$authBase/token?service=$authService&scope=repository:$image:pull" | jq --raw-output '.token')"
                fetch_blob "$token" "$image" "$layerDigest" "$dir/$layerTar" --progress
                sleep 1
            done

fetch_blob的另一部分:

while :; do
            #if the file already exists.. we will be resuming..
            if [ -f "$targetFile" ];then
                #getting current size of file we are resuming
                CUR=`stat --printf="%s" $targetFile`
                #use curl to get headers to find content-length of the full file
                LEN=`curl -I -fL "${curlArgs[@]}" "$blobRedirect"|grep content-length|cut -d" " -f2`

                #if we already have the entire file... lets stop curl from erroring with 416
                if [ "$CUR" == "${LEN//[!0-9]/}" ]; then
                    FULL_FILE=1
                    break
                fi
            fi

            HTTP_CODE=`curl -w %{http_code} -C - --tr-encoding --compressed --progress-bar -fL "${curlArgs[@]}" "$blobRedirect" -o "$targetFile"`
            if [ "$HTTP_CODE" == "403" ]; then
                #token expired so the server stopped allowing us to resume, lets return without setting FULL_FILE and itll restart this func w new token
                FULL_FILE=0
                break
            fi

            if [ "$HTTP_CODE" == "416" ]; then
                FULL_FILE=1
                break
            fi

            sleep 1
        done
kkbh8khc

kkbh8khc3#

我在Arch Linux上使用docker 24.0.2(不是docker桌面,只是你用pacman -S docker得到的任何东西)。
您可以通过将"features": {"containerd-snapshotter": true}添加到/etc/docker/daemon.json来启用docker pull恢复中断的下载。

sudo mkdir /etc/docker
sudo gedit /etc/docker/daemon.json

然后让它看起来像:

{
    "features": {"containerd-snapshotter": true}
}

重启dockerd:

systemctl restart docker

请注意,此功能仍处于实验阶段,将来可能会发生变化。此外,它似乎还支持其他一些东西,比如一次下载很多文件。那在我的机器上工作得很好,但是如果你的互联网连接很慢,你可能会有问题。
链接到配置文件文档。

vnzz0bqm

vnzz0bqm4#

试试这个
ps -ef | grep docker
获取所有docker pull命令的PID并对它们执行kill -9。一旦终止,重新发出docker pull <image>:<tag>命令。
这对我很有效!

相关问题