内网开发环境救星:手把手教你用K3s离线搭建轻量K8s集群(避坑指南)
内网开发环境救星:手把手教你用K3s离线搭建轻量K8s集群(避坑指南)
在金融、军工、医疗等对数据隔离要求严格的行业,或是实验室特殊网络环境中,开发团队常面临一个共同困境:如何在完全离线的物理环境中快速部署Kubernetes集群?传统K8s的离线部署如同在迷宫中徒手拼图——需要手动下载上百个组件依赖,处理复杂的镜像导出导入,稍有不慎就会陷入依赖地狱。而K3s的出现,就像为这个迷宫提供了精准的导航图。
1. 为什么K3s是离线环境的最佳选择
当我们在某银行数据中心首次尝试离线部署K8s时,团队花了三天时间处理etcd集群的证书问题。而改用K3s后,同样的部署过程缩短到2小时。这种效率跃升源于K3s的三大设计哲学:
- 单体二进制架构:将kube-apiserver、kube-controller-manager等核心组件编译为单个不足100MB的二进制文件,相比传统K8s动辄GB级的组件集合,更适合内网传输
- 内置容器运行时:默认集成containerd,无需额外部署Docker环境
- Airgap模式原生支持:提供预打包的系统镜像(airgap images tar),包含全部依赖组件
性能对比实验显示,在同等配置的离线服务器上:
| 指标 | 传统K8s部署耗时 | K3s部署耗时 |
|---|---|---|
| 基础环境准备 | 4.5小时 | 0.5小时 |
| 镜像导入 | 3小时 | 20分钟 |
| 集群初始化 | 2小时 | 15分钟 |
| 首次应用部署 | 1.5小时 | 8分钟 |
实际案例:某自动驾驶研发团队在内网环境使用K3s后,CI/CD流水线的部署频率从每周1次提升到每日3次
2. 离线部署前的关键准备
2.1 硬件资源规划建议
即使是轻量级集群,也需要合理规划资源。我们建议采用以下配置作为基准线:
- 控制节点:4核CPU/8GB内存/100GB存储(如需运行监控栈需额外增加)
- 工作节点:按应用需求动态扩展,建议2核CPU/4GB内存起
- 网络要求:
- 节点间需开放6443(API Server)、8472(Flannel VXLAN)等端口
- 内网DNS能解析节点主机名(或配置/etc/hosts)
2.2 离线资源包获取
通过外网机器下载以下必备资源(以v1.26.2+k3s1版本为例):
# 获取K3s二进制文件 wget https://github.com/k3s-io/k3s/releases/download/v1.26.2%2Bk3s1/k3s # 获取airgap镜像包 wget https://github.com/k3s-io/k3s/releases/download/v1.26.2%2Bk3s1/k3s-airgap-images-amd64.tar # 获取安装脚本(重要!不同版本可能有差异) wget https://get.k3s.io -O install.sh将这些文件通过安全介质(如加密U盘)传输到内网环境。一个常见失误是忽略安装脚本的版本匹配——我们曾遇到因使用旧版脚本导致集群证书失效的案例。
3. 两种离线部署方案详解
3.1 私有镜像仓库方案(推荐)
适合需要持续部署新应用的场景,需要提前在内网部署Harbor等私有仓库:
- 将airgap镜像导入私有仓库:
# 加载镜像到本地Docker docker load -i k3s-airgap-images-amd64.tar # 批量推送到私有仓库 for image in $(docker images | grep rancher | awk '{print $1":"$2}'); do docker tag $image myregistry.local/$image docker push myregistry.local/$image done- 创建registry配置文件:
# /etc/rancher/k3s/registries.yaml mirrors: "docker.io": endpoint: - "https://myregistry.local" configs: "myregistry.local": auth: username: admin password: Harbor@12345- 启动K3s时自动使用私有仓库:
INSTALL_K3S_SKIP_DOWNLOAD=true \ K3S_TOKEN=SECRET \ ./install.sh3.2 直接加载镜像方案
适合快速验证环境或临时测试,直接将镜像包放到指定位置:
# 创建镜像目录 sudo mkdir -p /var/lib/rancher/k3s/agent/images/ sudo cp k3s-airgap-images-amd64.tar /var/lib/rancher/k3s/agent/images/ # 安装K3s二进制 sudo chmod +x k3s sudo mv k3s /usr/local/bin/ # 启动单节点集群 INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh避坑提示:/var/lib/rancher目录权限必须正确,否则会导致镜像加载失败。遇到问题时执行
sudo chmod 755 /var/lib/rancher -R
4. 高可用集群部署技巧
对于生产环境,建议采用多控制节点部署。某医疗系统项目中的最佳实践:
- 准备外部数据库(MySQL/PostgreSQL等):
CREATE DATABASE k3s_cluster; GRANT ALL ON k3s_cluster.* TO 'k3s'@'%' IDENTIFIED BY 'StrongPassword';- 首个控制节点启动命令:
INSTALL_K3S_SKIP_DOWNLOAD=true \ K3S_TOKEN=SharedSecret \ INSTALL_K3S_EXEC="server --datastore-endpoint=mysql://k3s:StrongPassword@tcp(db-server:3306)/k3s_cluster" \ ./install.sh- 追加控制节点命令:
INSTALL_K3S_SKIP_DOWNLOAD=true \ K3S_TOKEN=SharedSecret \ K3S_URL=https://first-node:6443 \ INSTALL_K3S_EXEC="server --datastore-endpoint=mysql://k3s:StrongPassword@tcp(db-server:3306)/k3s_cluster" \ ./install.sh- 工作节点加入命令:
INSTALL_K3S_SKIP_DOWNLOAD=true \ K3S_URL=https://first-node:6443 \ K3S_TOKEN=SharedSecret \ ./install.sh agent关键检查点:
- 确保所有节点时间同步(NTP服务)
- 检查
kubectl get nodes显示所有节点Ready状态 - 验证数据库连接数(show processlist)
5. 常见问题排错指南
问题1:Pod始终处于ImagePullBackOff状态
- 检查项:
# 确认镜像路径是否正确 kubectl describe pod <pod-name> | grep "Failed to pull image" # 检查containerd日志 journalctl -u k3s -f | grep "pull access denied" - 解决方案:更新registries.yaml配置后重启k3s服务
问题2:节点无法加入集群
- 典型错误日志:
Failed to connect to proxy" error="dial tcp: lookup master-node on 8.8.8.8:53: no such host - 修复步骤:
- 在内网DNS中添加节点记录
- 或修改agent节点的/etc/hosts文件
- 检查防火墙是否放行6443端口
问题3:集群证书过期
- 预防措施:
# 查看证书有效期 sudo k3s kubectl get --raw="/readyz?verbose" | grep -A10 "certificates" - 更新方法:
# 备份旧证书 sudo cp -r /var/lib/rancher/k3s/server/tls /backup # 触发证书轮换 sudo systemctl restart k3s
在完成某能源企业的离线部署后,我们整理了一份检查清单:
- [ ] 所有节点SSH互信配置
- [ ] /etc/hosts包含所有节点解析
- [ ] 时间同步服务状态正常
- [ ] 防火墙规则已放行必要端口
- [ ] 磁盘空间大于20%阈值
6. 集群运维进阶技巧
离线环境下的升级策略:
- 下载新版本airgap包和二进制文件
- 滚动更新控制节点:
# 逐个节点执行 sudo systemctl stop k3s sudo cp new-k3s /usr/local/bin/k3s sudo systemctl start k3s - 验证集群状态:
kubectl get nodes -o wide kubectl get pods -A
资源监控方案:
# 部署轻量级监控栈 kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml helm install prometheus-stack --set grafana.enabled=false prometheus-community/kube-prometheus-stack存储配置建议:
# local-path-provisioner配置示例 apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: local-path provisioner: rancher.io/local-path volumeBindingMode: WaitForFirstConsumer reclaimPolicy: Delete在最近一次制造业客户部署中,我们通过以下优化将集群稳定性提升至99.9%:
- 配置Liveness/Readiness探针
- 设置合理的资源请求/限制
- 启用自动修复策略:
apiVersion: apps/v1 kind: Deployment spec: minReadySeconds: 10 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1
