Skip to content

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. 规划与备料:节点/网段规划,下载离线制品(§1.4)
  2. 节点初始化:防火墙放行(§2.1)+ 内核优化(§2.2)
  3. 安装 RKE2 运行时:解压二进制(§3.1)→ install.sh(§3.2)→ 镜像上传 Harbor(§3.3)→ registries.yaml(§3.4)
  4. 组建 HA 集群:首节点 init(§4.1)→ 加入 server(§4.3)→ 加入 agent(§4.4)→ 验证(§4.5)
  5. 安装 Rancher:cert-manager(§5.2)→ rancher(§5.3)→ 首登(§5.4)
  6. 日常运维:命令速查、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-01192.168.122.78首个 etcd/control-plane
server-2rocky9-vm-02192.168.122.69控制面
server-3rocky9-vm-03192.168.122.101控制面
agent-1~Nrocky9-vm-04+192.168.122.x工作节点
Harborharbor192.168.122.156:30000镜像仓库(HTTP 内网)
制品库(可选)repo192.168.122.1:31000离线包/脚本分发

1.3 网络规划

网段用途
10.12.0.0/16cluster-cidr(Pod)
10.13.0.0/16service-cidr(Service)
30000-60000NodePort 范围(可按需调整)

⚠️ 两个网段不得与物理网络重叠。

1.4 离线制品清单(提前准备)

文件用途
rke2.linux-amd64.tar.gzRKE2 二进制(containerd、runc、kubectl 等),解压到各节点 /usr/local
rke2-images.linux-amd64.tar.zst核心组件镜像包,上传 Harbor(见 §3.3),集群启动时从 Harbor 拉取
rke2-images-calico.linux-amd64.tar.zstCalico CNI 镜像包,上传 Harbor
install.shRKE2 官方安装脚本(生成 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.sh

2. 节点初始化(所有节点执行)

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/iptables

2.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.service

3.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.io mirror 让所有 Docker Hub 镜像请求也走 Harbor;Harbor 侧建 proxy cache 项目可进一步缓存公网镜像。 ⚠️ 若重装集群时 rm -rf /var/lib/rancher 报权限错误,是 RKE2 给 containerd hosts.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-server

4.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-agent

4.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.txt

5.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 个组件 Running

5.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/rancher

5.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 list

6.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 参数,依次启动其余 server

6.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.tar

6.4 添加新节点(扩容)

  1. 新节点执行 §2 初始化、§3 离线安装
  2. 写入 config.yaml(server/agent 同 §4.3 / §4.4,token 与集群一致
  3. systemctl enable --now rke2-server(或 rke2-agent
  4. kubectl get nodes 确认 Ready,按需打标签

6.5 常见故障速查

现象排查与处理
新节点 join 失败核对 server: 地址可达(9345 端口/防火墙)、token 与首节点一致、tls-san 是否包含访问地址
rm -rf /var/lib/rancher 报 Operation not permittedhosts.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 仅建议小环境使用)