Skip to main content

Exporting and importing docker images manually

 


Why

Sometimes it can be handy to have a copy of a container image locally or being able to manually copy a docker image from one computer to another. 

Recently I had an issue where newly built Kubernetes worker nodes did not work properly due to the fact that the flannel pod image was hosted on quay.io, which was not available at the time. The "fix" was to manually export the image from a server which had flannel running just fine and import on the new worker nodes (and restart the flannel pods).

Export

Assuming we want to save / export the image below:

$ docker images
REPOSITORY     TAG       IMAGE ID       CREATED       SIZE
kindest/node   <none>    af39c553b6de   2 weeks ago   1.12GB

We run docker save with the image id and redirect the output into a new local file.

$ docker save af39c553b6de > kindest-node.tar

Once done, we end up with a new tar file, which can be compressed optionally.

$ ls -lah kindest-node.tar 
-rw-rw-r-- 1 user user 1.1G Jun  6 12:11 kindest-node.tar
$ file kindest-node.tar
kindest-node.tar: POSIX tar archive

$ time pigz kindest-node.tar
real 0m3.353s
user 0m44.956s
sys 0m1.693s

$ ls -lah kindest-node.tar.gz 
-rw-rw-r-- 1 user user 450M Jun  6 12:11 kindest-node.tar.gz

Then we can copy the file to a different computer and import the image.

Import

To import the image manually, run the following command:

$ cat kindest-node.tar.gz | gzip -d | docker load
fe4ff16afbd5: Loading layer [==================================================>]  81.79MB/81.79MB
5b0bb23616f6: Loading layer [==================================================>]  15.36kB/15.36kB
af7c97115567: Loading layer [==================================================>]  3.584kB/3.584kB
0b1209dd2b24: Loading layer [==================================================>]   25.6kB/25.6kB
b0841d5ea26b: Loading layer [==================================================>]   12.8kB/12.8kB
20f5bf344878: Loading layer [==================================================>]  4.096kB/4.096kB
9adb7beab274: Loading layer [==================================================>]  3.072kB/3.072kB
c4d2062b972b: Loading layer [==================================================>]  3.072kB/3.072kB
463693fedd13: Loading layer [==================================================>]   7.68kB/7.68kB
9981da0c28e6: Loading layer [==================================================>]   5.12kB/5.12kB
1d56cf6e0165: Loading layer [==================================================>]  217.7MB/217.7MB
d0261d0f10de: Loading layer [==================================================>]  824.1MB/824.1MB
Loaded image ID: sha256:af39c553b6deb8ad9c3fb94ee6b4afbe3f7501296cf7e2f20aa1f8a13494f24c

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
<none>       <none>    af39c553b6de   2 weeks ago   1.12GB

$ docker tag af39c553b6de kindest/node:v1.21

$ docker images
REPOSITORY     TAG       IMAGE ID       CREATED       SIZE
kindest/node   v1.21.1   af39c553b6de   2 weeks ago   1.12GB

Voila, we have the image with correct tag on the new server ready to use.

Conclusion

While you should keep your Docker container images in your own container registry or proxy / cache external registries wherever you can it can be quite handy to know how to manually keep copies of your images or move them from one Docker runtime to another.

I have now set up a local Docker registry image proxy for quay.io, so this issue will hopefully not be repeated.



Comments

Popular posts from this blog

Manual Kubernetes TLS certificate renewal procedure

Intro Kubernetes utilizes TLS certificates to secure different levels of internal and external cluster communication.  This includes internal services like the apiserver, kubelet, scheduler and controller-manager etc. These TLS certificates are created during the initial cluster installation and are usually valid for 12 months. The cluster internal certificate authority (CA) certificate is valid for ten years. There are options available to automate certificate renewals, but they are not always utilised and these certs can become out of date. Updating certain certificates may require restarts of K8s components, which may not be fully automated either. If any of these certificates is outdated or expired, it will stop parts or all of your cluster from functioning correctly. Obviously this scenario should be avoided - especially in production environments. This blog entry focuses on manual renewals / re-creation of Kubernetes certificates. For example, the api-server certificate below...

Analysing and replaying MySQL database queries using tcpdump

Why There are situations where you want to quickly enable query logging on a MySQL Database or trouble shoot queries hitting the Database server in real-time. Yes, you can enable the DB query log and there are other options available, however the script below has helped me in many cases as it is non intrusive and does not require changing the DB server, state or configuration in any way. Limitations The following only works if the DB traffic is not encrypted (no SSL/TLS transport enabled). Also this needs to be run directly on the DB server host (as root / admin). Please also be aware that this should be done on servers and data you own only. Script This script has been amended to suit my individual requirements. #!/bin/sh tcpdump -i any -s 0 -l -w - dst port 3306 | strings | perl -e ' while(<>) { chomp; next if /^[^ ]+[ ]*$/;   if(/^(ALTER|COMMIT|CREATE|DELETE|DROP|INSERT|SELECT|SET|UPDATE|ROLLBACK)/i) {     if (defined $q) { print "$q\n"; }     $q=$_; ...

Deprecating Networking Ingress API version in Kubernetes 1.22

  Intro Kubernetes deprecates API versions over time. Usually this affects alpha and beta versions and only requires changing the apiVersion: line in your resource file to make it work. However with this Ingress object version change, additional changes are necessary. Basics For this post I am quickly creating a new cluster via Kind (Kubernetes in Docker) . Once done, we can see which API versions are supported by this cluster (version v1.21.1). $ kubectl api-versions | grep networking networking.k8s.io/v1 networking.k8s.io/v1beta1 Kubernetes automatically converts existing resources internally into different supported API versions. So if we create a new Ingress object with version v1beta1 on a recent cluster version, you will receive a deprecation warning - and the same Ingress object will exist both in version v1beta1 and v1. Create $ cat ingress_beta.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:   name: clusterpirate-ingress spec:   rules:  ...