三节点 Kubernetes v1.28.2 集群部署指南(k8s)

一、背景介绍

Kubernetes(简称 K8s)是一个开源的容器编排平台,用于自动化容器化应用的部署、扩展和管理。它能够跨主机集群调度容器,提供容器编排、服务发现、负载均衡、自愈能力、配置管理等核心功能,已成为云原生应用的核心基础设施。随着容器技术的普及,搭建稳定、兼容的 K8s 集群成为企业和开发者的必备技能。

本文将提供一套无省略、全细节、逐条标注操作主机的 K8s 集群部署方案,基于 v1.28.2 稳定版本,采用 containerd 作为容器运行时、Calico 作为网络插件,统一使用 systemd cgroup driver,全程使用阿里云镜像源加速,确保部署过程流畅、集群运行稳定。

二、关键词解释

  • Kubernetes 组件
    • Master(控制平面):集群核心管理节点,包含 API Server(集群入口)、etcd(数据存储)、Scheduler(调度器)、Controller Manager(控制器)等组件。
    • Worker(工作节点):运行容器化应用的节点,包含 kubelet(节点代理)、kube-proxy(网络代理)、容器运行时(本文为 containerd)。
  • 容器运行时:负责管理容器生命周期的软件,containerd 是轻量级容器运行时,兼容 OCI 标准,是 K8s 官方推荐的运行时之一(K8s v1.24+ 不再支持 Docker Engine)。
  • cgroup driver:用于限制容器资源(CPU、内存)的驱动,systemd 是 Linux 系统初始化系统,K8s 推荐使用 systemd cgroup driver 确保资源管理一致性。
  • 网络插件:Calico 是基于 BGP 协议的高性能网络插件,提供容器网络互通、网络策略控制等功能,支持大规模集群部署。
  • kubeadm:K8s 集群初始化工具,简化 master 节点初始化和 worker 节点加入流程。
  • kubectl:K8s 命令行工具,用于操作集群资源(创建、查看、删除 Pod、Service 等)。
  • IPVS:可选的负载均衡模式,相比 iptables 具有更高的性能和稳定性,适合大规模集群场景。
  • CNI:容器网络接口标准,用于实现容器之间的网络互通,Calico 是 CNI 插件的一种。

三、环境准备

1. 主机信息(需根据实际环境替换 IP)

主机名IP 地址角色
master172.24.221.34control-plane(控制平面)
worker1172.24.221.35worker(工作节点)
worker2172.24.221.36worker(工作节点)

2. 硬件要求

  • Master 节点:≥2 核 CPU,≥2GB 内存(生产环境推荐 4C8G+)
  • Worker 节点:≥1 核 CPU,≥1GB 内存(生产环境推荐 2C4G+)

3. 前置要求

  • 三台主机均为 CentOS 7.x 系统(64 位),支持 Rocky Linux 8 / AlmaLinux 8 兼容适配。
  • 所有节点配置静态 IP,三台主机之间网络互通(能互相 ping 通),且能访问外网(或已配置镜像缓存)。
  • 禁止使用 hostname 包含下划线、大写字母等特殊字符的主机。
  • 安全组规则:确保节点间开放以下端口(至少内网互通):6443(API Server)、2379-2380(etcd)、10250(kubelet)、10257/10259(scheduler/controller-manager);若使用 Flannel 需额外开放 8472 端口。

四、部署步骤

🔧 预备步骤:设置主机名与时间同步(在所有三台主机上执行)

K8s 集群对主机名唯一性和节点时间同步性要求极高,必须先完成此步骤。

1. 设置主机名

操作主机:分别在对应主机执行

master 节点

hostnamectl set-hostname master

worker1 节点

hostnamectl set-hostname worker1

worker2 节点

hostnamectl set-hostname worker2
2. 配置主机名解析(建议配置)

操作主机:master、worker1、worker2(分别执行)

# 编辑 hosts 文件
cat <<EOF | sudo tee -a /etc/hosts
172.24.221.34  master
172.24.221.35  worker1
172.24.221.36  worker2
EOF
3. 配置时间同步(必须执行)

K8s 集群节点时间差需控制在 5 秒内,否则会导致证书验证失败、Pod 调度异常等问题。

操作主机:master、worker1、worker2(分别执行)

# 安装 chrony 时间同步工具
yum install -y chrony

