当前位置: 首页 > news >正文

Kubernetes v1.24.17 全离线部署实战(Containerd + Calico)

适用环境:CentOS 7.9 / Rocky Linux 7.9 |容器运行时:Containerd |网络插件:Calico
架构:1 Master + 2 Node |模式:全离线(Air-Gap)


目录

📖 一、 什么是 Kubernetes (K8s)?

1. 基础定义

2. 它有什么用?

📌 前言

🛠️ 第一阶段:所有节点通用系统初始化(Master + Node1 + Node2)

1. 设置主机名与 Hosts 解析

2. 关闭防火墙与 SELinux

3. 关闭 Swap

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

5. 时间同步与时区设置

📦 第二阶段:所有节点部署 Containerd**(Master + Node1 + Node2)**

1. 解压离线包并安装 Containerd

2. 配置 Containerd

3. 启动并验证服务

4. 导入离线镜像(核心步骤)

5.确认containerd健康

⚙️ 第三阶段:所有节点安装 K8s 核心组件

1. 导入安装 kubeadm, kubelet, kubectl

2. 版本一致性校验

🚀 第四阶段:仅在 Master 节点初始化集群

1. 清理旧环境(如果是重装)

2. 执行 kubeadm init

3. 配置 kubectl 凭证

4. 验证控制平面

5. 移除 Master 污点 (可选,方便单节点测试)

6. 部署 Calico 网络插件

7. 验证 Master 节点状态

➕ 第五阶段:Worker 节点加入集群

1. 在 Master 生成 Token

2. 在 Node 节点执行 Join 命令

🎉 第六阶段:集群验证与测试

1. 查看节点状态

2. 检查系统 Pod

3. 创建测试 Pod 验证网络

⚠️ 避坑指南(小白必看)

📝 总结


📖 一、 什么是 Kubernetes (K8s)?

在开始部署之前,我们需要先搞清楚:K8s 到底是什么?它能干什么?

1. 基础定义

Kubernetes(简称 K8s,K 和 s 之间有 8 个字母)是一个开源的容器编排引擎
如果把 Docker 比作“集装箱卡车”(负责运行应用),那么 Kubernetes 就是“港口调度系统”(负责管理成千上万辆卡车)。

2. 它有什么用?

在微服务时代,应用被拆分成无数个小容器。如果没有 K8s,你需要手动去每台服务器启动、停止、重启容器。
K8s 的核心价值在于:

  • 自动化部署与回滚:一键发布新版本,出问题自动回退。
  • 服务发现与负载均衡:自动分配 IP 和 DNS 名称,流量自动分摊。
  • 自我修复:某个容器挂了,K8s 会自动拉起一个新的,保证服务不中断。
  • 弹性伸缩:流量大了自动增加容器数量,流量小了自动减少,节省资源。

📌 前言

在生产环境中,服务器往往无法直接访问互联网。本文档记录了从零开始,在完全离线的环境下部署一套高可用、稳定的 Kubernetes v1.24.17 集群的全过程。

集群规划

IP 地址主机名角色
192.168.30.153k8s-masterMaster 节点
192.168.30.154k8s-node1Worker 节点
192.168.30.155k8s-node2Worker 节点

**准备工作

**请提前下载好离线包k8s-offline-full.tar.gz,并上传至三台服务器的/root目录。


🛠️ 第一阶段:所有节点通用系统初始化(Master + Node1 + Node2)

注意:以下命令需要在三台机器上分别执行。

1. 设置主机名与 Hosts 解析

**设置主机名

**根据规划,分别设置每台机器的主机名。

# 在 192.168.30.153 上执行 hostnamectl set-hostname k8s-master # 在 192.168.30.154 上执行 hostnamectl set-hostname k8s-node1 # 在 192.168.30.155 上执行 hostnamectl set-hostname k8s-node2

**配置 Hosts 文件

**在三台机器上执行相同的命令,确保节点间可以通过主机名互相访问。

