答案1
到目前为止,docker 引擎有一个--registry-mirror
选项,但该选项仅适用于配置 Docker hub 的镜像。目前有一些未解决的问题,正在研究是否或如何调整该选项以允许镜像其他注册表,但还没有足够的动力来进行这种改变。如果您的上游注册表是 docker hub,则使用此标志指向本地缓存或镜像非常有用,因为对 hub 的请求会自动首先尝试此镜像,如果失败,则会尝试上游注册表。这意味着您不需要调整图像名称或担心本地中断。
Containerd 有一个类似的选项,它支持任何上游注册表,所以我相信这是我们最终会采用的。但是,如果你使用 docker,即使在幕后使用 containerd,我相信 docker 引擎仍然会执行镜像推送和拉取。
由于无法在 containerd 中配置此功能,我看到了一些用于缓存来自其他注册表的图像的选项:
配置 HTTP 缓存代理(如 squid)。您需要确保这会定期刷新可变响应(如图像清单)。层本身应保持不变,以便您可以长时间缓存它们。
直接从另一个镜像或缓存注册表中提取。
使用一些 DNS/TLS 劫持将请求发送到您的缓存或镜像。
配置拉取缓存注册表非常简单:
docker run -p 5000:5000 -e REGISTRY_PROXY_REMOTEURL=<upstream-url> registry:2
然而,我倾向于运行镜像,因为拉取缓存配置了参赛作品有效期 7 天。因此,如果发生中断并且您的条目最近从拉取缓存中过期,您将受到该中断的影响。
运行镜像需要运行注册表,就像拉取缓存一样,然后复制您想要镜像的那些镜像。一些注册表,比如 Harbor,提供镜像功能。您可以指定要镜像到或从哪些远程注册表镜像。我个人使用 shell 脚本进行镜像,因为这允许我备份旧镜像(如果上游替换了标签,大多数镜像都会替换标签,让您没有恢复选项)。然后,我将那个脚本包含在我的 CI/CD 工作流中,以便在适当的时间运行,例如在冲刺开始时或每个星期一早上。镜像脚本示例在我的演示文稿中。
在本地注册表中提供映像后,您需要配置 docker 以从该注册表中提取。如果没有此--registry-mirror
选项,您要么需要调整映像名称,要么在网络/docker 主机上配置 DNS/TLS 以将请求指向本地注册表而不是上游注册表。后一个选项看起来很有吸引力,因为它允许您在不进行任何更改的情况下运行 docker 命令,映像构建、组合堆栈、helm 图表等都像与远程注册表通信一样工作。但是,管理自己的 TLS 证书和自签名 CA 更容易出错,网络上的所有主机都需要配置为信任这些证书和 CA。所以对我来说,简单的选择是调整注册表名称。在我的 Dockerfile 中,我将有类似以下内容:
ARG REGISTRY=docker.io
FROM ${REGISTRY}/library/alpine:3.9
这样网络外的其他人就可以构建此映像。然后在网络上的构建命令中,我将使用本地镜像覆盖参数:
docker build --build-arg REGISTRY=local-mirror:5000 .
docker-compose.yml
我在带有变量的文件中执行相同操作:
image: ${REGISTRY:-docker.io}/my/repo:and-tag
然后使用以下命令进行本地部署:
REGISTRY=local-mirror:5000 docker-compose up -d
我在 DockerCon 演示文稿中介绍了这一点。幻灯片发布到我的 github 上:https://github.com/sudo-bmitch/presentations/tree/master/registry