环境信息:

  • Master: 192.168.80.225 (k8s-master)

  • Node1: 192.168.80.226 (k8s-node1)

  • Node2: 192.168.80.227 (k8s-nobe2)

  • 软件版本: Kubernetes v1.28.2 | Containerd v1.7.x (锁定版本) | Calico v3.26.1


第一阶段:基础环境准备 (所有节点执行)

所有机器以 root 身份执行。

1. 初始化系统配置

# 1. 设置主机名 (仅示例,请在对应机器执行)
# hostnamectl set-hostname k8s-master

# 2. 配置 Hosts
cat >> /etc/hosts <<EOF
192.168.80.225 k8s-master
192.168.80.226 k8s-node1
192.168.80.227 k8s-nobe2
EOF

# 3. 关闭防火墙、Swap、SELinux (必须)
systemctl stop firewalld && systemctl disable firewalld
swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

2. 加载内核模块与网络参数

cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter

cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sysctl --system

第二阶段:安装与配置 Containerd (避坑核心)

核心策略:强制安装 1.7.x 版本,避开 v2.x 与 K8s 1.28 工具链的兼容性问题;直接写入正确配置,不依赖默认生成。

在所有节点执行:

1. 安装 Containerd 1.7.x

dnf install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 避坑点1:不要直接 install containerd.io,这会装上 v2.x
dnf install -y containerd.io-1.7.11
# 如果报错提示没有找到匹配可通过dnf list containerd.io --showduplicates | sort -r查看可用下载版本根据版本选择1.7的最新版本即可如不放心那就选择最新版本的上一版本
dnf install -y containerd.io-1.7.29

2. 写入“黄金配置” (SystemdCgroup + 阿里云镜像)

mkdir -p /etc/containerd
# 避坑点2:直接覆盖配置,防止 sed 改错或默认配置缺失 sandbox_image
cat <<EOF > /etc/containerd/config.toml
version = 2
[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
	# 核心:将 registry.k8s.io 替换为阿里云,解决初始化超时
    sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
      runtime_type = "io.containerd.runc.v2"
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
		# 核心:必须开启 SystemdCgroup,否则 kubelet 启动失败
        SystemdCgroup = true
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
        endpoint = ["https://docker.m.daocloud.io"] 
EOF

# 启动服务
systemctl enable --now containerd

3. 配置 crictl 客户端

# 避坑点3:crictl 默认连 docker,必须指定连 containerd
cat <<EOF > /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

第三阶段:安装 Kubernetes (所有节点)

1. 添加阿里云 YUM 源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

2. 安装组件

dnf install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2 --disableexcludes=kubernetes
systemctl enable --now kubelet

第四阶段:初始化 Master (仅 Master 节点)

1. 执行初始化

# 避坑点4:指定 image-repository 解决核心组件拉取问题
kubeadm init \
  --apiserver-advertise-address=192.168.80.225 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.28.2 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16

2. 配置 Kubectl 权限

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

第五阶段:部署网络插件 Calico (手动同步版)

背景:Worker 节点通常拉不动 docker.io 镜像,导致 Calico 卡在 Init:0/3。
策略:Master 下载 -> 导出 -> 传输 -> Worker 导入。

1. 准备清单文件 (Master)

curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml -O
# 替换为代理源,方便 Master 拉取
sed -i 's|docker.io/calico|docker.m.daocloud.io/calico|g' calico.yaml
kubectl apply -f calico.yaml

2. “手动搬运”镜像 (解决 ImagePullBackOff)
在 Master 上检查镜像是否已拉取 (crictl images | grep calico),然后执行:

# 1. 在 Master 导出
ctr -n k8s.io images export calico-cni.tar docker.m.daocloud.io/calico/cni:v3.26.1
ctr -n k8s.io images export calico-node.tar docker.m.daocloud.io/calico/node:v3.26.1
ctr -n k8s.io images export calico-ctl.tar docker.m.daocloud.io/calico/kube-controllers:v3.26.1

# 2. 发送给 Worker (Node1, Node2)
scp calico-*.tar root@192.168.80.226:/root/
scp calico-*.tar root@192.168.80.227:/root/

在 Worker 节点上执行导入:

# 避坑点5:必须指定 -n k8s.io,否则 kubelet 看不到
ctr -n k8s.io images import calico-cni.tar
ctr -n k8s.io images import calico-node.tar
ctr -n k8s.io images import calico-ctl.tar

第六阶段:Worker 加入与最终验证

1. Worker 加入集群
在 Node1 和 Node2 执行 kubeadm join ... (初始化时生成的命令)。

2. 解决 CNI 配置文件丢失问题 (避坑点6)
如果节点加入后长期 NotReady,报错 cni plugin not initialized:

  • 原因:可能为了排错删除了 /etc/cni/net.d。

  • 修复:在 Master 上执行 kubectl delete pod -l k8s-app=calico-node -n kube-system。重启的 Pod 会重新写入配置文件。

3. 部署测试应用 (Nginx)

# Master 操作
kubectl create deployment nginx-demo --image=docker.m.daocloud.io/library/nginx:alpine --replicas=2
kubectl expose deployment nginx-demo --port=80 --target-port=80 --type=NodePort

如果 Worker 上的 Pod 卡在 ContainerCreating,使用同样的“打包-SCP-导入”大法手动分发 Nginx 镜像。


附录:踩坑报错与解决方案总结

现象/报错信息 根本原因 解决方案
Timeout waiting for the condition (kubeadm init) 1. 无法拉取 pause 镜像<br>2. Cgroup 驱动不一致 (systemd vs cgroupfs) 1. config.toml 中修改 sandbox_image 为阿里云地址。<br>2. config.toml 中设置 SystemdCgroup = true。
crictl: context deadline exceeded / connection refused crictl 默认去连 Docker,但我们装的是 Containerd。 创建 /etc/crictl.yaml 指定 runtime-endpoint 为 containerd.sock。
CRI v1 runtime API is not implemented 安装了 Containerd v2.x,与 K8s 1.28 的工具链不兼容。 降级:卸载 v2,强制安装 containerd.io-1.7.11。
NetworkPluginNotReady: cni plugin not initialized /etc/cni/net.d/ 目录为空或不存在。通常因为排错时误删。 1. 确保目录存在 mkdir -p /etc/cni/net.d<br>2. 删除 Calico Pod 让其重建并重写配置。<br>3. 重启 kubelet。
Pod 一直 ContainerCreating / Init:0/3 Worker 节点网络差,无法从公网拉取镜像。 手动搬运:Master 导出 (ctr export) -> SCP -> Worker 导入 (ctr -n k8s.io import)。
ImagePullBackOff (尽管手动导入了镜像) 导入时忘记加 -n k8s.io 参数,镜像进了 default 命名空间,K8s 看不到。 在 Worker 上重新执行导入命令,务必加上 -n k8s.io。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