cat >> /etc/hosts << EOF 192.168.30.153 k8s-master 192.168.30.154 k8s-node1 192.168.30.155 k8s-node2 EOF

**验证解析

**执行以下脚本,确保输出结果中所有项均为✓ 成功

for node in k8s-master k8s-node1 k8s-node2; do echo "=== 测试节点: $node ===" echo -n "主机名解析: " if ping -c 1 -W 1 $node >/dev/null 2>&1; then echo "✓ 成功"; else echo "✗ 失败"; fi ip=$(grep "$node" /etc/hosts | awk '{print $1}') echo "对应 IP: $ip" echo -n "IP 连通性: " if ping -c 1 -W 1 $ip >/dev/null 2>&1; then echo "✓ 成功"; else echo "✗ 失败"; fi echo -n "hosts 记录: " grep "$node" /etc/hosts || echo "未找到" echo "" done #额外验证:反向测试 for ip in 192.168.30.153 192.168.30.154 192.168.30.155; do echo -n "连接到 $ip: " if ping -c 1 -W 1 $ip >/dev/null 2>&1; then echo "✓ 可达" else echo "✗ 不可达" fi done #检验主机名唯一性 for node in k8s-master k8s-node1 k8s-node2; do printf "%-15s %-20s " "$node" "$(grep $node /etc/hosts | awk '{print $1}')" if ping -c 1 -W 1 $node >/dev/null 2>&1; then echo "✓ 连通正常" else echo "✗ 无法连通" fi done echo "hosts 文件配置验证:" cat /etc/hosts | grep -E "k8s-master|k8s-node1|k8s-node2"

2. 关闭防火墙与 SELinux

为了避免网络拦截和权限问题,我们需要关闭防火墙和 SELinux。

# 关闭防火墙 systemctl stop firewalld systemctl disable firewalld # 临时关闭 SELinux setenforce 0 # 永久关闭 SELinux(重启生效) sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

3. 关闭 Swap

Kubernetes 官方强烈建议关闭 Swap 分区以获得更好的性能。

# 临时关闭 swapoff -a # 永久关闭(注释掉 fstab 中的 swap 行) sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

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

配置网络桥接和流量转发,这是 K8s 网络工作的基础。

# 加载模块 modprobe br_netfilter modprobe overlay # 写入永久配置 cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF # 使配置立即生效 sysctl --system

5. 时间同步与时区设置

集群内时间必须一致,误差不能超过几秒。

# 启动并设置开机自启 chronyd 服务 systemctl start chronyd systemctl enable chronyd # 设置时区为上海 timedatectl set-timezone Asia/Shanghai # 查看状态(关键指标 NTP synchronized: yes) timedatectl status /#方法一:使用 chronyc 检查(推荐) # 1. 查看时间同步源 chronyc sources -v # 2. 查看时间同步状态(核心指标) chronyc tracking /#方法二:使用 timedatectl 检查 #这个命令可以一眼看出系统时钟是否已同步。 timedatectl status #验证要点(必须全部满足): #NTP enabled: yes #NTP synchronized: yes #(这是最关键的指标,表示已成功同步) #System clock synchronized: yes #Time zone: Asia/Shanghai #RTC in local TZ: no #(建议设为 no,避免双系统时间错乱)

**集群时间一致性校验

**在 Master 节点执行,确保所有节点时间一致:

/# 方法三:集群内多节点一致性校验(For 循环) for node in k8s-master k8s-node1 k8s-node2; do echo -n "$node 时间: " ssh $node "date '+%Y-%m-%d %H:%M:%S'" done

📦 第二阶段:所有节点部署 Containerd**(Master + Node1 + Node2)**

注意:以下命令需要在三台机器上分别执行。

1. 解压离线包并安装 Containerd

