3 minutes
Skopeo: a tool to move around container images
Skopeo is one of those tools you don’t know you need until you need it. I currently manage quite a bunch of small k3s clusters that connects to IoT devices and it behaves as a controller. The main issue I have, is that many of those clusters have bad Internet connectivity, or simply are on air gapped environments. Therefore, deploying new images is cumbersome, sometimes quite impossible and requires a lot of coordination and logistics. Here is where Skopeo takes place.
First, What is it?
Basically is a tool to copy, synchronize and manage container images from different registries and runtimes. It support docker,podman and other container storage formats. It doesn’t require a daemon or any service running so is quite useful specially if you don’t work with containers on daily basis, or you don’t have docker on your current workspace (if you are reading this, I guess that’s quite unreal.) Another feature is that you can sync or copy images between registries without the need to copy them to your local.
These are some examples found on skopeo repo README.md
$ skopeo copy docker://quay.io/buildah/stable docker://registry.internal.company.com/buildah
$ skopeo copy oci:busybox_ocilayout:latest dir:existingemptydirectory
I use podman on my local so my images are on containers-storage so you can perform same commands like the following:
$ skopeo copy containers-storage:localhost/image:tag docker://docker.io/user/image:tag
$ skopeo copy containers-storage:busybox_ocilayout:latest dir:existingemptydirectory
Air-gapped environments with k3s
Like I mentioned on the beginning of this blog post, what I need is to deploy updated versions of containers to a k3s cluster that is on an air-gapped environment or with slow connectivity. So the idea is use skopeo to copy the images to a USB stick or any other storage devices that will be used to deploy the container images on the k3s clusters.
So first lets copy the images to a tar file:
# I will copy from my local podman, but use any other transport
$ mkdir image-tag
$ skopeo copy containers-storage:localhost/important-image:tag docker-archive:image.tar:image:tag
Also you can sync the whole repository:
$ skopeo sync --src docker --dest docker-archive registry.example.com/image /media/usb/image
# copy them as docker-archive format
$ for i in $(ls -d */); do skopeo copy dir:"${i}" docker-archive:"${i}" && find . -maxdepth 1 -type f -exec mv {} {}.tar \; && rm -rfv "$i"; done
After this, import them using k3s crt
for i in $(ls); do sudo k3s ctr images import $i; done
After this you can verify you have your images on containerd because you will have a message like this:
unpacking docker.io/library/latest:latest (sha256:ccc3ef27fb601799c737dbc643135205ef3979f70b1ccdd4aa23175bea1ccef4)...done
Skopeo is quite an amazing tool, it solved an specific issue I had, but I will keep using this for moving container images and to move local images to minikube without having the need to push my credentials into it.