Manually Pull Container images used by Kubernetes kubeadm

Posted on 102 views

When setting up Kubernetes cluster with kubeadmin, an init command option is used to set up the Kubernetes control plane. Kubernetes has a number of Container images that will be used while bootstrapping a cluster.

In an environment where internet access is not reliable or when you have a restricted internet access like when using Proxy servers, or if your Kubernetes nodes doesn’t have internet access at all, it makes sense to pre-pull the container images to be used.

First you’ll need to print a list of images kubeadm will use ( on a machine with kubeadm installed).

$ sudo kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.22.2
k8s.gcr.io/kube-controller-manager:v1.22.2
k8s.gcr.io/kube-scheduler:v1.22.2
k8s.gcr.io/kube-proxy:v1.22.2
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4

The default registry used is k8s.gcr.io, you have an option to use a different registry. E.g using docker:

$ sudo kubeadm config images list --image-repository docker.io
docker.io/kube-apiserver:v1.22.2
docker.io/kube-controller-manager:v1.22.2
docker.io/kube-scheduler:v1.22.2
docker.io/kube-proxy:v1.22.2
docker.io/pause:3.5
docker.io/etcd:3.5.0-0
docker.io/coredns:v1.8.4

This will use the latest stable version of Kubernetes. You can also specify the version of Kubernetes to use, e.g stablelatest

$ sudo kubeadm config images list --kubernetes-version latest

Pull container images with kubeadm command

If your Kubernetes machines have access to internet for pulling Container images, you can use the kubeadm command to pre-pull the required images:

### Pull from default registry: k8s.gcr.io ###
$ sudo kubeadm config images pull

### Pull from a different registry, e.g docker.io or internal ###
$ sudo kubeadm config images pull --image-repository docker.io

For docker you may need to login to pull the images:

$ sudo docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: jmutai
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Note that if you change a container repository, you’ll need to do the same when running init.

$ sudo kubeadm init --image-repository  

Pull container images with docker / podman command

For Kubernetes nodes without internet access, you’ll need to download images from you Local machine and upload the to your Kubernetes nodes.

  • List images to be used on machine with kubeadm
sudo kubeadm config images list 
  • Download images locally
for image in k8s.gcr.io/kube-apiserver:v1.22.2 \
  k8s.gcr.io/kube-controller-manager:v1.22.2 \
  k8s.gcr.io/kube-scheduler:v1.22.2 \
  k8s.gcr.io/kube-proxy:v1.22.2 \
  k8s.gcr.io/pause:3.5 \
  k8s.gcr.io/etcd:3.5.0-0 \
  k8s.gcr.io/coredns:1.8.4; do
sudo docker pull $image;
done

If using podman:

for image in k8s.gcr.io/kube-apiserver:v1.22.2 \
  k8s.gcr.io/kube-controller-manager:v1.22.2 \
  k8s.gcr.io/kube-scheduler:v1.22.2 \
  k8s.gcr.io/kube-proxy:v1.22.2 \
  k8s.gcr.io/pause:3.5 \
  k8s.gcr.io/etcd:3.5.0-0 \
  k8s.gcr.io/coredns/coredns:v1.8.4; do
sudo docker pull $image;
done
  • Save images as .tar files
# Example
mkdir ~/k8s-images
docker save k8s.gcr.io/kube-apiserver:v1.22.2 > ~/k8s-images/kube-apiserver.tar
# Do the same for all other images
  • Upload saved images to Kubernetes nodes
rsync -av ~/k8s-images/* k8s-node:~/k8s-images/
  • Import .tar image files into Docker.
cd k8s-images/
ls * | while read image; do sudo docker load < $image; done

Here is a sample load output.

# ls * | while read image; do docker load < $image; done
225df95e717c: Loading layer [==================================================>]  336.4kB/336.4kB
7c9b0f448297: Loading layer [==================================================>]  41.37MB/41.37MB
Loaded image: k8s.gcr.io/coredns:1.6.5
fe9a8b4f1dcc: Loading layer [==================================================>]  43.87MB/43.87MB
ce04b89b7def: Loading layer [==================================================>]  224.9MB/224.9MB
1b2bc745b46f: Loading layer [==================================================>]  21.22MB/21.22MB
Loaded image: k8s.gcr.io/etcd:3.4.3-0
fc4976bd934b: Loading layer [==================================================>]  53.88MB/53.88MB
f103db1d7ea4: Loading layer [==================================================>]  118.6MB/118.6MB
Loaded image: k8s.gcr.io/kube-apiserver:v1.17.0
01b437934b9d: Loading layer [==================================================>]  108.5MB/108.5MB
Loaded image: k8s.gcr.io/kube-controller-manager:v1.17.0
ac06623e44c6: Loading layer [==================================================>]   42.1MB/42.1MB
Loaded image: k8s.gcr.io/kube-scheduler:v1.17.0
682fbb19de80: Loading layer [==================================================>]  21.06MB/21.06MB
2dc2f2423ad1: Loading layer [==================================================>]  5.168MB/5.168MB
ad9fb2411669: Loading layer [==================================================>]  4.608kB/4.608kB
597151d24476: Loading layer [==================================================>]  8.192kB/8.192kB
0d8d54147a3a: Loading layer [==================================================>]  8.704kB/8.704kB
6bc5ae70fa9e: Loading layer [==================================================>]  37.81MB/37.81MB
Loaded image: k8s.gcr.io/kube-proxy:v1.17.0
e17133b79956: Loading layer [==================================================>]  744.4kB/744.4kB
Loaded image: k8s.gcr.io/pause:3.1

Confirm the images are imported:

[[email protected] ~]# crictl images
IMAGE                                 TAG                 IMAGE ID            SIZE
docker.io/calico/apiserver            v3.20.1             4e7da027faaa7       53.2MB
docker.io/calico/cni                  v3.20.1             e69ccb66d1b65       146MB
docker.io/calico/kube-controllers     v3.20.1             5df320a38f63a       63.2MB
docker.io/calico/node                 v3.20.1             355c1ee44040b       158MB
docker.io/calico/pod2daemon-flexvol   v3.20.1             55fa5eb71e097       21.8MB
docker.io/calico/typha                v3.20.1             8473ae43d01b8       59.4MB
k8s.gcr.io/coredns/coredns            v1.8.4              8d147537fb7d1       47.7MB
k8s.gcr.io/etcd                       3.5.0-0             0048118155842       296MB
k8s.gcr.io/kube-apiserver             v1.22.2             e64579b7d8862       130MB
k8s.gcr.io/kube-controller-manager    v1.22.2             5425bcbd23c54       123MB
k8s.gcr.io/kube-proxy                 v1.22.2             873127efbc8a7       105MB
k8s.gcr.io/kube-scheduler             v1.22.2             b51ddc1014b04       53.9MB
k8s.gcr.io/pause                      3.2                 80d28bedfe5de       688kB
k8s.gcr.io/pause                      3.5                 ed210e3e4a5ba       690kB
quay.io/tigera/operator               v1.20.3             98e04bee27575       48.2MB

You can then proceed with your Kubernetes installation with locally added images. Depending on the CNI you use, you may need to pull its image as well in advance if doing offline installations.

coffee

Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.