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).

$ kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.17.0
k8s.gcr.io/kube-controller-manager:v1.17.0
k8s.gcr.io/kube-scheduler:v1.17.0
k8s.gcr.io/kube-proxy:v1.17.0
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.5

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

$ kubeadm config images list --image-repository docker.io
docker.io/kube-apiserver:v1.17.0
docker.io/kube-controller-manager:v1.17.0
docker.io/kube-scheduler:v1.17.0
docker.io/kube-proxy:v1.17.0
docker.io/pause:3.1
docker.io/etcd:3.4.3-0
docker.io/coredns:1.6.5

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

$ 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 -------
# kubeadm config images pull

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

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

# 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.

# 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
kubeadm config images list 
  • Download images locally
for image in k8s.gcr.io/kube-apiserver:v1.17.0 
  k8s.gcr.io/kube-controller-manager:v1.17.0 
  k8s.gcr.io/kube-scheduler:v1.17.0 
  k8s.gcr.io/kube-proxy:v1.17.0 
  k8s.gcr.io/pause:3.1 
  k8s.gcr.io/etcd:3.4.3-0 
  k8s.gcr.io/coredns:1.6.5; do
docker pull $image;
done

If using podman:

for image in k8s.gcr.io/kube-apiserver:v1.17.0 
  k8s.gcr.io/kube-controller-manager:v1.17.0 
  k8s.gcr.io/kube-scheduler:v1.17.0 
  k8s.gcr.io/kube-proxy:v1.17.0 
  k8s.gcr.io/pause:3.1 
  k8s.gcr.io/etcd:3.4.3-0 
  k8s.gcr.io/coredns:1.6.5; do
docker pull $image;
done
  • Save images as .tar files
# Example
mkdir ~/k8s-images
docker save k8s.gcr.io/kube-apiserver:v1.17.0 > ~/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 docker load < $image; done

Here is a sample load output.

# ls * | while read image; do docker load ]  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:

# docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
k8s.gcr.io/kube-proxy                v1.17.0             7d54289267dc        4 weeks ago         116MB
k8s.gcr.io/kube-apiserver            v1.17.0             0cae8d5cc64c        4 weeks ago         171MB
k8s.gcr.io/kube-controller-manager   v1.17.0             5eb3b7486872        4 weeks ago         161MB
k8s.gcr.io/kube-scheduler            v1.17.0             78c190f736b1        4 weeks ago         94.4MB
k8s.gcr.io/coredns                   1.6.5               70f311871ae1        2 months ago        41.6MB
k8s.gcr.io/etcd                      3.4.3-0             303ce5db0e90        2 months ago        288MB
k8s.gcr.io/pause                     3.1                 da86e6ba6ca1        2 years ago         742kB

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.

Also check:

How To Setup Local OpenShift 4.2 Cluster with CodeReady Containers

How To Export and Import Docker Images / Containers

How To run Docker Containers using Podman and Libpod

Best Books To learn Docker and Ansible Automation