最近对于有上一个项目,由于是容器镜像形式交付并在内网部署:需要在内部网络拉取外网镜像仓库镜像,这样就需要原本不通外网的服务器节点通过代理的形式(网络复杂,巨慢)来拉取外网镜像。
为了解决拉取镜像耗时巨大的问题,这边考虑在内网自建镜像仓库Harbor,通过镜像同步的方式来拉取外网公共仓库的镜像存储到本地镜像仓库,实现内部节点拉取本地镜像来解决该问题。
我们常规的操作是用docker retag
来给镜像重新打标签,然后docker push
到我们新的仓库地址,这个也是最简单的方法
# 假设从dockerhub公共镜像仓库拉取 library/alpine:latest
# docker pull
root@ubuntu:~# docker pull alpine:latest
latest: Pulling from library/alpine
596ba82af5aa: Pull complete
Digest: sha256:d9a7354e3845ea8466bb00b22224d9116b183e594527fb5b6c3d30bc01a20378
Status: Downloaded newer image for alpine:latest
# docker tag
root@ubuntu:~# docker tag alpine:latest harbor.foo.com/library/alpine:latest
# docker push
root@ubuntu:~# docker push harbor.foo.com/library/alpine:latest
上述方法对于单个镜像操作,没有什么大的问题,但是涉及批量镜像迁移就会有一个问题:因为 docker pull –> docker tag –> docker push 的过程中会对镜像的 layer 进行解压缩,registry 中存储的镜像 layer 格式是 vnd.docker.image.rootfs.diff.tar.gzip
,因为 docker pull 镜像时会对 registry 上的 layer 进行解压缩,这一点和我们解压缩一些 gzip 压缩的资源一样道理,为了减少网络传输的流量。这样可以顺推 docker push
的时候也是类似,所以只是将镜像从一个 registry 复制到另一个 registry 来说,这些过程将在解压缩耗时巨大,显然不是最佳方案。
既然我们已经知道了在做镜像仓库迁移的时候的性能瓶颈在哪。那我们能不能有方法来规避这个解压缩的过程,直接是blob级别的复制,而不涉及layer的解压缩,那不是在迁移速度方面飞起。
由此引出了Skoepo
这个工具,可以使用 skopeo copy
直接从一个 registry 中复制镜像原始的 layer 到另一个 registry 中,期间不会涉及镜像 layer 解压缩操作
Skoepo的github项目地址:https://github.com/containers/skopeo
用法
skopeo --help
Various operations with container images and container image registries
Usage:
skopeo [command]
Available Commands:
copy Copy an IMAGE-NAME from one location to another
delete Delete image IMAGE-NAME
help Help about any command
inspect Inspect image IMAGE-NAME
list-tags List tags in the transport/repository specified by the REPOSITORY-NAME
login Login to a container registry
logout Logout of a container registry
manifest-digest Compute a manifest digest of a file
standalone-sign Create a signature using local files
standalone-verify Verify a signature using local files
sync Synchronize one or more images from one location to another
Flags:
--command-timeout duration timeout for the command execution
--debug enable debug output
-h, --help help for skopeo
--insecure-policy run the tool without any policy check
--override-arch ARCH use ARCH instead of the architecture of the machine for choosing images
--override-os OS use OS instead of the running OS for choosing images
--override-variant VARIANT use VARIANT instead of the running architecture variant for choosing images
--policy string Path to a trust policy file
--registries.d DIR use registry configuration files in DIR (e.g. for container signature storage)
--tmpdir string directory used to store temporary files
-v, --version Version for Skopeo
Use "skopeo [command] --help" for more information about a command.
可以看到 skopeo 的功能很简单:
skoepo copy
支持可以在各种存储机制之间复制容器镜像,包括:
$ skopeo copy docker://quay.io/buildah/stable docker://registry.internal.company.com/buildah
$ skopeo copy oci:busybox_ocilayout:latest dir:existingemptydirectory
#### skoepo delete
$ skopeo delete docker://localhost:5000/imagename:latest
skoepo sync 支持的参数更多
$ skopeo sync --src docker --dest dir registry.example.com/busybox /media/usb
$ skopeo sync --src dir --dest docker /media/usb/busybox:1-glibc my-registry.local.lan/test/
$ skopeo sync --src docker --dest dir --scoped registry.example.com/busybox /media/usb
Images are located at:
/media/usb/registry.example.com/busybox:1-glibc
/media/usb/registry.example.com/busybox:1-musl
/media/usb/registry.example.com/busybox:1-ubuntu
...
/media/usb/registry.example.com/busybox:latest
$ skopeo sync --src docker --dest docker registry.example.com/busybox my-registry.local.lan
Destination registry content:
REPO TAGS
registry.local.lan/busybox 1-glibc, 1-musl, 1-ubuntu, ..., latest
skopeo sync --src docker --dest docker registry.example.com/repo/busybox my-registry.local.lan/repo
Destination registry content:
REPO TAGS
registry.local.lan/repo/busybox 1-glibc, 1-musl, 1-ubuntu, ..., latest
skoepo inspect
这个命令可以查看一个镜像的 image config 和 mainfests文件,和 crictl inspect 命令差不多
skopeo inspect docker://alpine:latest --raw | jq "."
{
"manifests": [
{
"digest": "sha256:4661fb57f7890b9145907a1fe2555091d333ff3d28db86c3bb906f6a2be93c87",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"platform": {
"architecture": "amd64",
"os": "linux"
},
"size": 528
}
}
镜像存在方式
IMAGE NAMES | example |
---|---|
containers-storage: | containers-storage: |
dir: | dir:/PATH |
docker:// | docker://alpine:latest |
docker-daemon: | docker-daemon:alpine:latest |
docker-archive: | docker-archive:alpine.tar (docker save) |
oci: | oci:alpine:latest |