# 启动并设置开机自启
systemctl start chronyd
systemctl enable chronyd

# 同步时间
chronyc sources -v

# 验证时间同步状态
timedatectl

✅ 验证:timedatectl 输出中 NTP synchronized 应为 yesSystem clock synchronized 应为 yes

🔧 第一部分:系统初始化(在所有三台主机上执行)

操作主机:master、worker1、worker2(分别登录每台执行以下命令)

# 1. 关闭防火墙(K8s 集群内部通信无需防火墙拦截)
systemctl stop firewalld
systemctl disable firewalld

# 2. 关闭 SELinux(避免权限拦截容器操作)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# 3. 关闭 swap(Kubernetes 强制要求,避免内存交换影响性能)
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab

# 4. 安装必要工具(依赖包、网络工具等)
yum install -y yum-utils device-mapper-persistent-data lvm2 ipset ipvsadm

# 5. 加载必要内核模块(容器网络、IPVS 依赖)
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF

modprobe overlay
modprobe br_netfilter
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
modprobe nf_conntrack

# 6. 配置 sysctl 参数(开启网络转发、桥接过滤等功能)
cat <<EOF | sudo 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
vm.swappiness                       = 0
EOF

sysctl --system

✅ 验证:执行完后,每台机器应看到 sysctl: setting key "xxx": OK 类似输出,无报错即成功。

🐳 第二部分:安装 containerd(在所有三台主机上执行)

操作主机:master、worker1、worker2(分别登录每台执行)

# 1. 安装 containerd(默认安装稳定版,兼容 K8s v1.28)
yum install -y containerd.io

# 2. 生成 containerd 默认配置文件
containerd config default > /etc/containerd/config.toml

# 3. 编辑配置文件,启用 SystemdCgroup(关键:与 kubelet cgroup 驱动一致)
# ⚠️ 关于 sed 修改 config.toml 的风险提示
# 虽然 sed -i 's/false/true/' 看似简单,但 TOML 文件中可能存在多个 SystemdCgroup 字段(如旧版本模板),或字段不存在,导致:
# 1. 替换失败(仍为 false) 2. 重复添加(引发解析异常) 3. 缩进错误(虽 TOML 不强制缩进,但易读性差且可能被某些解析器拒绝)
# ✅ 更安全的做法:先备份,再手动编辑
cp /etc/containerd/config.toml /etc/containerd/config.toml.bak
vim /etc/containerd/config.toml

✅ 在 vim 中找到以下段落(约在文件中下部),按要求修改:

toml

          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            BinaryName = ""
            CriuImagePath = ""
            CriuPath = ""
            CriuWorkPath = ""
            IoGid = 0
            IoUid = 0
            NoNewKeyring = false
            NoPivotRoot = false
            Root = ""
            ShimCgroup = ""
            SystemdCgroup = true   # ← 确保仅此处存在该配置,缩进为 12 个空格

保存退出后继续执行:

# 4. 配置镜像加速(针对国内网络环境优化,可选但推荐)
sed -i 's#registry.k8s.io#registry.aliyuncs.com/google_containers#g' /etc/containerd/config.toml
sed -i '/\[plugins."io.containerd.grpc.v1.cri".registry.mirrors\]/a \  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\n    endpoint = ["https://registry.docker-cn.com", "https://mirror.baidubce.com"]' /etc/containerd/config.toml

# 5. 启动并设置 containerd 开机自启
systemctl restart containerd
systemctl enable containerd

# 6. 配置 crictl 使用 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

# 7. 验证配置生效(确认 SystemdCgroup 已启用)
crictl info | grep -A5 'SystemdCgroup'
# 验证配置文件无重复字段
grep -c 'SystemdCgroup' /etc/containerd/config.toml  # 输出应为 1

✅ 正确输出应包含:

json

"options": {
  "SystemdCgroup": true
}

📦 第三部分:安装 kubeadm、kubelet、kubectl(在所有三台主机上执行)

操作主机:master、worker1、worker2(分别登录每台执行)

# 1. 添加 Kubernetes 阿里云 YUM 源(国内加速,避免官方源访问超时)
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

# 2. 安装指定版本(v1.28.2,确保三台主机版本一致)
yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2 --disableexcludes=kubernetes

