skopeo 是一个命令行工具,可对容器镜像和容器存储进行操作。 在没有dockerd的环境下,使用 skopeo 操作镜像是非常方便的。

安装

包管理器

# RHEL / CentOS Stream ≥ 8 sudo dnf install skopeo # RHEL/CentOS ≤ 7.x yum install skopeo # openSUSE: sudo zypper install skopeo # alpine: sudo apk add skopeo # macOS: brew install skopeo # ArchLinux sudo pacman -S skopeo

其他系统见 安装文档

编译安装

git clone https://github.com/containers/skopeo skopeo cd !$ git checkout v1.0.0 make binary-static DISABLE_CGO=1 cp skopeo /usr/local/bin/

使用

在使用 skopeo 之前,我们首先要知道在命令行中镜像的格式

需要注意的是,这几种镜像的名字,对应着镜像存在的方式,不同存在的方式对镜像的 layer 处理的方式也不一样,比如 docker:// 这种方式是存在 registry 上的,docker-daemon: 是存在本地 docker pull 下来的,再比如 docker-archive 是通过 docker save 出来的镜像。同一个镜像有这几种存在的方式就像水有气体、液体、固体一样。可以这样去理解,他们表述的都是同一个镜像,只不过是存在的方式不一样而已。

IMAGE NAMESexample
containers-storage:containers-storage:
dir:dir:/PATH
docker://docker://k8s.gcr.io/kube-apiserver:v1.17.5
docker-daemon:docker-daemon:alpine:latest
docker-archive:docker-archive:alpine.tar (docker save)
oci:oci:alpine:latest

命令选项

# skopeo --help NAME: skopeo - Various operations with container images and container image registries USAGE: skopeo [global options] command [command options] [arguments...] VERSION: 0.1.37 COMMANDS: copy Copy an IMAGE-NAME from one location to another inspect Inspect image IMAGE-NAME delete Delete image IMAGE-NAME 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 help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --debug enable debug output --policy value Path to a trust policy file --insecure-policy run the tool without any policy check --registries.d DIR use registry configuration files in DIR (e.g. for container signature storage) --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 --command-timeout value timeout for the command execution (default: 0s) --help, -h show help --version, -v print the version

可以看到 skopeo 的功能很简单:

  • copy:复制一个镜像从 A 到 B,这里的 A 和 B 可以为本地 docker 镜像或者 registry 上的镜像。
  • inspect:查看一个镜像的 manifest 火车 image config 详细信息
  • delete:删除一个镜像,可以是本地 docker 镜像或者 registry 上的镜像
  • list-tags:列出一个 registry 上某个镜像的所有 tag
  • login:登录到某个 registry,和 docker login 类似
  • logout: 退出已经登录到某个 registry 的 auth 信息,和 docker logout 类似
  • manifest-digeststandalone-signstandalone-verify 这三个用的不多
  • sync:同步一个镜像从 A 到 B,感觉和 copy 一样,但 sync 支持的参数更多,功能更强大

获取镜像的信息

skopeo 可以在不用下载镜像的情况下,获取镜像信息

# skopeo inspect docker://docker.io/centos { "Name": "docker.io/library/centos", "Digest": "sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700", "RepoTags": [ "5.11", "5", "6.10", "6.6", "6.7", "6.8", "6.9", "6", "7.0.1406", "7.1.1503", "7.2.1511", "7.3.1611", "7.4.1708", "7.5.1804", "7.6.1810", "7.7.1908", "7", "8.1.1911", "8", "centos5.11", "centos5", "centos6.10", "centos6.6", "centos6.7", "centos6.8", "centos6.9", "centos6", "centos7.0.1406", "centos7.1.1503", "centos7.2.1511", "centos7.3.1611", "centos7.4.1708", "centos7.5.1804", "centos7.6.1810", "centos7.7.1908", "centos7", "centos8.1.1911", "centos8", "latest" ], "Created": "2020-01-18T00:26:46.850750902Z", "DockerVersion": "18.06.1-ce", "Labels": { "org.label-schema.build-date": "20200114", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS", "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00", "org.opencontainers.image.licenses": "GPL-2.0-only", "org.opencontainers.image.title": "CentOS Base Image", "org.opencontainers.image.vendor": "CentOS" }, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:8a29a15cefaeccf6545f7ecf11298f9672d2f0cdaf9e357a95133ac3ad3e1f07" ] }
docker://: 是使用 Docker Registry HTTP API V2 进行连接远端
docker.io: 远程仓库
centos: 镜像名称

也可以获取本地dockerd的镜像信息