cd /root tar -xvzf k8s-offline-full.tar.gz cd /root/k8s-offline/rpms/ # 使用 yum localinstall 解决依赖关系 yum localinstall -y containerd.io-1.6.21-3.1.el7.x86_64.rpm container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm # 验证版本 rpm -qa | grep containerd containerd --version

2. 配置 Containerd

这是离线部署最容易出错的地方,请务必仔细核对。

# 生成默认配置文件 mkdir -p /etc/containerd containerd config default > /etc/containerd/config.toml # 关键修改1: 将 cgroup 驱动改为 systemd(K8s 推荐) sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml # 关键修改2: 指定本地 pause 镜像(注意版本号必须与离线包内的 pause 镜像一致) sed -i 's#sandbox_image = ".*"#sandbox_image = "registry.k8s.io/pause:3.7"#g' /etc/containerd/config.toml # 验证修改是否生效 grep -E "SystemdCgroup|sandbox_image" /etc/containerd/config.toml

3. 启动并验证服务

systemctl daemon-reload systemctl restart containerd systemctl enable containerd # 检查状态 grep -E "SystemdCgroup|sandbox_image" /etc/containerd/config.toml # 应看到 SystemdCgroup = true 和 sandbox_image ="registry.k8s.io/pause:3.7"

4. 导入离线镜像(核心步骤)

注意:K8s 使用的是k8s.io命名空间,不是默认的default

# 导入基础镜像(包含 pause, kube-proxy 等) ctr -n k8s.io images import /root/k8s-offline/k8s-base-images.tar # 导入 Calico 网络插件镜像 ctr -n k8s.io images import /root/k8s-offline/calico-images.tar # 验证镜像列表 ctr -n k8s.io images list

5.确认containerd健康

  1. 确认 containerd 健康状态

在所有节点(Master 和 Node)上完成 containerd 部署后,首先需要验证其运行状态。

  1. **检查服务状态 **执行以下命令,确认服务处于active (running)状态。
systemctl status containerd
  1. **检查版本信息 **执行以下命令,确认能正常显示客户端(client)和服务端(server)的版本信息。
ctr version # 能看到 client 和 server 版本

所有节点做完后,下一步做什么

当你所有 master + node 都完成了 containerd 的部署,并且 systemctl status

containerd 都是 running 状态后:

  1. Master 节点执行 kubeadm init … 初始化集群
  2. Node 节点拿到 master 输出的 kubeadm join … 命令后执行,加入集群
  3. 在 master 上 kubectl get nodes 能看到 node 状态变成 Ready给小白的几个避坑提醒

⚙️ 第三阶段:所有节点安装 K8s 核心组件

注意:以下命令需要在三台机器上分别执行。

1. 导入安装 kubeadm, kubelet, kubectl

cd /root/k8s-offline/rpms yum localinstall -y \ kubernetes-cni-1.1.1-0.x86_64.rpm \ cri-tools-1.24.0-0.x86_64.rpm \ *kubelet-1.24.17*.rpm \ *kubeadm-1.24.17*.rpm \ *kubectl-1.24.17*.rpm # 设置 kubelet 开机自启(注意:此时 kubelet 尚未启动,等待 init/join 后才会真正运行) systemctl enable kubelet

2. 版本一致性校验

确保三台机器的版本完全一致,避免诡异问题。

kubelet --version kubeadm version kubectl version --client

预期输出:所有版本均为v1.24.17


🚀 第四阶段:仅在 Master 节点初始化集群

注意:以下命令k8s-master(192.168.30.153) 上执行。

1. 清理旧环境(如果是重装)

如果是第一次安装,跳过此步;如果是重装,必须执行。

kubeadm reset -f iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X ipvsadm -C rm -rfv /etc/kubernetes /var/lib/etcd /var/lib/kubelet $HOME/.kube

2. 执行 kubeadm init

kubeadm init \ --kubernetes-version=v1.24.17 \ --apiserver-advertise-address=192.168.30.153 \ --image-repository=registry.aliyuncs.com/google_containers \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12 \ --node-name=k8s-master \ --cri-socket=unix:///run/containerd/containerd.sock