# 3. 配置 kubelet 使用 containerd 运行时及 systemd cgroup 驱动
cat > /etc/default/kubelet <<EOF
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock
EOF

# 4. 启用 kubelet 开机自启(暂不启动,待集群初始化后自动启动)
systemctl enable kubelet
systemctl daemon-reload

⚙️ 第四部分:验证 kubelet 状态(在所有三台主机上执行)

操作主机:master、worker1、worker2(分别登录每台执行)

# 查看 kubelet 状态
systemctl status kubelet    

🧹 第五部分:清理旧集群残留(仅在 master 上执行,如有需要)

操作主机:master(仅此一台)

如果之前在 master 节点安装过 K8s 集群,必须执行以下清理命令,避免残留文件影响新集群初始化:

# 重置 kubeadm 配置
kubeadm reset --force

# 手动删除残留文件(配置文件、数据存储、网络插件配置)
rm -rf /etc/kubernetes/
rm -rf /var/lib/etcd
rm -rf /etc/cni/net.d/

# 重启相关服务
systemctl restart containerd kubelet

# 确认关键端口未被占用(6443:API Server,2379/2380:etcd,10250:kubelet 等)
ss -tulnp | grep -E ':(6443|10259|10257|10250|2379|2380)'

✅ 预期结果:端口检查命令应无任何输出(无占用)。

💡 注意:worker 节点无需执行此步骤,因为它们尚未加入任何集群,无残留文件。

🚀 第六部分:初始化 Kubernetes 控制平面(仅在 master 上执行)

操作主机:master(仅此一台)

1. (可选)预拉取 K8s 核心镜像(网络较差时推荐)
# 创建镜像拉取脚本
cat > pull-k8s-images.sh << 'EOF'
#!/bin/bash
K8S_VERSION=v1.28.2
PAUSE_VERSION=3.9
ETCD_VERSION=3.5.9-0
COREDNS_VERSION=v1.10.1

images=(
  kube-apiserver:${K8S_VERSION}
  kube-controller-manager:${K8S_VERSION}
  kube-scheduler:${K8S_VERSION}
  kube-proxy:${K8S_VERSION}
  pause:${PAUSE_VERSION}
  etcd:${ETCD_VERSION}
  coredns:${COREDNS_VERSION}
)

# 使用 crictl 拉取(自动处理命名空间,兼容性更好)
for imageName in ${images[@]}; do
  full_image="registry.aliyuncs.com/google_containers/${imageName}"
  echo "Pulling $full_image"
  crictl pull "$full_image"
done
EOF

# 添加执行权限
chmod +x pull-k8s-images.sh

# 运行脚本拉取镜像
./pull-k8s-images.sh
2. 初始化 master 节点(必须执行)
# 使用kubeadm初始化k8s容器集群,1和2选择一个执行即可
# 1.直接执行初始化命令(推荐,便于查看实时输出)
kubeadm init \
  --kubernetes-version=v1.28.2 \
  --image-repository=registry.aliyuncs.com/google_containers \
  --apiserver-advertise-address=172.24.221.34 \
  --pod-network-cidr=192.168.0.0/16 \
  --service-cidr=10.96.0.0/12 \
  --v=5


# 2.创建集群初始化脚本(可选,也可直接执行命令)
cat > init-master.sh << 'EOF'
#!/bin/bash
kubeadm init \
  --kubernetes-version=v1.28.2 \
  --image-repository=registry.aliyuncs.com/google_containers \
  --apiserver-advertise-address=172.24.221.34 \
  --pod-network-cidr=192.168.0.0/16 \
  --service-cidr=10.96.0.0/12 \
  --v=5
EOF

# 添加执行权限
chmod +x init-master.sh

# 运行初始化脚本
./init-master.sh

⏳ 等待 2~5 分钟(取决于网络速度),直到看到 Your Kubernetes control-plane has initialized successfully! 提示,说明 master 节点初始化成功。

📝 关键步骤:务必记录最后输出的 kubeadm join 命令(你的 token 和 hash 会与示例不同),格式如下:

kubeadm join 172.24.221.34:6443 --token abcdef.0123456789abcdef \
	--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

建议复制该命令保存到文本文件(如记事本),后续 worker 节点加入集群时需使用。

💡 若初始化失败:执行 kubeadm reset --force && rm -rf /etc/cni/net.d && systemctl restart containerd 清理后重新执行初始化命令。

