文档简介

本文基于 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
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

2.2 永久关闭 Swap 交换分区

Kubernetes 强制要求关闭 Swap,否则集群初始化异常

swapoff -a
sed -i '/swap/d' /etc/fstab

2.3 配置主机名与内网域名解析

# 主节点设置主机名
hostnamectl set-hostname k8s-master
# 工作节点设置主机名
hostnamectl set-hostname k8s-node1

# 统一写入本地域名解析
cat >> /etc/hosts <<EOF
内网主节点IP  k8s-master
内网工作节点IP  k8s-node1
数据库内网IP   数据库自定义域名
EOF

2.4 加载内核网络转发模块

开启容器网络转发内核参数,保证集群网络互通

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

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

三、离线安装 Containerd 容器运行时

3.1 离线本地安装依赖包

提前下载好 containerd 离线 RPM 包,所有节点统一执行

yum localinstall -y containerd-*.rpm

3.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.toml

3.3 启动服务并设置开机自启

systemctl daemon-reload
systemctl start containerd
systemctl enable containerd

四、离线安装 K8s 核心组件

所有集群节点统一离线安装 kubeadm、kubelet、kubectl

yum localinstall -y kubeadm-1.28.2*.rpm kubelet-1.28.2*.rpm kubectl-1.28.2*.rpm
systemctl enable kubelet

五、离线导入 K8s 系统核心镜像

提前下载 v1.28.2 版本全套系统镜像打包为 tar 格式,所有节点必须全部导入

ctr -n k8s.io image import etcd.tar
ctr -n k8s.io image import pause.tar
ctr -n k8s.io image import coredns.tar
ctr -n k8s.io image import kube-apiserver.tar
ctr -n k8s.io image import kube-controller-manager.tar
ctr -n k8s.io image import kube-scheduler.tar
ctr -n k8s.io image import kube-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_containers

6.1 配置 kubectl 集群管理权限

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

6.2 生成工作节点加入集群命令

kubeadm token create --print-join-command

复制输出的 kubeadm join 命令,到所有 Worker 工作节点执行,完成集群节点加入。

七、离线部署 Flannel 集群网络插件

所有集群节点导入 Flannel 离线镜像包

ctr -n k8s.io image import flannel.tar

离线应用 Flannel 网络配置文件

kubectl apply -f kube-flannel.yml

查看集群节点运行状态

kubectl get nodes

所有节点状态变为 Ready,代表 Kubernetes 集群搭建完成。

八、离线制作 SpringBoot 后端项目镜像

8.1 离线镜像构建痛点说明

  • 官方老旧 openjdk:8-jdk-slim 镜像已下架,无法拉取
  • 纯离线服务器无法外网拉取基础镜像,不能直接执行 build 构建
  • 最优方案:外网环境提前拉取替代 JDK 镜像 + 构建业务镜像,打包离线包传到内网导入

8.2 外网机器拉取可用 JDK8 基础镜像

docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eclipse-temurin:8-jre
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eclipse-temurin:8-jre eclipse-temurin:8-jre
docker save -o eclipse-temurin-8-jre.tar eclipse-temurin:8-jre

8.3 编写项目标准 Dockerfile

FROM eclipse-temurin:8-jre
WORKDIR /app
COPY 后端项目.jar app.jar
EXPOSE 10022
ENTRYPOINT ["java","-jar","app.jar"]

8.4 外网构建业务镜像并导出离线包

docker build -t saaf-app:1.0 .
docker save -o saaf-app.tar saaf-app:1.0

8.5 内网集群统一导入镜像

将打包好的 tar 镜像包上传至内网所有集群节点,统一执行导入

ctr -n k8s.io image import 镜像存放路径/eclipse-temurin-8-jre.tar
ctr -n k8s.io image import 镜像存放路径/saaf-app.tar

九、Kubernetes 正式部署 SpringBoot 项目

9.1 完整版部署 YAML 文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: saaf-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: saaf-app
  template:
    metadata:
      labels:
        app: saaf-app
    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      volumes:
      - name: host-hosts
        hostPath:
          path: /etc/hosts
      containers:
      - name: saaf-app
        image: saaf-app:1.0
        ports:
        - containerPort: 10022
        volumeMounts:
        - name: host-hosts
          mountPath: /etc/hosts
---
apiVersion: v1
kind: Service
metadata:
  name: saaf-svc
spec:
  type: NodePort
  selector:
    app: saaf-app
  ports:
  - port: 10022
    targetPort: 10022
    nodePort: 32022

9.2 启动部署项目

kubectl apply -f saaf-app.yaml

9.3 集群日常运维常用命令

# 查看所有运行中的Pod
kubectl get pods

# 实时查看后端项目启动日志(自动匹配Pod名称,无需手动填写)
kubectl logs -f $(kubectl get pods -l app=saaf-app -o name)

# 滚动重启后端项目
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 名称。

十二、项目部署完成验证标准

  1. Kubernetes 集群所有节点状态正常为 Ready
  2. SpringBoot 项目 Pod 运行状态 1/1 Running,无异常重启
  3. 项目启动日志无数据库连接、注册中心连接报错
  4. 成功登录内网 Nacos 控制台,可查看到当前后端服务正常在线
  5. 通过集群节点对外暴露端口,可正常访问后端所有业务接口

更多推荐