Node Configuration Table
| Role | IP Address |
|---|---|
| master1 | 192.168.40.180 |
| master2* | 192.168.40.183 |
| node1 | 192.168.40.181 |
| node2* | 192.168.40.182 |
*Nodes marked with an asterisk are reserved for future cluster expansion.
Prerequisites for All Node
Hostname Assignment
hostnamectl set-hostname master1 && bash # Run on master1
hostnamectl set-hostname node1 && bash # Run on node1
Disable Firewall and SELinux
systemctl stop firewalld && systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
reboot
Configure Host Resolution
Append the following to /etc/hosts on every machine:
192.168.40.180 master1
192.168.40.181 node1
Establish Password-less SSH from master1
ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
ssh-copy-id node1
Disable Swap
swapoff -a
sed -i '/swap/ s/^/#/' /etc/fstab
Kernel Tuning and Bridged Traffic
modprobe br_netfilter
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
Add Yum Repositories
yum install -y yum-utils
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF
Time Synchronization
yum install -y ntpdate
ntpdate cn.pool.ntp.org
echo "* * * * * /usr/sbin/ntpdate cn.pool.ntp.org" | crontab
service crond restart
Install Essential Packages
yum install -y device-mapper-persistent-data lvm2 wget net-tools nfs-utils \
gcc make openssl-devel curl unzip vim socat ipvsadm conntrack
Container Runtime: containerd and Docker
Install and Configure containerd
yum install -y containerd.io-1.6.6
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
Edit /etc/containerd/config.toml:
- Set
SystemdCgroup = true - Replace
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"
systemctl enable --now containerd
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
systemctl restart containerd
Image Acceleration for containerd
In /etc/containerd/config.toml, set:
config_path = "/etc/containerd/certs.d"
Then create the mirror configuration:
mkdir -p /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml <<EOF
[host."https://ag38j4ig.mirror.aliyuncs.com",host."https://registry.docker-cn.com"]
capabilities = ["pull"]
EOF
systemctl restart containerd
Install Docker (Optional, for Image Building)
yum install -y docker-ce
systemctl enable --now docker
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://ag38j4ig.mirror.aliyuncs.com","https://registry.docker-cn.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
systemctl restart docker
Kubernetes Component Installation
yum install -y kubelet-1.26.0 kubeadm-1.26.0 kubectl-1.26.0
systemctl enable kubelet
Set the container runtime for crictl:
crictl config runtime-endpoint unix:///run/containerd/containerd.sock
Cluster Initialization on master1
Generate and Modify the Configuration
kubeadm config print init-defaults > kubeadm-init.yaml
Edit kubeadm-init.yaml with the following essential sections:
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.40.180
bindPort: 6443
nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock
name: master1
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: 1.26.0
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
Import Container Images Locally (Optional)
If you have pre-downloaded images (k8s_1.26.0.tar.gz), import them:
ctr -n=k8s.io images import k8s_1.26.0.tar.gz
Bootstrap the Control Plane
kubeadm init --config=kubeadm-init.yaml --ignore-preflight-errors=SystemVerification
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
Joining Worker Nodes
Retrieve the join command on master1:
kubeadm token create --print-join-command
Execute the command on node1:
kubeadm join 192.168.40.180:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash> --ignore-preflight-errors=SystemVerification
Network Plugin: Calico
Install Calico
Import the Calico image (calico.tar.gz) on both nodes:
ctr -n=k8s.io images import calico.tar.gz
Deploy Calico using the provided manifest:
kubectl apply -f calico.yaml
Verify that all pods are runing and nodes become Ready:
kubectl get nodes -w
Testing Pod Connectivity
kubectl run test-busybox --image=docker.io/library/busybox:1.28 --restart=Never --rm -it -- sh
# Inside the pod
ping www.baidu.com
nslookup kubernetes.default.svc.cluster.local
exit
Adding Secondary Nodes for Expansion
Worker Node 2 (node2)
Repeat all prerequisite steps and then run the same kubeadm join command (without the --control-plane flag).
Additional Control Plane Node (master2)
- Complete the prerequisite configuration as for node1.
- Import
k8s_1.26.0.tar.gzandcalico.tar.gzimages. - On master1, distribute certificate files:
mkdir -p /etc/kubernetes/pki/etcd && mkdir -p ~/.kube/ scp /etc/kubernetes/pki/{ca.crt,ca.key,sa.key,sa.pub,front-proxy-ca.crt,front-proxy-ca.key} master2:/etc/kubernetes/pki/ scp /etc/kubernetes/pki/etcd/{ca.crt,ca.key} master2:/etc/kubernetes/pki/etcd/ - Confirm that the
kubeadm-configConfigMap includescontrolPlaneEndpoint:kubectl -n kube-system edit cm kubeadm-config # Add or ensure the following exists: controlPlaneEndpoint: "192.168.40.180:6443" - Join the cluster as a control plane node:
kubeadm join 192.168.40.180:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash> --control-plane --ignore-preflight-errors=SystemVerification - Setup kubeconfig on master2:
mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config
CLI Tools Comparison: ctr vs crictl
- ctr: The native CLI for containerd. Can manage images outside of Kubernetes namespaces.
- crictl: Designed as a Kubernetes CRI client. Ideal for troubleshooting pods and containers but lacks direct image management commands like
pull/push. Usecrictlfor operations within thek8s.ionamespace.