🧰 第七部分:配置 kubectl(仅在 master 上执行)

操作主机:master(仅此一台)

kubectl 是 K8s 命令行工具,需配置权限才能操作集群:

# 创建 kubectl 配置目录
mkdir -p $HOME/.kube

# 复制 master 节点的管理员配置文件到用户目录
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(仅当前终端有效)。

🌐 第八部分:安装 Calico 网络插件(三台主机全部执行)

操作主机:master,worker1,worker2

K8s 集群初始化后,需安装网络插件才能实现 Pod 之间的网络互通,本文选择 Calico v3.28.0(与 K8s v1.28 兼容):

# 方式一:在线安装(推荐,网络通畅时使用)
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml

# 方式二:离线安装(无网络环境使用)
# 1. 提前下载 calico 镜像包(calico-cni.tar、calico-node.tar)
# 2. 在所有节点导入镜像:ctr images import calico-cni.tar && ctr images import calico-node.tar
# 3. 下载 calico.yaml 本地执行:kubectl apply -f calico.yaml

# 验证 Calico Pod 启动状态(等待 1~2 分钟,直到所有 Calico Pod 运行)
kubectl get pods -n kube-system | grep calico

✅ 预期结果:

  • 看到 calico-node-xxxxx(当前仅 master 节点,故 1 个)。
  • 看到 calico-kube-controllers-xxxxx(1 个副本)。
  • 所有 Calico 相关 Pod 状态均为 Running

🔍 验证 Calico 网络是否真正就绪即使 calico-node 显示 Running,也可能因 BGP 未建立、IP 分配失败等原因导致 Pod 无法通信。执行以下检查:

# 1. 检查 Calico 节点状态(应显示所有节点为 Ready)
kubectl get nodes -o wide

# 2. 检查 Calico IPAM 是否分配 CIDR 给节点
kubectl get blockaffinities.crd.projectcalico.org -A

# 3. (可选)部署测试 Pod 验证跨节点通信(后续添加 worker 节点后可测试)
kubectl run test-pod --image=busybox --command -- sleep 3600

✅ 验证要点:

  • blockaffinities 输出非空,说明 Calico 已成功为节点分配网段。
  • 若 blockaffinities 为空,需查看 Calico 日志排查问题:kubectl logs -n calico-system <calico-node-pod-name>

若始终拉取calico镜像失败,且确认前面步骤均无问题,只有网络连接不上,则可使用如下方法(先使用docker拉取镜像,然后导入到containerd)(在master执行):

        1.使用 Docker 拉取 Calico 镜像

# 拉取 Calico 节点镜像
docker pull calico/node:v3.28.0
# 拉取 Calico CNI 插件镜像
docker pull calico/cni:v3.28.0
# 拉取 Calico 控制器镜像
docker pull calico/kube-controllers:v3.28.0

        2.将 Docker 镜像保存为 tar 包(关键:使用实际拉取的镜像名)

# 保存节点镜像
docker save docker.io/calico/node:v3.28.0 -o calico-node.tar
# 保存 CNI 插件镜像
docker save docker.io/calico/cni:v3.28.0 -o calico-cni.tar
# 保存控制器镜像
docker save docker.io/calico/kube-controllers:v3.28.0 -o calico-kube-controllers.tar

        3.导入镜像到 containerd(K8s 容器运行时)

# 导入镜像到 k8s.io 命名空间
ctr -n k8s.io images import calico-node.tar
ctr -n k8s.io images import calico-cni.tar
ctr -n k8s.io images import calico-kube-controllers.tar
# 验证镜像导入结果
ctr -n k8s.io images list | grep calico

        4.重新部署 Calico 网络插件

# 1.应用 Calico 官方配置
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml
# 2.删除失败的 Calico Pod(触发重建)
kubectl delete pods -n kube-system -l k8s-app=calico-node
kubectl delete pods -n kube-system -l k8s-app=calico-kube-controllers
# 3.检查 Calico Pod 状态
kubectl get pods -n kube-system | grep calico
# 4.验证 K8s 节点状态
kubectl get nodes

然后在worker主机执行

        1.在 Worker 节点上导入 Calico 镜像(与 Master 步骤相同)

# 1. 从Master节点拷贝Calico镜像tar包(或重新拉取)
scp root@master:/root/calico-node.tar /root/
scp root@master:/root/calico-cni.tar /root/
scp root@master:/root/calico-kube-controllers.tar /root/