3. 配置 kubectl 凭证

初始化成功后,按照终端提示执行以下命令:

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

4. 验证控制平面

kubectl get pods -n kube-system

预期输出etcdkube-apiserverkube-controller-managerkube-scheduler均为Running

5.移除 Master 污点 (可选,方便单节点测试)

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

6. 部署 Calico 网络插件

由于是离线环境,我们已经有了calico.yaml文件。

# 应用 Calico 配置 kubectl apply -f /root/k8s-offline/calico.yaml #如果出错: rm -f /root/k8s-offline/calico.yaml wget https://docs.projectcalico.org/v3.25/manifests/calico.yaml -O /root/k8s-offline/calico.yaml # 监控 Pod 启动状态(等待几分钟) kubectl get pods -n kube-system -w

直到calico-node-xxxcalico-kube-controllers-xxx全部变为Running

7. 验证 Master 节点状态

kubectl get nodes

预期输出k8s-master状态变为Ready


➕ 第五阶段:Worker 节点加入集群

注意:以下命令在Node1 和 Node2上执行。

1. 在 Master 生成 Token

如果刚才 Master 初始化时的命令丢了,可以在 Master 上重新生成:

kubeadm token create --print-join-command

2. 在 Node 节点执行 Join 命令

重点:必须指定--cri-socket参数指向 containerd。

kubeadm join 192.168.30.153:6443 \ --token xxxxxx.xxxxxxxxxxxxxxxx \ --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ --cri-socket=unix:///run/containerd/containerd.sock

🎉 第六阶段:集群验证与测试

注意:以下命令在Master上执行。

1. 查看节点状态

等待几分钟,直到所有节点状态为Ready

# Master 验证节点加入(两台 Worker 节点会自动调度 calico-node Pod,随后依次变为 Ready。) kubectl get nodes -w kubectl get nodes -o wide

2. 检查系统 Pod

确保所有系统组件运行正常。

kubectl get pods -n kube-system

3. 创建测试 Pod 验证网络

# 创建一个 Nginx Pod kubectl run test-nginx --image=nginx # 查看 Pod 是否运行及 IP 分配情况 kubectl get pods -o wide # 进入 Pod 测试网络(可选) kubectl exec -it test-nginx -- curl k8s-master:6443

⚠️ 避坑指南(小白必看)

  1. Pause 镜像版本不一致config.toml里的sandbox_image版本必须与k8s-base-images.tar里的 pause 镜像版本严格一致(例如都是3.7),否则 Node 节点会一直NotReady
  2. 镜像命名空间错误: 导入镜像时必须加-n k8s.io。如果导入到了default,K8s 是找不到镜像的,会导致ImagePullBackOff
  3. 忘记指定 CRI Socket: 在kubeadm initkubeadm join时,如果不指定--cri-socket,新版本 K8s 可能会尝试连接 Docker,导致报错。
  4. Swap 未关闭: 虽然可以通过参数忽略,但强烈建议物理关闭 Swap,否则可能引发 kubelet 异常。

K8s 核心学术名词解析

在 K8s 的学习和面试中,以下名词是必须掌握的“黑话”:

1. 架构组件类
  • Master Node (控制平面):集群的大脑。包含 API Server(唯一入口)、Scheduler(调度器)、Controller Manager(管家)、etcd(数据库)。
  • Worker Node (工作节点):干活的苦力。包含 Kubelet(接收指令)、Kube-proxy(网络代理)、Container Runtime(容器运行时)。
  • Pod:K8s 的最小调度单位。一个 Pod 可以包含一个或多个容器(通常是 1 个),它们共享网络和存储。
  • CNI (Container Network Interface):容器网络接口标准。Calico、Flannel 都是 CNI 插件的实现,负责给 Pod 分配 IP 并打通网络。
