Documentation Index
Fetch the complete documentation index at: https://support.lilt.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
This document entails steps and procedures to install k8s in an offline environment without internet access, whether in the cloud (public or private), or on bare-metal hardware.
System Parameters/Versions Used for this Example:
-
Rocky Linux: 8.10
-
K8s: 1.29.12
-
Containerd: 1.7.23
-
Docker: 27.2.0
-
One computer/system with containerd/docker installed and internet access.
- recommend to use a system with the same chipset as installation system (i.e. AMD64)
-
Destination offline system for installation (no internet access).
Prerequisites
The following packages/dependencies should already be completed:
-
base operating system (OS) updated and patched
-
containerd or docker installed (both on-line and off-line systems)
-
firewalld installed
Prepare K8S Images/Binaries
System with Internet Access
Download all required binaries/images. Perform the following steps from the system with internet access. This example uses a linux machine.
Step 1: Set Version
Set desired K8S version:
Step 2: Download K8S Packages
Download all K8S packages for installation on Rocky 8. Set the repository:
# set repository and repo
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/$K8S_VERSION/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/$K8S_VERSION/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
Pull packages, saved in /k8s directory:
sudo dnf install -y --downloadonly --downloaddir=/k8s kubelet kubeadm kubectl --disableexcludes=kubernetes
Compress directory for easier transfer:
tar -zcvf /k8s.tar.gz /k8s
Step 3 (optional): Determine Dependencies
Required dependencies are already listed in the following step, but can verify if necessary.
Check which version of K8S was downloaded:
Output should look similar to the following:
kubeadm-1.29.12-150500.1.1.x86_64.rpm
In this example, using v1.29.12. Set variable for kubeadm version:
export KUBEADM_VERSION=v1.29.12
Download kubeadm binary, make executable, and move to bin:
# download
curl -L https://dl.k8s.io/release/$KUBEADM_VERSION/bin/linux/amd64/kubeadm -o kubeadm_$KUBEADM_VERSION
# move binary
sudo mv kubeadm_$KUBEADM_VERSION /usr/local/bin/kubeadm
# set permissions to execute
sudo chmod +x /usr/local/bin/kubeadm
List dependencies:
kubeadm config images list --kubernetes-version=$KUBEADM_VERSION
Output should be similar to the following:
registry.k8s.io/kube-apiserver:v1.29.12
registry.k8s.io/kube-controller-manager:v1.29.12
registry.k8s.io/kube-scheduler:v1.29.12
registry.k8s.io/kube-proxy:v1.29.12
registry.k8s.io/coredns/coredns:v1.11.1
registry.k8s.io/pause:3.9
registry.k8s.io/etcd:3.5.16-0
Step 4: Prepare Dependency Images
Pull all required images, can use Docker or containerd.
Using Docker:
docker pull --platform=linux/amd64 registry.k8s.io/kube-apiserver:v1.29.12
docker pull --platform=linux/amd64 registry.k8s.io/kube-controller-manager:v1.29.12
docker pull --platform=linux/amd64 registry.k8s.io/kube-scheduler:v1.29.12
docker pull --platform=linux/amd64 registry.k8s.io/kube-proxy:v1.29.12
docker pull --platform=linux/amd64 registry.k8s.io/coredns/coredns:v1.11.1
docker pull --platform=linux/amd64 registry.k8s.io/pause:3.9
docker pull --platform=linux/amd64 registry.k8s.io/etcd:3.5.16-0
Save the images as compressed files so that they can be transferred to the offline system:
docker save -o kube-apiserver_v1.29.12.tar registry.k8s.io/kube-apiserver:v1.29.12
docker save -o kube-controller-manager_v1.29.12.tar registry.k8s.io/kube-controller-manager:v1.29.12
docker save -o kube-scheduler_v1.29.12.tar registry.k8s.io/kube-scheduler:v1.29.12
docker save -o kube-proxy_v1.29.12.tar registry.k8s.io/kube-proxy:v1.29.12
docker save -o coredns_v1.11.1.tar registry.k8s.io/coredns/coredns:v1.11.1
docker save -o pause_3.9.tar registry.k8s.io/pause:3.9
docker save -o etcd_3.5.16-0.tar registry.k8s.io/etcd:3.5.16-0
Using containerd:
ctr image pull --platform=linux/amd64 registry.k8s.io/kube-apiserver:v1.29.12
ctr image pull --platform=linux/amd64 registry.k8s.io/kube-controller-manager:v1.29.12
ctr image pull --platform=linux/amd64 registry.k8s.io/kube-scheduler:v1.29.12
ctr image pull --platform=linux/amd64 registry.k8s.io/kube-proxy:v1.29.12
ctr image pull --platform=linux/amd64 registry.k8s.io/coredns/coredns:v1.11.1
ctr image pull --platform=linux/amd64 registry.k8s.io/pause:3.9
ctr image pull --platform=linux/amd64 registry.k8s.io/etcd:3.5.16-0
Save the images as compressed files so that they can be transferred to the offline system:
ctr image export --platform=linux/amd64 kube-apiserver_v1.29.12.tar registry.k8s.io/kube-apiserver:v1.29.12
ctr image export --platform=linux/amd64 kube-controller-manager_v1.29.12.tar registry.k8s.io/kube-controller-manager:v1.29.12
ctr image export --platform=linux/amd64 kube-scheduler_v1.29.12.tar registry.k8s.io/kube-scheduler:v1.29.12
ctr image export --platform=linux/amd64 kube-proxy_v1.29.12.tar registry.k8s.io/kube-proxy:v1.29.12
ctr image export --platform=linux/amd64 coredns_v1.11.1.tar registry.k8s.io/coredns/coredns:v1.11.1
ctr image export --platform=linux/amd64 pause_3.9.tar registry.k8s.io/pause:3.9
ctr image export --platform=linux/amd64 etcd_3.5.16-0.tar registry.k8s.io/etcd:3.5.16-0
Step 5: Transfer Binaries/Images to Offline System
Transfer downloaded binaries and images to offline system. This can be done via secure ssh or removable storage media.
-
k8s.tar.gz
-
kube-apiserver_v1.29.12.tar
-
kube-controller-manager_v1.29.12.tar
-
kube-scheduler_v1.29.12.tar
-
kube-proxy_v1.29.12.tar
-
coredns_v1.11.1.tar
-
pause_3.9.tar
-
etcd_3.5.16-0.tar
Install K8S
Offline System without Internet Access
Import all binaries and images from the system with internet access to the offline system. This example uses a linux machine.
Commands have to be performed as root (since it involves installation of Kubernetes).
Step 1: Install K8S Packages
Unzip k8s.tar and install, then enable kubelet:
# unzip k8s components
tar -zxvf k8s.tar.gz
# install k8s
rpm -ivh --replacefiles --replacepkgs /k8s/*.rpm
# enable kubelet
systemctl enable kubelet.service
systemctl start kubelet.service
# check status
sudo systemctl status kubelet
Step 2: Load K8S Dependency Images
Load K8S images with either docker or containerd(using containerd for this example):
sudo ctr -n=k8s.io images import kube-apiserver_v1.29.12.tar
sudo ctr -n=k8s.io images import kube-controller-manager_v1.29.12.tar
sudo ctr -n=k8s.io images import kube-scheduler_v1.29.12.tar
sudo ctr -n=k8s.io images import kube-proxy_v1.29.12.tar
sudo ctr -n=k8s.io images import coredns_v1.11.1.tar
sudo ctr -n=k8s.io images import pause_3.9.tar
sudo ctr -n=k8s.io images import etcd_3.5.16-0.tar
Step 3: Initialize K8S
Initialize and setup cluster control-plane node:
CNI_CIDR="192.168.100.0/19"
SERVICE_CIDR="192.168.200.0/19"
NODE_NAME="my-node"
kubeadm init \
--pod-network-cidr $CNI_CIDR \
--service-cidr $SERVICE_CIDR \
--node-name $NODE_NAME
NOTE: Ensure that CNI and Service CIDRs are consistent with previous or desired installation.
Set kubectl config:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
Verify that the cluster is running:
Output should be similar to the following:
NAME STATUS ROLES AGE VERSION
ip-172-31-9-184.ec2.internal NotReady control-plane 37m v1.29.12
List running pods:
Output should be similar to the following:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-76f75df574-msppj 0/1 Pending 0 37m
kube-system coredns-76f75df574-pdn7f 0/1 Pending 0 37m
kube-system etcd-ip-172-31-9-184.ec2.internal 1/1 Running 0 37m
kube-system kube-apiserver-ip-172-31-9-184.ec2.internal 1/1 Running 0 37m
kube-system kube-controller-manager-ip-172-31-9-184.ec2.internal 1/1 Running 0 37m
kube-system kube-proxy-fj4k8 1/1 Running 0 37m
kube-system kube-scheduler-ip-172-31-9-184.ec2.internal 1/1 Running 0 37m
NOTE: coredns pods will be in “Pending” state until flannel (or other CNI) is installed.