# 2. 导入镜像到containerd
ctr -n k8s.io images import /root/calico-node.tar
ctr -n k8s.io images import /root/calico-cni.tar

        2.重启 kubelet 服务

systemctl restart kubelet

👥 第九部分:将 worker1 和 worker2 加入集群

✅ Worker 节点加入前自检清单(务必确认)

在执行 kubeadm join 前,请确保 worker 节点已完成以下检查:

  1. containerd 已安装并运行:systemctl status containerd(状态为 active running)
  2. kubelet 已安装并启用:systemctl is-enabled kubelet(输出 enabled)
  3. /etc/default/kubelet 已配置 --cgroup-driver=systemdcat /etc/default/kubelet
  4. 能从 worker 节点 ping 通 master 的 172.24.221.34:ping 172.24.221.34 -c 3
  5. 能从 worker 节点连通 master 的 6443 端口:
yum install -y telnet
telnet 172.24.221.34 6443
# 或
nc -vz 172.24.221.34 6443

若端口不通,检查 master 防火墙、安全组或 apiserver 是否监听正确 IP。

💡 ⚠️ 重要提示:避免 kubeadm join 命令输入错误

不要手动敲写 kubeadm join 命令!务必直接从 master 节点复制输出结果,以下是更安全的操作方式:

        1.在 master 上执行以下命令,直接生成单行可复制命令(即使 token 未过期也推荐):

kubeadm token create --print-join-command

        2.输出示例(单行格式,无换行):

kubeadm join 172.24.221.34:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        3.直接全选复制这一整行,在 worker 节点粘贴执行即可,避免任何换行或编辑错误。