2. 控制器与工作负载类
  • Deployment:最常用的控制器,用于管理无状态应用(如 Nginx)。它保证指定数量的 Pod 副本一直运行。
  • DaemonSet:守护进程集。保证每个(或特定)节点上都运行一个 Pod 副本。常用于日志收集、监控代理、网络插件(如 Calico)。
  • Service:服务发现。Pod 是 ephemeral(短暂的,IP 会变),Service 提供一个固定的 VIP(虚拟 IP)来访问一组 Pod。
3. 状态与策略类
  • Ready:表示 Pod 已经准备好接收流量。
  • CrashLoopBackOff:容器启动后立刻挂掉,K8s 正在尝试指数退避重启。通常是应用配置错误。
  • ImagePullBackOff:拉取镜像失败。通常是镜像名写错、仓库没权限或离线环境没导入镜像。
  • Taints & Tolerations (污点与容忍)
    • 污点:节点说“我不喜欢这类 Pod,别往我这调度”。
    • 容忍:Pod 说“我不介意那个污点,我就要去那个节点”。
    • 实战应用:Master 节点默认有污点,不允许运行业务 Pod,除非你执行kubectl taint nodes ...去除它。

📝 总结

至此,一个基于 Containerd、版本为 v1.24.17 的 Kubernetes 三节点集群已全部搭建完成。你可以开始在上面部署你的微服务应用了!

如果觉得这篇文章对你有帮助,请点赞收藏支持一下!如有问题,欢迎在评论区留言讨论。

http://www.jsqmd.com/news/1324748/

相关文章:

  • Android源码编译:模块清理原理与高效操作指南
  • 正规的长途出院救护车哪里有卖?成都专业转运机构怎么选才靠谱? - 优质品牌商家
  • Shellcode免杀技术实战:从静态加密到动态系统调用的攻防对抗
  • Claude自己跑出去hack了3家公司——我为什么还在用它写代码
  • Python量化交易入门:从环境搭建到策略开发
  • 老旧安卓电视的终极救星:MyTV-Android免费直播完整解决方案
  • C++返回值优化(RVO)原理与实践:消除拷贝提升性能
  • 商业智能预置模板:提升BI项目效率的关键
  • 免费AI内容检测对抗工具实测与优化技巧
  • 黔西南州厨房漏水怎么处理_2026贵州西南部万峰林马岭河峡谷州府漏水维修攻略与精选 - 雨婺虹房屋维修
  • PyTorch 深度学习笔记(五)张量拼接与自动微分——构建神经网络基础
  • SpringBoot+Vue水质监测系统全栈开发实践
  • 2026年企业知识库管理工具排行榜 行业观察选型避坑指南
  • Hot-55 跳跃游戏
  • 【机器学习】随机森林算法——集成学习原理与垃圾邮件分类实战
  • 如何免费解锁Twitch订阅专属内容:3分钟安装完整指南
  • Python栈与队列实现:从list、deque到手动链表,性能与应用全解析
  • 英雄联盟Akari助手:免费开源的游戏自动化工具箱,提升你的竞技体验
  • 基于SSM框架的反诈骗平台开发实战
  • Qt 多线程架构从入门到精通:QThread 与 QtConcurrent 选型对比及实时波形卡顿治理
  • 腾讯云轻量服务器Docker容器化部署实战:从零到多应用管理
  • 3小时掌握BepInEx:Unity游戏插件开发从入门到实战
  • 3分钟打造专业级语音转文字工作流:Faster-Whisper-GUI完全指南
  • 第七天心得体会
  • 电赛通信协议设计:从帧结构到状态机,打造不丢数据的串口通信
  • Spring Boot入门指南:从零构建Java Web应用,告别配置地狱
  • 湘美书院谈AI系列经典哲学,奥德赛时期的等待者
  • 嵌入式学习笔记--liunx基础命令(unbantu)
  • 多物理场耦合仿真中的辐射传热建模与应用
  • Trae文件管理器紧凑模式优化指南