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 NAMES | example |
---|---|
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 上某个镜像的所有 taglogin
:登录到某个 registry,和 docker login 类似logout
: 退出已经登录到某个 registry 的 auth 信息,和 docker logout 类似manifest-digest
、standalone-sign
、standalone-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 4月 13 15:26 .
drwxrwxrwt. 12 root root 4.0K 4月 13 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": "[email protected]"
}
}
}
其他参数
# 跳过源地址的 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 前缀