Deploying Kubernetes 1.17 on Ubuntu 18.04 Using Kubeadm

Configuring the Container Runtime

To begin, configure the Docker daemon to utilize a registry mirror, which accelerates image downloads. Create the necessary configuration file:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon. <<-'EOF'
{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
EOF

Apply the changes by reloading the systemd daemon and restarting the Docker service.

sudo systemctl daemon-reload
sudo systemctl restart docker

System Preparation

Kubernetes requires that swap memory be disabled. Execute the following commands to disable swap immediately and prevent it from mounting on reboot:

sudo swapoff -a
sudo sed -i '/ swap / s/^(.*)$/#\1/g' /etc/fstab

Reboot the system to ensure all changes take effect.

sudo reboot

Setting Up the Kubernetes Repository

Add the Aliyun mirror for Kubernetes packages to ensure accessibility. Import the GPG key and add the repository to the source list.

sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update

Installing Kubernetes Components

Install the specific versions of kubeadm, kubelet, and kubectl:

sudo apt-get install -y kubeadm=1.17.17-00 kubelet=1.17.17-00 kubectl=1.17.17-00

Pre-pulling Control Plane Images

Due to network restrictions, pull images from a local mirror and re-tag them. Save the following script as fetch_images.sh:

#!/bin/bash

IMAGES=(
  kube-apiserver:v1.17.17
  kube-controller-manager:v1.17.17
  kube-scheduler:v1.17.17
  kube-proxy:v1.17.17
  pause:3.1
  etcd:3.4.3-0
  coredns:1.6.5
)

ALIYUN_REPO="registry.cn-hangzhou.aliyuncs.com/google_containers"
K8S_REPO="k8s.gcr.io"

for img in "${IMAGES[@]}"; do
  echo "Processing $img..."
  sudo docker pull "$ALIYUN_REPO/$img"
  sudo docker tag "$ALIYUN_REPO/$img" "$K8S_REPO/$img"
  sudo docker rmi "$ALIYUN_REPO/$img"
done

Grant execution permissions and run the script:

chmod +x fetch_images.sh
sudo bash fetch_images.sh

Verifying Kubelet

Execute kubelet to check for immediate errors. A lack of critical errors indicates the service is ready for initialization.

kubelet --version

Initializing the Cluster

Initialize the Kubernetes master node using kubeadm. Define the pod network CIDR to match Flannel's default settings.

sudo kubeadm init \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.17.17 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16

If the output indicates success, configure kubectl for the current user:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Fixing Component Health Status

It is common for scheduler and controller-manager to appear Unhealthy due to the bind address configuration. Edit the manifests to comment out the port argument:

sudo sed -i 's/- --port=0/#- --port=0/g' /etc/kubernetes/manifests/kube-scheduler.yaml
sudo sed -i 's/- --port=0/#- --port=0/g' /etc/kubernetes/manifests/kube-controller-manager.yaml

Wait a moment and verify the component status:

kubectl get cs

Deploying the Pod Network

CoreDNS pods will remain pending until a network overlay is deployed. Install Flannel to handle the pod networking:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

If the connection to GitHub fails, download the kube-flannel.yml file manually and apply it locally. Once applied, ensure all pods in the kube-system namespace are running:

kubectl get pods -n kube-system

Enabling Master Scheduling

By default, the master node is tainted to prevent workload scheduling. Remove the taint to allow pods to run on the single-node cluster:

kubectl taint nodes --all node-role.kubernetes.io/master-

Deploying a Workload

Create a namespace and a simple Nginx pod to verify the cluster functionality. Create a file named test_pod.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: demo-env
---
apiVersion: v1
kind: Pod
metadata:
  name: web-frontend
  namespace: demo-env
spec:
  containers:
  - name: nginx-instance
    image: nginx:alpine
    ports:
    - containerPort: 80

Apply the configuration and verify the pod status:

kubectl apply -f test_pod.yaml
kubectl get pods -n demo-env

Tags: kubernetes Ubuntu kubeadm docker devops

Posted on Thu, 02 Jul 2026 17:14:38 +0000 by gijs