# skopeo inspect docker-daemon:ubuntu:latest { "Name": "docker.io/library/ubuntu", "Digest": "sha256:004d05bd520c5c386fb8322d6081f4de567a9417e1ba8e5071663d7811992c88", "RepoTags": [], "Created": "2020-03-20T19:20:22.835345724Z", "DockerVersion": "18.09.7", "Labels": null, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:c8be1b8f4d60d99c281fc2db75e0f56df42a83ad2f0b091621ce19357e19d853", "sha256:977183d4e9995d9cd5ffdfc0f29e911ec9de777bcb0f507895daa1068477f76f", "sha256:6597da2e2e52f4d438ad49a14ca79324f130a9ea08745505aa174a8db51cb79d", "sha256:16542a8fc3be1bfaff6ed1daa7922e7c3b47b6c3a8d98b7fca58b9517bb99b75" ] }
docker-daemon: docker守护镜像的镜像
ubuntu:latest: 本地镜像的名称

拷贝镜像

注意一下,这里的 location 就是指的上面提到的 IMAGE NAMES ,也就是说 skopeo copy src dest 可以有 6*6=36 种组合!比如我可以将一个镜像从一个 registry 复制到另一个 registry,skopeo copy docker://IMAGE_NAME docker://IMAGE_NAME,再强调一遍,一定要注意 IMAGE_NAME 的命名的格式。

在不使用 docker 的情况下从远端下载镜像

# skopeo --insecure-policy copy docker://nginx:1.17.6 docker-archive:/tmp/nginx.tar Getting image source signatures Copying blob 8ec398bc0356 done Copying blob 465560073b6f done Copying blob f473f9fd0a8c done Copying config f7bb5701a3 done Writing manifest to image destination Storing signatures # ls -alh /tmp/nginx.tar -rw-r--r-- 1 root root 125M 4月 13 15:22 /tmp/nginx.tar
--insecure-policy: 用于忽略安全策略配置文件
docker://nginx:1.17.6: 该命令将会直接通过 http 下载目标镜像
docker-archive: 存储为 /tmp/nginx.tar,此文件可以直接通过 docker load 命令导入

相应的,可以将下载的文件导入到本地

# skopeo copy docker-archive:/tmp/nginx.tar docker-daemon:nginx:latest Getting image source signatures Copying blob 556c5fb0d91b done Copying blob 49434cc20e95 done Copying blob 75248c0d5438 done Copying config f7bb5701a3 done Writing manifest to image destination Storing signatures # docker images nginx REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest f7bb5701a33c 3 months ago 126MB

也可以将镜像下载到指定目录

# skopeo copy docker://busybox:latest dir:/tmp/busybox Getting image source signatures Copying blob 0669b0daf1fb done Copying config 83aa35aa1c done Writing manifest to image destination Storing signatures # ls -alh /tmp/busybox/ 总用量 760K drwxr-xr-x 2 root root 186 413 15:26 . drwxrwxrwt. 12 root root 4.0K 413 15:25 .. -rw-r--r-- 1 root root 743K 4月 13 15:26 0669b0daf1fba90642d105f3bc2c94365c5282155a33cc65ac946347a90d90d1 -rw-r--r-- 1 root root 1.5K 4月 13 15:26 83aa35aa1c79e4b6957e018da6e322bfca92bf3b4696a211b42502543c242d6f -rw-r--r-- 1 root root 527 4月 13 15:26 manifest.json -rw-r--r-- 1 root root 33 4月 13 15:25 version

或者从指定目录导入到本地

# skopeo copy dir:/tmp/busybox docker-daemon:busybox:latest Getting image source signatures Copying blob 0669b0daf1fb done Copying config 83aa35aa1c done Writing manifest to image destination Storing signatures # docker images busybox REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest 83aa35aa1c79 4 weeks ago 1.22MB

其他命令

skopeo --debug copy docker-archive:/dev/stdin containers-storage:foo < /tmp/nginx.tar

删除镜像

skopeo delete docker://localhost:5000/nginx:latest

认证文件

认证文件默认存放在 $HOME/.docker/config.json

文件内容

{ "auths": { "myregistrydomain.com:5000": { "auth": "dGVzdHVzZXI6dGVzdHBhc3N3b3Jk", "email": "stuf@ex.cm" } } }

其他参数

# 跳过源地址的 tls skopeo copy docker://192.168.25.8:5000/library/registry:latest oci-archive:registry-latest.tar --src-tls-verify=false # 跳过验证 tls skopeo list-tags --tls-verify=false docker://dockerio.vkvmsg1.skybyte.me/library/registry # 注意这里 dockerio 的顶级镜像自行补全 library 前缀

References

Docker #Containerd #Kubernetes

最后修改:2024 年 11 月 23 日
如果觉得我的文章对你有用,请随意赞赏