🛠️ 若已发生类似 accepts at most 1 arg(s), received X 错误:

  • 检查命令中是否包含非法字符(如 ., #, $, 额外空格等)。
  • 使用 history | tail -n 5 查看实际执行的命令内容,定位错误位置。
  • 重新从 master 生成并复制命令,不要手动修改。
9.1 在 worker1 上执行

操作主机:worker1(仅此一台)

粘贴从 master 复制的单行 join 命令(示例如下,替换为你自己的命令):

# 示例命令(请替换为你 master 节点生成的实际命令!)
kubeadm join 172.24.221.34:6443 --token 9hx1dx.hwbjglx3vtkfx5yk --discovery-token-ca-cert-hash sha256:d86fa1adea8221356e5e55655a69f306178ba9c6176841c04c805555c1e7eb55

✅ 成功后会显示:This node has joined the cluster

9.2 在 worker2 上执行

操作主机:worker2(仅此一台)

粘贴与 worker1 完全相同的单行 join 命令(直接复制,不要修改):

# 示例命令(替换为你自己的实际命令!)
kubeadm join 172.24.221.34:6443 --token 9hx1dx.hwbjglx3vtkfx5yk --discovery-token-ca-cert-hash sha256:d86fa1adea8221356e5e55655a69f306178ba9c6176841c04c805555c1e7eb55

✅ 成功后同样显示:This node has joined the cluster

💡 常见问题:

  • 如果 token 过期(默认 24 小时),可在 master 节点重新生成 join 命令:kubeadm token create --print-join-command
  • 若加入失败,在 worker 节点执行清理:kubeadm reset --force && rm -rf /etc/cni/net.d && systemctl restart containerd 后重试。

✅ 第十部分:验证集群状态(仅在 master 上执行)

操作主机:master(仅此一台)

1. 查看所有节点状态
kubectl get nodes

✅ 正常输出(3 个节点全部为 Ready 状态):

plaintext

NAME      STATUS   ROLES           AGE   VERSION
master    Ready    control-plane   5m    v1.28.2
worker1   Ready    <none>          1m    v1.28.2
worker2   Ready    <none>          1m    v1.28.2
2. 查看所有系统 Pod 状态
kubectl get pods -A

✅ 预期结果:

  • 每个节点都有 calico-node-xxxxx(共 3 个)。
  • coredns-xxxxx(2 个副本,DNS 服务)。
  • kube-proxy-xxxxx(3 个,每节点 1 个)。
  • 所有 Pod 状态均为 Running(无 Pending 或 Error)。
3. 验证跨节点 Pod 通信(补充测试)
# 在 worker1 上找到测试 Pod(若之前未创建则执行 kubectl run test-pod --image=busybox --command -- sleep 3600)
POD_IP=$(kubectl get pods -o wide | grep test-pod | awk '{print $6}')

# 在 worker2 上创建临时 Pod 测试 ping 连通性
kubectl run temp-pod --image=busybox --rm -it --command -- ping $POD_IP -c 3

✅ 预期结果:ping 成功,无丢包。

4. 查看集群信息
kubectl cluster-info

✅ 正常输出应显示 API Server 地址及状态正常提示。

🎯 (可选)允许 Master 调度工作负载(仅测试环境)

操作主机:master(仅此一台)

默认情况下,master 节点为控制平面,不会调度用户 Pod(避免影响集群稳定性)。如果是测试环境,可移除污点允许调度:

# 移除 master 节点污点(生产环境不建议执行!)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

五、最终确认清单

检查项执行命令期望结果
所有节点 Readykubectl get nodes3 行输出,STATUS 均为 Ready
Calico 网络插件正常kubectl get pods -n calico-system3 个 calico-node + 1 个 calico-kube-controllers,均为 Running
cgroup 驱动一致`crictl infogrep SystemdCgroup`(每台)输出 "SystemdCgroup": true
kubelet 无报错journalctl -u kubelet -n 10(每台)无 cgroup 冲突、连接超时等错误
系统 Pod 全部运行kubectl get pods -Acoredns、kube-proxy 等均为 Running
集群信息正常kubectl cluster-info显示 API Server 地址及正常状态提示
跨节点 Pod 通信正常kubectl run temp-pod --image=busybox --rm -it --command -- ping <PodIP> -c 3ping 成功,无丢包

六、各主机操作汇总表

步骤masterworker1worker2
设置主机名与时间同步
系统初始化
安装 containerd
安装 kubeadm/kubelet/kubectl
配置 kubelet 运行时与 cgroup
清理旧集群残留
拉取 K8s 核心镜像(可选)
kubeadm init
配置 kubectl
安装 Calico
Worker 节点前置自检
kubeadm join
验证集群状态

七、常见问题与故障排除

  1. kubelet 启动失败,日志提示 cgroup driver mismatch

    • 原因:containerd 未启用 SystemdCgroup,或 kubelet 未配置 --cgroup-driver=systemd
    • 解决:重新执行第二部分第 3 步(手动编辑 containerd 配置)和第三部分第 3 步(配置 kubelet),确保两者 cgroup 驱动一致。
  2. Calico Pod 一直处于 Pending 状态

    • 原因:Pod 网络网段与 kubeadm init 中 --pod-network-cidr 不一致,或节点网络不通。
    • 解决:确保 kubeadm init 时 --pod-network-cidr=192.168.0.0/16,且三台主机之间能互相 ping 通。
  3. coredns 出现 CrashLoopBackOff

    • 原因:Calico 部署失败,或 Pod 网络未正常初始化。
    • 解决:查看 Calico 日志 kubectl logs -n calico-system <calico-node-pod-name>,排查网络配置或镜像拉取问题。
  4. worker 节点加入集群失败,提示 container runtime is not running

    • 原因:worker 节点未安装或未启动 containerd。
    • 解决:在 worker 节点重新执行第二部分(安装并启动 containerd)。
  5. kubectl 执行命令提示 The connection to the server xxx:6443 was refused

    • 原因:API Server 未启动,或 kubectl 配置文件错误。
    • 解决:检查 master 节点 kube-apiserver-xxxxx Pod 状态;重新执行第七部分(配置 kubectl)。
  6. kubeadm join 提示 accepts at most 1 arg(s), received X

    • 原因:命令中存在非法字符(如多余的点号、空格、换行符)。
    • 解决:在 master 重新生成单行 join 命令,直接复制粘贴执行,不手动编辑。

八、实战小 Demo:部署 Nginx 应用练手

集群搭建完成后,通过部署简单的 Nginx 应用熟悉 K8s 资源操作,包含 Deployment(部署)、Service(服务)。

一、环境准备(集群就绪)

确保 K8s 集群所有节点(Master+Worker)状态为Ready,网络插件(Calico/Flannel)正常运行:

kubectl get nodes

✅ 正常情况:所有节点状态为Ready,网络插件 Pod(calico-node/flannel)均为Running


二、正常场景:直接部署 Nginx(无网络 / 镜像限制)
1. 创建 Deployment 配置文件
cat > nginx-deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2  # 2个Pod副本
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine  # 轻量级Nginx镜像
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: "0.5"
            memory: "512Mi"
          requests:
            cpu: "0.2"
            memory: "256Mi"
EOF
2. 应用配置文件
kubectl apply -f nginx-deployment.yaml
3. 验证 Deployment 和 Pod
# 查看Deployment状态
kubectl get deployments

# 查看Pod状态
kubectl get pods

✅ 正常结果:Deployment 状态READY 2/2,Pod 自动拉取镜像并启动,状态为Running

4. 创建 Service 暴露服务
cat > nginx-service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort
EOF

kubectl apply -f nginx-service.yaml
5. 访问 Nginx 服务
# 获取NodePort端口
kubectl get svc nginx-service

# 访问服务(示例端口30080)
curl http://<任意节点IP>:30080

✅ 正常结果:返回 Nginx 默认欢迎页面。


三、异常场景:网络 / 镜像限制下的部署(国内环境适配)
1. 手动拉取并分发镜像
(1)在 Master 节点拉取镜像
docker pull nginx:1.25-alpine
docker save nginx:1.25-alpine -o nginx.tar
(2)分发镜像到所有 Worker 节点
scp /root/nginx.tar root@worker1:/root/
scp /root/nginx.tar root@worker2:/root/
(3)所有节点导入镜像到 containerd
# Master/Worker节点均执行
ctr -n k8s.io images import /root/nginx.tar
2. 重新部署 Nginx
kubectl apply -f nginx-deployment.yaml
kubectl delete pods -l app=nginx  # 重建Pod使用本地镜像
3. 验证部署结果
kubectl get pods

✅ 修复结果:Pod 使用本地镜像启动,状态为Running


四、扩展与更新应用(通用步骤)
1. 扩展 Pod 副本数
kubectl scale deployment nginx-deployment --replicas=3
kubectl get pods
2. 更新 Nginx 版本
# 正常场景:直接更新(自动拉取新镜像)
kubectl set image deployment/nginx-deployment nginx=nginx:1.26-alpine

# 异常场景:提前导入新镜像后更新
docker pull nginx:1.26-alpine
docker save nginx:1.26-alpine -o nginx-1.26.tar
# 分发并导入所有节点后执行更新
kubectl set image deployment/nginx-deployment nginx=nginx:1.26-alpine
3. 查看更新状态
kubectl rollout status deployment/nginx-deployment

五、清理资源(通用步骤)
kubectl delete svc nginx-service
kubectl delete deployment nginx-deployment

总结

  1. 正常场景:外网通畅时可直接部署,K8s 自动拉取镜像并运行;
  2. 异常场景:国内环境需手动拉取镜像并分发到所有节点,确保 Pod 能使用本地镜像启动;
  3. 核心差异:镜像获取方式(自动拉取 vs 手动导入),其余部署步骤完全一致。

总结

本文提供了一套从零开始部署三节点 K8s v1.28.2 集群的完整方案,覆盖环境准备、系统配置、容器运行时安装、K8s 组件部署、集群初始化、网络插件安装、节点加入、状态验证及实战 Demo 全流程,特别强化了容错性、可操作性和新手友好度。

核心优化要点:

  1. 新增 kubeadm join 输入安全指南,通过单行命令生成 + 直接复制的方式,避免换行、非法字符等常见输入错误。
  2. 补充 containerd 配置修改的风险提示,推荐备份 + 手动编辑的安全方式,防止配置文件结构破坏。
  3. 增强 Calico 网络验证,从单纯查看 Pod 状态升级到 IP 分配检查 + 跨节点通信测试,确保网络真正可用。
  4. 增加 Worker 节点加入前自检清单,提前排查环境问题,减少 join 失败概率。
  5. 优化镜像预拉取脚本,使用 crictl 提升兼容性,同时注明仅网络极差时必要。
  6. 统一所有代码块的语言标识,提升文档可读性和专业性。

按照文中步骤操作,即可获得稳定兼容的 K8s 集群,结合 Nginx 实战 Demo 可快速上手 K8s 应用部署与管理,为后续复杂应用运维打下基础!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值