Skopeo

skopeo is a command line utility that performs various operations on container images and image repositories. see it’s git repos. This is really a fantastic tool! Other two complementaries are buildah and podman.

Command usage see here.

In Red Hat/Centos, you can use yum to install skopeo.

Note the docker registry should be secured by SSL/TLS, basic authentication can also apply.

Skopeo can do paralelly copy, you can run several skopeo processes in background then wait.

Docker Installed

In docker environmet, skopeo will check $HOME/.docker/config.json file for authentication (created by docker login command). If the auth file is there, you are good and you can directly copy image tar (or gzip tar) to docker registry and copy image directly from docker registry to local docker daemon for example (can use docker hub to do test):

1
2
3
4
5
6
7
skopeo copy \
docker-archive:<absolute or relative path>/<tar name>.tar.gz \
docker://<registry>[:5000]/<image name>:tag

skopeo copy \
docker://<registry>[:5000]/<image name>:tag \
docker-daemon:<image name>:tag

This is extremely efficient compare to old load/tag/push method. Many other benefits like no docker daemon needed, rootless please see doc.

Inspect docker image in registry:

1
2
skopeo inspect \
docker://<registry>[:5000]/<image name>:tag

Delete image in registry

1
2
skopeo delete \
docker://<registry>[:5000]/<image name>:tag

You must enable deletion in docker registry configuration:

No Docker Installed

If there is no docker daemon, skopeo will still work, but you need to explicitly give the auth creds and ssl/tls certificates path of the target registry, for example, the destination registry login user name and password are both demo, and the certificates path for ssl/tls is /root/certs (must include *.key, *.crt and *.cert, the *.crt and *.cert could be the same content if it’s self-signed).

1
2
3
4
5
6
7
8
9
10
11
skopeo copy \
--dest-creds demo:demo \
--dest-cert-dir /root/certs \
docker-archive:<absolute or relative path>/<tar name>.tar.gz \
docker://<registry>[:5000]/<image name>:tag

skopeo copy \
--src-creds demo:demo \
--src-cert-dir /root/certs \
docker://<registry>[:5000]/<image name>:tag \
docker-daemon:<image name>:tag

Inspect docker image in registry:

1
2
3
4
skopeo inspect \
--creds demo:demo \
--cert-dir /root/certs \
docker://<registry>[:5000]/<image name>:tag

Delete image in registry

1
2
3
4
skopeo delete \
--creds demo:demo \
--cert-dir /root/certs \
docker://<registry>[:5000]/<image name>:tag

You must enable deletion in docker registry configuration:

Other Use Case

One important use case is we pre-load image to target host machine because we pre-assign some application runs on some dedicated nodes. Pre-load will save much time from pull if the image is big, the application pod will up and run instantly.

So, how to copy image tarball from local to remote machine docker daemon? Yes there are --src-daemon-host and --dest-daemon-host options, but how?

Refer document from docker: By default, the Docker daemon listens for connections on a UNIX socket to accept requests from local clients. It is possible to allow Docker to accept requests from remote hosts by configuring it to listen on an IP address and port as well as the UNIX socket.

So, let first open the port in target host: It is conventional to use port 2375 for un-encrypted, and port 2376 for encrypted communication with the daemon.

注意,这里我只考虑了un-encrypted,因为设置encrypted connection可能会影响kubelet对docker的操控,我在使用完后关闭了这一端口,并且如果集群有单独的网关且访问worker nodes的IP是内部的,影响也不大。

Here we can configure remote access with systemd unit file or with daemon.json, I prefer the second one, because after systemd unit file update, I need to reload then restart docker:

1
2
systemctl daemon-reload
systemctl restart docker

Using daemon json file only need to restart, just add this line to it:

1
2
3
{
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}

You can listen on port 2375 on all network interfaces(eg: 0.0.0.0), or on a particular network interface using its IP address(eg: 172.192.10.1).

After restart docker service, check the port status:

1
netstat -lntp | grep 2375

Now we can execute copy:

1
2
3
4
skopeo copy \
--dest-daemon-host http://<target machine hostname or ip>:2375 \
docker-archive:<path>/<image tarball name>.tar.gz \
docker-daemon:<image name>:<tag>

Check these articles: Skopeo Copy to the Rescue

0%