文档简介
本文基于 CentOS7 纯离线无外网环境,完整讲解 Kubernetes v1.28.2 集群从零搭建流程,采用 containerd 作为容器运行时、Flannel 作为网络插件,最后完成 JDK8 版本 SpringBoot 后端项目离线部署,解决离线环境镜像拉取、外网服务连通、自定义域名解析等一系列生产实战问题,并汇总全套踩坑经验,适合内网服务器、涉密环境、无外网机房部署参考。
一、集群整体环境规划
1.1 集群节点规划
| 集群角色 | 内网 IP | 主机名 | 操作系统 |
|---|---|---|---|
| Master 管理节点 | 内网主节点 IP | k8s-master | CentOS 7 |
| Worker 工作节点 | 内网工作节点 IP | k8s-node1 | CentOS 7 |
1.2 网络网段规划
- Pod 容器网段:10.244.0.0/16
- Service 服务网段:10.96.0.0/12
- 后端项目内置端口:10022
- 集群对外暴露端口:32022
1.3 外部依赖环境
- 注册中心:Nacos 部署在内网独立服务器
- 数据库:MySQL 数据库配置内网自定义域名映射,宿主机已配置 hosts 解析
二、集群所有节点统一初始化配置(必执行)
2.1 关闭防火墙与安全策略
离线集群无需防火墙拦截,直接关闭常驻安全防护
systemctl stop firewalld systemctl disable firewalld setenforce0sed-i's/^SELINUX=enforcing/SELINUX=disabled/'/etc/selinux/config2.2 永久关闭 Swap 交换分区
Kubernetes 强制要求关闭 Swap,否则集群初始化异常
swapoff-ased-i'/swap/d'/etc/fstab2.3 配置主机名与内网域名解析
# 主节点设置主机名hostnamectl set-hostname k8s-master# 工作节点设置主机名hostnamectl set-hostname k8s-node1# 统一写入本地域名解析cat>>/etc/hosts<<EOF 内网主节点IP k8s-master 内网工作节点IP k8s-node1 数据库内网IP 数据库自定义域名 EOF2.4 加载内核网络转发模块
开启容器网络转发内核参数,保证集群网络互通
cat>/etc/modules-load.d/k8s.conf<<EOF overlay br_netfilter EOFmodprobe overlay modprobe br_netfiltercat>/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 EOFsysctl--system三、离线安装 Containerd 容器运行时
3.1 离线本地安装依赖包
提前下载好 containerd 离线 RPM 包,所有节点统一执行
yum localinstall-ycontainerd-*.rpm3.2 生成并修改容器运行时配置
mkdir-p/etc/containerd containerd config default>/etc/containerd/config.toml# 统一开启 systemd 驱动(集群必统一,否则kubelet启动失败)sed-i's/SystemdCgroup = false/SystemdCgroup = true/'/etc/containerd/config.toml# 替换国内镜像源 pause 基础镜像sed-i's#registry.k8s.io/pause#registry.aliyuncs.com/google_containers/pause#'/etc/containerd/config.toml3.3 启动服务并设置开机自启
systemctl daemon-reload systemctl start containerd systemctlenablecontainerd四、离线安装 K8s 核心组件
所有集群节点统一离线安装 kubeadm、kubelet、kubectl
yum localinstall-ykubeadm-1.28.2*.rpm kubelet-1.28.2*.rpm kubectl-1.28.2*.rpm systemctlenablekubelet五、离线导入 K8s 系统核心镜像
提前下载 v1.28.2 版本全套系统镜像打包为 tar 格式,所有节点必须全部导入
ctr-nk8s.io imageimportetcd.tar ctr-nk8s.io imageimportpause.tar ctr-nk8s.io imageimportcoredns.tar ctr-nk8s.io imageimportkube-apiserver.tar ctr-nk8s.io imageimportkube-controller-manager.tar ctr-nk8s.io imageimportkube-scheduler.tar ctr-nk8s.io imageimportkube-proxy.tar六、初始化 Master 主节点集群
仅在 Master 管理节点执行集群初始化命令
kubeadm init\--apiserver-advertise-address=内网主节点IP\--kubernetes-version=v1.28.2\--service-cidr=10.96.0.0/12\--pod-network-cidr=10.244.0.0/16\--image-repository=registry.aliyuncs.com/google_containers6.1 配置 kubectl 集群管理权限
mkdir-p$HOME/.kubecp-i/etc/kubernetes/admin.conf$HOME/.kube/configchown$(id-u):$(id-g)$HOME/.kube/config6.2 生成工作节点加入集群命令
kubeadm token create --print-join-command复制输出的 kubeadm join 命令,到所有 Worker 工作节点执行,完成集群节点加入。
七、离线部署 Flannel 集群网络插件
所有集群节点导入 Flannel 离线镜像包
ctr-nk8s.io imageimportflannel.tar离线应用 Flannel 网络配置文件
kubectl apply-fkube-flannel.yml查看集群节点运行状态
kubectl get nodes所有节点状态变为 Ready,代表 Kubernetes 集群搭建完成。
八、离线制作 SpringBoot 后端项目镜像
8.1 离线镜像构建痛点说明
- 官方老旧 openjdk:8-jdk-slim 镜像已下架,无法拉取
- 纯离线服务器无法外网拉取基础镜像,不能直接执行 build 构建
- 最优方案:外网环境提前拉取替代 JDK 镜像 + 构建业务镜像,打包离线包传到内网导入
8.2 外网机器拉取可用 JDK8 基础镜像
dockerpull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eclipse-temurin:8-jredockertag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eclipse-temurin:8-jre eclipse-temurin:8-jredockersave-oeclipse-temurin-8-jre.tar eclipse-temurin:8-jre8.3 编写项目标准 Dockerfile
FROM eclipse-temurin:8-jre WORKDIR /app COPY 后端项目.jar app.jar EXPOSE 10022 ENTRYPOINT ["java","-jar","app.jar"]8.4 外网构建业务镜像并导出离线包
dockerbuild-tsaaf-app:1.0.dockersave-osaaf-app.tar saaf-app:1.08.5 内网集群统一导入镜像
将打包好的 tar 镜像包上传至内网所有集群节点,统一执行导入
ctr-nk8s.io imageimport镜像存放路径/eclipse-temurin-8-jre.tar ctr-nk8s.io imageimport镜像存放路径/saaf-app.tar九、Kubernetes 正式部署 SpringBoot 项目
9.1 完整版部署 YAML 文件
apiVersion:apps/v1kind:Deploymentmetadata:name:saaf-appspec:replicas:1selector:matchLabels:app:saaf-apptemplate:metadata:labels:app:saaf-appspec:hostNetwork:truednsPolicy:ClusterFirstWithHostNetvolumes:-name:host-hostshostPath:path:/etc/hostscontainers:-name:saaf-appimage:saaf-app:1.0ports:-containerPort:10022volumeMounts:-name:host-hostsmountPath:/etc/hosts---apiVersion:v1kind:Servicemetadata:name:saaf-svcspec:type:NodePortselector:app:saaf-appports:-port:10022targetPort:10022nodePort:320229.2 启动部署项目
kubectl apply-fsaaf-app.yaml9.3 集群日常运维常用命令
# 查看所有运行中的Podkubectl get pods# 实时查看后端项目启动日志(自动匹配Pod名称,无需手动填写)kubectl logs-f$(kubectl get pods-lapp=saaf-app-oname)# 滚动重启后端项目kubectl rollout restart deployment saaf-app# 查看集群所有服务kubectl get svc十、核心配置参数作用详解
hostNetwork: true
容器直接复用宿主机物理网卡,脱离集群内部网络隔离,可直接访问内网独立部署的 Nacos、MySQL 等外网服务。dnsPolicy: ClusterFirstWithHostNet
开启宿主机网络模式后,兼容 Kubernetes 集群内部 DNS 解析规则,避免域名解析异常。挂载 /etc/hosts
让容器直接继承宿主机本地域名解析配置,完美解决内网自定义数据库域名无法解析报错问题。
十一、离线环境全流程踩坑总结
1. 系统初始化阶段坑点
未彻底关闭 Swap 分区
- 现象:集群初始化失败、kubelet 进程频繁异常退出
- 解决方案:执行关闭命令并注释开机自动挂载配置,彻底禁用交换分区。
防火墙与安全组件未关闭
- 现象:集群节点无法互相通信、Flannel 网络插件启动异常
- 解决方案:离线环境直接关闭防火墙与 SELinux,简化内网通信规则。
Cgroup 驱动不统一
- 现象:kubelet 启动报错无法加入集群
- 解决方案:所有节点 containerd 统一开启 SystemdCgroup=true,与 kubelet 保持一致。
2. K8s 集群搭建阶段坑点
离线环境缺失系统基础镜像
- 现象:集群初始化卡死、组件镜像拉取失败
- 解决方案:提前下载对应版本全套系统镜像,所有节点统一导入。
Flannel 网络插件离线镜像缺失
- 现象:集群节点状态一直处于 NotReady
- 解决方案:所有工作节点必须导入 Flannel 离线镜像,再应用网络配置。
3. Docker 镜像构建阶段坑点
在内网离线服务器执行镜像构建
- 现象:构建过程拉取基础镜像超时、构建失败
- 解决方案:构建操作仅在有外网机器执行,内网只做镜像导入,不做构建。
老旧 JDK 镜像失效
- 现象:openjdk:8-jdk-slim 提示镜像不存在
- 解决方案:替换社区长期维护镜像 eclipse-temurin:8-jre。
4. SpringBoot 项目运行阶段坑点
容器无法连接内网 Nacos 注册中心
- 现象:项目启动注册超时、无法注册服务
- 解决方案:开启宿主机网络模式,打通容器与内网独立服务网络。
数据库自定义域名解析失败报错
- 现象:java.net.UnknownHostException
- 解决方案:容器挂载宿主机 hosts 解析文件,复用内网域名规则。
YAML 配置文件缩进错误
- 现象:kubectl 应用配置提示 JSON 格式转换失败
- 解决方案:严格使用2个空格缩进,禁止使用 Tab 制表符排版。
仅主节点导入业务镜像
- 现象:工作节点调度 Pod 出现 ErrImagePull 镜像拉取失败
- 解决方案:集群所有节点必须同步导入全部离线镜像。
手动指定 Pod 名称查看日志报错
- 现象:提示 Pod 资源不存在
- 解决方案:使用标签自动匹配命令,无需固定填写 Pod 名称。
十二、项目部署完成验证标准
- Kubernetes 集群所有节点状态正常为 Ready
- SpringBoot 项目 Pod 运行状态 1/1 Running,无异常重启
- 项目启动日志无数据库连接、注册中心连接报错
- 成功登录内网 Nacos 控制台,可查看到当前后端服务正常在线
- 通过集群节点对外暴露端口,可正常访问后端所有业务接口