主题
Harbor 私有仓库 + RKE2 v1.35.6 高可用集群离线部署与 Rancher 运维手册
适用场景:内网/离线环境,使用 Harbor 作为镜像仓库与 OCI 制品库, 通过离线包
rke2.linux-amd64.tar.gz部署 RKE2 v1.35.6 高可用集群(3 Server + N Agent), 并离线安装开源 Rancher 作为管理面。环境基线:Rocky Linux 9.8 | RKE2 v1.35.6 | CNI:Calico | kube-proxy:IPVS | Rancher v2.14.3 | cert-manager v1.20.3
部署流程总览:
- 规划与备料:节点/网段规划,下载离线制品(§1.4)
- 节点初始化:防火墙放行(§2.1)+ 内核优化(§2.2)
- 安装 RKE2 运行时:解压二进制(§3.1)→ install.sh(§3.2)→ 镜像上传 Harbor(§3.3)→ registries.yaml(§3.4)
- 组建 HA 集群:首节点 init(§4.1)→ 加入 server(§4.3)→ 加入 agent(§4.4)→ 验证(§4.5)
- 安装 Rancher:cert-manager(§5.2)→ rancher(§5.3)→ 首登(§5.4)
- 日常运维:命令速查、etcd 快照恢复、扩容、故障速查(§6)
1. 架构与规划
1.1 整体架构
┌──────────── Harbor 私有仓库 ────────────┐
│ 192.168.122.156:30000(HTTP) │
│ · 系统镜像(离线包上传,见 §3.3) │
│ · Rancher / cert-manager Chart(OCI) │
└───────▲───────────────────▲─────────────┘
│ pull │ helm pull oci://
┌───────────────────┼───────────────────┼───────────────────┐
│ │ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ server-1 │◄─────►│ server-2 │◄─────►│ server-3 │ │ agent-N │
│ (etcd+cp) │ etcd │ (etcd+cp) │ etcd │ (etcd+cp) │ │ (worker) │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
└────────── 注册入口:server: https://<首节点或VIP>:9345 ──────────┘- Server(控制面):3 节点组成 etcd 仲裁,关闭默认污点后可兼跑业务(小规格环境)
- Agent(工作面):按需水平扩展
- Harbor:所有镜像与 Helm Chart 的唯一来源,集群通过
system-default-registry+registries.yaml接入
1.2 节点规划(示例,按实际替换)
| 角色 | 主机名 | IP | 说明 |
|---|---|---|---|
| server-1(初始化节点) | rocky9-vm-01 | 192.168.122.78 | 首个 etcd/control-plane |
| server-2 | rocky9-vm-02 | 192.168.122.69 | 控制面 |
| server-3 | rocky9-vm-03 | 192.168.122.101 | 控制面 |
| agent-1~N | rocky9-vm-04+ | 192.168.122.x | 工作节点 |
| Harbor | harbor | 192.168.122.156:30000 | 镜像仓库(HTTP 内网) |
| 制品库(可选) | repo | 192.168.122.1:31000 | 离线包/脚本分发 |
1.3 网络规划
| 网段 | 用途 |
|---|---|
| 10.12.0.0/16 | cluster-cidr(Pod) |
| 10.13.0.0/16 | service-cidr(Service) |
| 30000-60000 | NodePort 范围(可按需调整) |
⚠️ 两个网段不得与物理网络重叠。
1.4 离线制品清单(提前准备)
| 文件 | 用途 |
|---|---|
rke2.linux-amd64.tar.gz | RKE2 二进制(containerd、runc、kubectl 等),解压到各节点 /usr/local |
rke2-images.linux-amd64.tar.zst | 核心组件镜像包,上传 Harbor(见 §3.3),集群启动时从 Harbor 拉取 |
rke2-images-calico.linux-amd64.tar.zst | Calico CNI 镜像包,上传 Harbor |
install.sh | RKE2 官方安装脚本(生成 systemd unit) |
rke2-canal-kernel-tune.sh | 内核优化脚本(见 §2.2,可提前放制品库) |
下载(有网环境或制品库):
bash
# 从 GitHub Release(有网环境)
# https://github.com/rancher/rke2/releases/tag/v1.35.6%2Brke2r1
# 或从内网制品库(本文示例)
wget http://192.168.122.1:31000/repo/rke2/1.35.6/rke2.linux-amd64.tar.gz
wget http://192.168.122.1:31000/repo/rke2/1.35.6/rke2-images.linux-amd64.tar.zst
wget http://192.168.122.1:31000/repo/rke2/1.35.6/rke2-images-calico.linux-amd64.tar.zst
wget http://192.168.122.1:31000/repo/rke2/install-1.35.6.sh -O install.sh && chmod +x install.sh2. 节点初始化(所有节点执行)
2.1 防火墙端口(生产建议放行,测试环境可关闭 firewalld)
bash
# 控制面节点间必需端口
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 9345 -j ACCEPT # RKE2 supervisor API
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 6443 -j ACCEPT # Kubernetes API
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 2379 -j ACCEPT # etcd client
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 2380 -j ACCEPT # etcd peer
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 10250 -j ACCEPT # kubelet
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 10257 -j ACCEPT # controller-manager
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 10259 -j ACCEPT # scheduler
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 9091 -j ACCEPT # calico-node 健康检查
iptables -I INPUT -s 192.168.122.0/24 -p tcp --dport 5473 -j ACCEPT # Calico Typha
iptables -I INPUT -s 192.168.122.0/24 -p udp --dport 4789 -j ACCEPT # VXLAN(Calico)
iptables -I INPUT -s 192.168.122.0/24 -p udp --dport 8472 -j ACCEPT # VXLAN(Canal/Flannel)
iptables-save > /etc/sysconfig/iptables2.2 内核优化脚本(rke2-canal-kernel-tune.sh)
适配 8C16G 节点,Calico/Canal 通用。可放制品库后 curl -s http://<repo>/rke2-canal-kernel-tune.sh | sh 执行:
bash
#!/bin/bash
set -e
echo "===== Rocky 9 RKE2 + Calico/Canal 内核优化 ====="
dnf install -y iptables
# 1. 关闭 SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 2. 关闭 Swap
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
# 3. 预加载内核模块
cat > /etc/modules-load.d/k8s-canal.conf <<EOF
overlay
ip_tables
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
nf_tables
EOF
modprobe overlay ip_tables ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack nf_tables
# 4. sysctl 调优
cat > /etc/sysctl.d/99-rke2-canal.conf <<EOF
# IPv4转发 & 网桥(CNI 强制依赖)
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# conntrack(16G 内存规格)
net.netfilter.nf_conntrack_max = 2621440
net.netfilter.nf_conntrack_tcp_timeout_established = 300
# TCP 高并发
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 1024 65535
# 网络缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.somaxconn = 32768
net.core.netdev_max_backlog = 16384
# IPVS 优化
net.ipv4.vs.expire_nodest_conn = 1
net.ipv4.vs.expire_quiescent = 1
# 内存参数
vm.swappiness = 0
vm.max_map_count = 262144
EOF
# 5. 生效
sysctl --system
# 6. 文件句柄上限
cat >> /etc/security/limits.conf <<EOF
* soft nofile 1048576
* hard nofile 1048576
EOF
sed -i '/DefaultLimitNOFILE/d' /etc/systemd/system.conf
echo "DefaultLimitNOFILE=1048576" >> /etc/systemd/system.conf
systemctl daemon-reload
# 7. 校验
echo "nf_conntrack_max: $(sysctl -n net.netfilter.nf_conntrack_max)"
echo "ip_forward: $(sysctl -n net.ipv4.ip_forward)"
echo "bridge-nf-call: $(sysctl -n net.bridge.bridge-nf-call-iptables)"
lsmod | grep -E "overlay|ip_vs|nf_conntrack"
echo "===== 优化完成(limits 需重登或重启后完全生效) ====="注:若安装过程中 dnf 残留 RKE2 仓库的 gpg-agent 进程导致卡慢,可清理:
pkill -f "gpg-agent --homedir /var/cache/dnf/rancher-rke2"
3. 离线安装 RKE2 运行时
安装顺序:先在各节点装运行时(§3.1~3.2),再一次性把镜像上传 Harbor(§3.3), 最后配置 registries.yaml(§3.4)并启动集群——启动时所有系统镜像均从 Harbor 拉取。
3.1 解压二进制(所有节点执行)
bash
mkdir -p /opt/rke2-1.35.6 && cd /opt/rke2-1.35.6
# 放入 §1.4 的离线制品后:
tar -xzf rke2.linux-amd64.tar.gz -C /usr/local镜像 tar 包不需要拷贝到宿主机(集群统一从 Harbor 拉取)。 若个别环境无 Harbor,备选方案才是把
rke2-images.*.tar.zst放到/var/lib/rancher/rke2/agent/images/(启动时自动导入 containerd)。
3.2 运行官方安装脚本(所有节点执行,生成 systemd unit)
bash
INSTALL_RKE2_ARTIFACT_PATH=/opt/rke2-1.35.6 /opt/rke2-1.35.6/install.sh
# 产物:/etc/systemd/system/rke2-server.service、rke2-agent.service3.3 上传离线镜像到 Harbor(一次性,在装有 Docker 的机器执行)
bash
# 0) HTTP Harbor 需在 /etc/docker/daemon.json 配置后重启 docker:
# { "insecure-registries": ["192.168.122.156:30000"] }
docker login -u admin -p <密码> 192.168.122.156:30000
# 1) 镜像包导入 docker(zstd 解压管道直接 load,无需落盘解压)
zstdcat rke2-images.linux-amd64.tar.zst | docker load
zstdcat rke2-images-calico.linux-amd64.tar.zst | docker load
# 2) 批量重打标签并推送(rancher/* 系统镜像 + calico/* 组件镜像)
docker images --format '{{.Repository}}:{{.Tag}}' \
| grep -E '^(rancher|calico)/' > rke2-1.35.6.images.txt
while read line; do
new_img="192.168.122.156:30000/$line"
echo "$line -> $new_img"
docker tag "$line" "$new_img" && docker push "$new_img"
done < rke2-1.35.6.images.txt推送完成后在 Harbor Web 控制台确认
rancher/、calico/项目镜像齐全。 RKE2 系统镜像清单也可从 Release 页面获取rke2-images-all.linux-amd64.txt核对数量。
3.4 配置 Harbor 镜像仓库(所有节点)
bash
mkdir -p /etc/rancher/rke2
cat > /etc/rancher/rke2/registries.yaml <<EOF
mirrors:
"192.168.122.156:30000":
endpoint:
- "http://192.168.122.156:30000"
"docker.io":
endpoint:
- "http://192.168.122.156:30000"
configs:
"192.168.122.156:30000":
tls:
insecure_skip_verify: true
# Harbor 若开启认证,追加:
# auth:
# username: xxx
# password: xxx
EOF说明:
docker.iomirror 让所有 Docker Hub 镜像请求也走 Harbor;Harbor 侧建 proxy cache 项目可进一步缓存公网镜像。 ⚠️ 若重装集群时rm -rf /var/lib/rancher报权限错误,是 RKE2 给 containerdhosts.toml加了 immutable 属性,先解锁:chattr -i /var/lib/rancher/rke2/agent/etc/containerd/certs.d/*/hosts.toml
4. 高可用集群搭建
4.1 第一个 Server 节点(cluster-init,192.168.122.78)
bash
cat > /etc/rancher/rke2/config.yaml <<EOF
# ---- 集群身份 ----
token: <集群共享Token,自定义强随机串> # 所有 server/agent 必须一致
# ---- 网络 ----
cni: calico
node-ip: 192.168.122.78
cluster-cidr: 10.12.0.0/16
service-cidr: 10.13.0.0/16
service-node-port-range: "30000-60000"
kube-proxy-arg:
- "proxy-mode=ipvs"
# ---- API 证书 SAN(所有控制面 IP / VIP / 域名都列入) ----
tls-san:
- 192.168.122.78
- 192.168.122.69
- 192.168.122.101
# ---- Harbor 默认镜像仓库 ----
system-default-registry: 192.168.122.156:30000
# ---- 小环境:关闭控制面污点,允许调度业务 Pod ----
disable-scheduler-node-taints: true
# ---- etcd 自动快照 ----
etcd-snapshot-retention: 5
etcd-snapshot-schedule-cron: "0 */6 * * *"
# ---- (可选)组件调优 ----
# kube-apiserver-arg:
# - max-requests-inflight=3000
# kubelet-arg:
# - max-pods=100
# - eviction-hard=memory.available<1Gi,nodefs.available<10%
EOF
systemctl enable --now rke2-server4.2 配置 kubectl 并验证首节点
bash
mkdir -p /root/.kube
ln -sf /etc/rancher/rke2/kubeconfig.yaml /root/.kube/config
export KUBECONFIG=/root/.kube/config
# 另存一份 kubeconfig 到本地,后续管理/Rancher 导入都要用
kubectl get nodes -o wide # 首节点 Ready(约 1~2 分钟)即可继续
kubectl get pods -A # calico、coredns 等系统 Pod 全部 Running(镜像从 Harbor 拉取)4.3 加入其余 Server 节点(192.168.122.69 / .101)
在新节点上完成 §2、§3 后:
bash
cat > /etc/rancher/rke2/config.yaml <<EOF
# ---- 注册到已有集群 ----
server: https://192.168.122.78:9345 # 首节点(或 VIP)的 supervisor 地址
token: <与首节点相同的集群Token>
# ---- 其余配置与首节点保持一致 ----
cni: calico
node-ip: <本机IP>
cluster-cidr: 10.12.0.0/16
service-cidr: 10.13.0.0/16
service-node-port-range: "30000-60000"
kube-proxy-arg:
- "proxy-mode=ipvs"
tls-san:
- 192.168.122.78
- 192.168.122.69
- 192.168.122.101
system-default-registry: 192.168.122.156:30000
disable-scheduler-node-taints: true
etcd-snapshot-retention: 5
etcd-snapshot-schedule-cron: "0 */6 * * *"
EOF
systemctl enable --now rke2-server💡 VIP(可选):有 keepalived/kube-vip 时把
server:与tls-san换成 VIP(如 192.168.122.253), 控制面入口高可用;无 VIP 时用首节点 IP 也可工作(首节点故障不影响已加入节点运行,只影响新节点注册)。
4.4 加入 Agent 工作节点
Agent 节点 config.yaml 仅保留:
yaml
server: https://192.168.122.78:9345
token: <与首节点相同的集群Token>
node-ip: <本机IP>bash
systemctl enable --now rke2-agent4.5 节点标签与集群验证
bash
# 给 worker 打标签(按实际节点名)
kubectl label node rocky9-vm-04 node-role.kubernetes.io/worker=true
kubectl label node rocky9-vm-05 node-role.kubernetes.io/worker=true
# 整体验证(3 server + N agent 全部 Ready,系统 Pod 无 ImagePull 报错)
kubectl get nodes -o wide
kubectl get pods -A -o wide
kubectl get --raw='/readyz?verbose' | grep -v 'check passed' # 无输出即健康5. 离线安装 Rancher(开源版)
5.1 前置:镜像与 Chart 已入 Harbor
在有网机器上拉取后推送(或直接 helm push Chart 到 Harbor OCI):
bash
# 镜像批量重打标签推送(以 rancher 镜像为例)
docker images | grep ^rancher | awk '{print $1":"$2}' > images.txt
while read line; do
new_img="192.168.122.156:30000/$line"
docker tag "$line" "$new_img" && docker push "$new_img"
done < images.txt
# cert-manager(quay.io/jetstack)同理,替换前缀为 Harbor 地址
docker images | grep jetstack | awk '{print $1":"$2}' > jetstack.images.txt
while read line; do
new_img=$(echo "$line" | sed 's|^quay.io|192.168.122.156:30000|')
docker tag "$line" "$new_img" && docker push "$new_img"
done < jetstack.images.txt5.2 安装 cert-manager
bash
helm pull oci://192.168.122.156:30000/cert-manager/cert-manager --version v1.20.3
helm install cert-manager ./cert-manager-v1.20.3.tgz \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true \
--set global.imageRegistry=192.168.122.156:30000
kubectl -n cert-manager get pods # 3 个组件 Running5.3 安装 Rancher
bash
helm pull oci://192.168.122.156:30000/cnrancher/rancher --version 2.14.3
helm upgrade --install rancher ./rancher-2.14.3.tgz \
--namespace cattle-system --create-namespace \
--set hostname=rancher.ai-ear.cn \
--set bootstrapPassword="xxx" \
--set replicas=1 \
--set ingress.ingressClassName=nginx \
--set global.cattle.psp.enabled=false \
--set systemDefaultRegistry=192.168.122.156:30000 \
--set rancherImage=192.168.122.156:30000/rancher/rancher \
--set rancherImageTag=v2.14.3
kubectl -n cattle-system rollout status deploy/rancher5.4 首次登录
bash
# 获取 bootstrap 密码(如未在 helm 中自定义)
kubectl get secret --namespace cattle-system bootstrap-secret \
-o go-template='{{.data.bootstrapPassword|base64decode}}{{"\n"}}'
# 拼接首次设置链接
echo "https://rancher.ai-ear.cn/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}')"
rancher.ai-ear.cn需解析到任一节点 Ingress(nginx-ingress)入口 IP。
6. 日常运维
6.1 常用命令速查
bash
# 服务管理
systemctl status rke2-server # 或 rke2-agent
journalctl -u rke2-server -f # 跟踪日志
# 节点与负载
kubectl get nodes -o wide
kubectl top nodes && kubectl top pods -A
# crictl(RKE2 的 containerd 与 k3s 共用 socket 路径)
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///var/run/k3s/containerd/containerd.sock
image-endpoint: unix:///var/run/k3s/containerd/containerd.sock
timeout: 10
EOF
crictl ps # 运行中容器
crictl images # 本地镜像
# ctr(排障/导出镜像)
export CONTAINERD_ADDRESS=/var/run/k3s/containerd/containerd.sock
ctr -n k8s.io images list6.2 etcd 快照与恢复
bash
# 配置已含自动快照(每 6 小时,保留 5 份):/var/lib/rancher/rke2/server/db/snapshots/
ls -lh /var/lib/rancher/rke2/server/db/snapshots/
# 手动快照
rke2 etcd-snapshot save --name manual-$(date +%F-%H%M)
# 恢复(集群故障时,先在所有 server 停 rke2-server,再选一个节点执行)
# rke2 server --cluster-reset --cluster-reset-restore-path=<快照文件>
# 完成后去掉 --cluster-reset 参数,依次启动其余 server6.3 离线镜像分发(节点间拷贝)
bash
# 一次性导出多个镜像为 tar(如 cert-manager 三件套)
ctr -n k8s.io images export cert-manager-v1.20.3-all.tar \
quay.io/jetstack/cert-manager-controller:v1.20.3 \
quay.io/jetstack/cert-manager-startupapicheck:v1.20.3 \
quay.io/jetstack/cert-manager-webhook:v1.20.3
# 目标节点导入
ctr -n k8s.io images import cert-manager-v1.20.3-all.tar6.4 添加新节点(扩容)
- 新节点执行 §2 初始化、§3 离线安装
- 写入 config.yaml(server/agent 同 §4.3 / §4.4,token 与集群一致)
systemctl enable --now rke2-server(或rke2-agent)kubectl get nodes确认 Ready,按需打标签
6.5 常见故障速查
| 现象 | 排查与处理 |
|---|---|
| 新节点 join 失败 | 核对 server: 地址可达(9345 端口/防火墙)、token 与首节点一致、tls-san 是否包含访问地址 |
rm -rf /var/lib/rancher 报 Operation not permitted | hosts.toml 被加 immutable:chattr -i /var/lib/rancher/rke2/agent/etc/containerd/certs.d/*/hosts.toml 后重试 |
| 镜像拉取失败 | 检查 registries.yaml 缩进、Harbor 可达性;containerd 对 certs.d 热加载,改 registries.yaml 建议重启 rke2 服务 |
| dnf 安装卡顿/挂起 | 清理残留 GPG 进程:pkill -f "gpg-agent --homedir /var/cache/dnf/rancher-rke2" |
| etcd 节点 NotReady | 检查 2379/2380 互通;journalctl -u rke2-server -e 看 etcd 日志;必要时按 §6.2 快照恢复 |
| Pod 跨节点不通 | Calico:查 4789(VXLAN)/5473(Typha) 端口、sysctl net.bridge.bridge-nf-call-iptables=1 |
7. 安全加固清单(上线前)
- [ ] 集群 token 使用强随机串,不入文档/代码库
- [ ] Harbor 开启认证(registries.yaml 配
auth),内网 HTTP 仅在内网使用 - [ ] Rancher
bootstrapPassword首登后立即修改为强密码 - [ ] 生产环境开启 firewalld 并按 §2.1 精确放行,不要整体关闭
- [ ] etcd 快照定期异地备份(快照目录拷贝到对象存储/备份机)
- [ ] 控制面节点恢复默认污点(
disable-scheduler-node-taints仅建议小环境使用)