CentOS 8 安装 RKE2 集群指南
在 CentOS 8 上使用 RKE2 v1.37.1+rke2r1 从零搭建 Kubernetes 集群:环境准备、安装与启动、节点组网、运行时方案、就绪验证与示例应用访问,命令与回显实测验证。
CentOS 8 安装 RKE2 集群指南
目标:在 4 台 CentOS 8 服务器上从零搭建一套 RKE2 v1.37.1+rke2r1 集群(1 控制平面 + 3 工作节点),并完成基础验证与示例应用部署。本文所有命令与回显均在 CentOS 8(内核 6.8.0-138-generic)实测通过。
一、环境信息与主机规划
| 主机名 | 角色 | 内网 IP | 规格建议 |
|---|---|---|---|
| rke2-c8-server | server(control-plane + etcd) | 172.24.0.2 | 4 核 8 GB |
| rke2-c8-agent1 | agent(工作节点) | 172.24.0.3 | 2 核 4 GB |
| rke2-c8-agent2 | agent(工作节点) | 172.24.0.4 | 2 核 4 GB |
| rke2-c8-agent3 | agent(工作节点) | 172.24.0.5 | 2 核 4 GB |
- 操作系统:CentOS Linux release 8(内核 6.8.0-138-generic)
- 集群版本:RKE2 v1.37.1+rke2r1(Kubernetes v1.37.1)
- 集群 CIDR:Pod 10.42.0.0/16,Service 10.43.0.0/16
- 本机账号:root,密码示例 q1w2e3r4(生产环境请更换强密码)
端口规划(rke2 使用):
| 端口 | 用途 |
|---|---|
| 6443 | kube-apiserver HTTPS |
| 9345 | supervisor(agent 通过 wss 接入控制平面) |
| 10250 | kubelet |
| 6444 | 本地负载均衡备用端口 |
二、基础环境配置
2.1 关闭交换分区与防火墙
swapoff -a
sed -i '/ swap /s/^/#/' /etc/fstab
systemctl disable --now firewalld
💡 RKE2 要求 swap 关闭;防火墙按生产安全策略放行 6443/9345 端口,测试环境可直接关闭。
2.2 修复 CentOS 8 软件源(EOL 后官方源不可用)
CentOS 8 于 2021 年 12 月停止维护(EOL),默认源 mirrorlist.centos.org 已失效,安装依赖前必须切换到清华 vault 源:
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://mirror.centos.org|baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault|g' \
-e 's|/\$contentdir/\$releasever|/8.5.2111|g' \
-i.bak /etc/yum.repos.d/CentOS-Base.repo
验证源可用:
yum makecache
实测回显(末尾):
Metadata cache created.
2.3 安装基础依赖
yum install -y tar gzip curl iptables
实测回显(末尾):
Installed:
iptables-1.8.4-20.el8.x86_64 libnetfilter_conntrack-1.0.6-5.el8.x86_64
libnfnetlink-1.0.1-13.el8.x86_64 libnftnl-1.1.5-4.el8.x86_64
Complete!
⚠️ iptables 必装:RKE2 内嵌 containerd 的 CNI portmap 插件(traefik 等使用 hostPort 的组件)依赖
iptables可执行文件,缺省会报plugin type="portmap" failed (add): failed to open iptables: exec: "iptables": executable file not found。本集群实测已复现并补装解决,4 个节点都必须安装。
2.4 加载内核模块
modprobe br_netfilter
modprobe overlay
cat <<'EOF' > /etc/modules-load.d/rke2.conf
br_netfilter
overlay
EOF
💡 rke2 systemd 单元自带
ExecStartPre=/sbin/modprobe br_netfilter与overlay,此处显式加载并在重启后自动生效。
2.5 配置系统内核参数
cat <<'EOF' > /etc/sysctl.d/99-rke2.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
实测回显(末尾):
sysctl: setting key "net.ipv4.ip_forward"
sysctl: setting key "net.bridge.bridge-nf-call-iptables"
三、版本选型
| 组件 | 版本 | 说明 |
|---|---|---|
| RKE2 | v1.37.1+rke2r1 | 当前 stable 渠道版本(2026-09 发布) |
| Kubernetes | v1.37.1 | rke2 二进制内置(kubectl Kustomize v5.8.1) |
| containerd | v2.3.4-k3s1 | 内嵌运行时(socket 位于 /run/k3s/containerd/containerd.sock) |
| etcd | v3.7.1-k3s3 | hardened-etcd 构建 build20260915 |
| CoreDNS | v1.14.7 | 集群 DNS |
| CNI | calico v3.32.2 + flannel v0.28.9 | canal 模式(rke2 默认 CNI) |
💡 版本信息以
rke2 --version与kubectl version实测为准,升级请遵循官方 release 渠道(stable/latest)。
四、下载与安装 RKE2 二进制(tarball 方式)
⚠️ 安装方式说明(实测):RKE2 官方 yum 仓库
rpm.rancher.io/rke2/stable/stable/centos/8/x86_64对 CentOS 8 已返回 404(官方已停止 CentOS 8 的 rpm 包发布,仅 common 仓库可达),实测yum install rke2-agent报 "No match for argument"。因此 CentOS 8 推荐使用官方 tarball 安装,以下为实测完整流程。
4.1 下载官方 tarball
curl -fL -o /tmp/rke2.linux-amd64.tar.gz \
https://github.com/rancher/rke2/releases/download/v1.37.1+rke2r1/rke2.linux-amd64.tar.gz
⚠️ 若服务器无法直连 github.com,可将 tar 包上传后放置到
/tmp再解压,后续步骤不变。
4.2 解压安装到 /usr/local
tar xzf /tmp/rke2.linux-amd64.tar.gz -C /usr/local
chmod +x /usr/local/bin/rke2
4.3 验证二进制版本
rke2 --version
实测回显:
rke2 version v1.37.1+rke2r1 (bb33a3e8f191b46f773bd4eae2fe471927126c1b)
go version go1.26.8-X:boringcrypto
4.4 安装 systemd 服务单元
rke2 server --help > /dev/null
💡 RKE2 二进制首次以
server/agent子命令运行时会在/usr/local/lib/systemd/system/生成rke2-server.service与rke2-agent.service单元文件(Type=notify、Restart=always、RestartSec=5s、Delegate=yes),无需手工编写。
五、配置并启动控制平面(server)
以下操作在 rke2-c8-server(172.24.0.2)上执行。
5.1 编写启动配置 config.yaml
mkdir -p /etc/rancher/rke2
cat > /etc/rancher/rke2/config.yaml <<'EOF'
snapshotter: native
kubelet-arg:
- "cgroup-driver=cgroupfs"
EOF
配置说明:
| 配置键 | 说明 |
|---|---|
snapshotter: native | containerd 快照器使用 native,兼容共享 cgroup 树等受限内核环境(默认 overlayfs) |
kubelet-arg: cgroup-driver=cgroupfs | kubelet 使用 cgroupfs 驱动,与下方 containerd 的 SystemdCgroup=false 保持一致 |
5.2 配置 containerd 运行时参数(SystemdCgroup=false)
mkdir -p /var/lib/rancher/rke2/agent/etc/containerd/config-v3.toml.d
cat > /var/lib/rancher/rke2/agent/etc/containerd/config-v3.toml.d/00-cgroupfs.toml <<'EOF'
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = false
EOF
⚠️ 在共享 cgroup 树(系统级 cgroup 由宿主统一管理)的服务器环境中,rke2 默认
SystemdCgroup=true会导致 etcd 等静态 Pod 的 sandbox 反复被 SIGTERM 终止,日志出现Pod for etcd not synced (waiting for termination of old pod sandbox)、pod sandbox not found循环。将 containerd 的SystemdCgroup设为false并将 kubelet 驱动改为cgroupfs后,etcd 立即稳定(ATTEMPT 0)。标准 systemd 环境可省略此步骤。
5.3 配置镜像加速(registries.yaml)
国内服务器拉取 docker.io 镜像慢或失败时,配置 daocloud 镜像加速:
cat > /etc/rancher/rke2/registries.yaml <<'EOF'
mirrors:
docker.io:
endpoint:
- "https://docker.m.daocloud.io"
EOF
💡 rke2 启动时自动将 registries.yaml 合并进内嵌 containerd 配置,无需重启 containerd 服务。
5.4 配置 crictl(管理内嵌 containerd)
cat > /etc/crictl.yaml <<'EOF'
runtime-endpoint: unix:///run/k3s/containerd/containerd.sock
image-endpoint: unix:///run/k3s/containerd/containerd.sock
timeout: 10
debug: false
EOF
💡 RKE2 内嵌 containerd 的 socket 位于
/run/k3s/containerd/containerd.sock(与 K3s 一致),crictl 需通过/etc/crictl.yaml显式指定。
5.5 启动并设置开机自启
systemctl enable --now rke2-server
等待控制平面就绪:
journalctl -u rke2-server -f
实测回显(关键行):
time="2026-10-11T03:21:14Z" level=info msg="Starting rke2 v1.37.1+rke2r1 (bb33a3e8f191b46f773bd4eae2fe471927126c1b)"
time="2026-10-11T03:21:14Z" level=info msg="Saving certs to /var/lib/rancher/rke2/server/tls"
time="2026-10-11T03:21:15Z" level=info msg="Server node token is available at /var/lib/rancher/rke2/server/token"
time="2026-10-11T03:21:27Z" level=info msg="Wrote kubeconfig /etc/rancher/rke2/rke2.yaml"
time="2026-10-11T03:21:28Z" level=info msg="Kube API server is now running"
服务状态确认:
systemctl status rke2-server
实测回显(摘要):
● rke2-server.service - Rancher Kubernetes Engine v2 (server)
Loaded: loaded (/usr/local/lib/systemd/system/rke2-server.service; enabled)
Active: active (running) since Sun 2026-10-11 03:21:14 UTC
Main PID: 76126 (rke2)
Tasks: 114
Memory: 1.1G
CGroup: /system.slice/rke2-server.service
├─76126 /usr/local/bin/rke2 server
├─76144 containerd -c /var/lib/rancher/rke2/agent/etc/containerd/config.toml
5.6 验证控制平面
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
kubectl get nodes
实测回显:
NAME STATUS ROLES AGE VERSION
rke2-c8-server Ready control-plane,etcd 2m v1.37.1+rke2r1
查看集群信息:
kubectl cluster-info
实测回显:
Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/rke2-coredns-rke2-coredns:udp-53/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
六、获取集群加入令牌
cat /var/lib/rancher/rke2/server/token
实测回显(示例,实际以服务器生成为准):
K10fcfe51d0a0fec73982ffcf6ceb10d80af7e3158f57c8ba4ad944fb12869e7429::server:a457dedd175e0a09e6b326025f34a2a7
💡
server/token与node-token同值,agent 与 server 均使用该令牌加入。为安全起见可将令牌写入各节点/etc/rancher/rke2/config.yaml的token:字段。
七、添加工作节点(agent)
以下三个 agent 分别在 rke2-c8-agent1(172.24.0.3)、rke2-c8-agent2(172.24.0.4)、rke2-c8-agent3(172.24.0.5)上独立执行,每个节点单独操作,禁止循环批量。
7.1 加入 rke2-c8-agent1(172.24.0.3)
编写配置并启动:
mkdir -p /etc/rancher/rke2
cat > /etc/rancher/rke2/config.yaml <<'EOF'
server: https://172.24.0.2:9345
token: K10fcfe51d0a0fec73982ffcf6ceb10d80af7e3158f57c8ba4ad944fb12869e7429::server:a457dedd175e0a09e6b326025f34a2a7
snapshotter: native
kubelet-arg:
- "cgroup-driver=cgroupfs"
EOF
按 5.2 节配置 00-cgroupfs.toml(SystemdCgroup=false),按 5.3 节配置 registries.yaml,然后启动:
systemctl enable --now rke2-agent
7.2 加入 rke2-c8-agent2(172.24.0.4)
配置(仅 token 相同,server 地址不变):
mkdir -p /etc/rancher/rke2
cat > /etc/rancher/rke2/config.yaml <<'EOF'
server: https://172.24.0.2:9345
token: K10fcfe51d0a0fec73982ffcf6ceb10d80af7e3158f57c8ba4ad944fb12869e7429::server:a457dedd175e0a09e6b326025f34a2a7
snapshotter: native
kubelet-arg:
- "cgroup-driver=cgroupfs"
EOF
同样完成 00-cgroupfs.toml 与 registries.yaml 配置后启动:
systemctl enable --now rke2-agent
7.3 加入 rke2-c8-agent3(172.24.0.5)
配置:
mkdir -p /etc/rancher/rke2
cat > /etc/rancher/rke2/config.yaml <<'EOF'
server: https://172.24.0.2:9345
token: K10fcfe51d0a0fec73982ffcf6ceb10d80af7e3158f57c8ba4ad944fb12869e7429::server:a457dedd175e0a09e6b326025f34a2a7
snapshotter: native
kubelet-arg:
- "cgroup-driver=cgroupfs"
EOF
完成 00-cgroupfs.toml 与 registries.yaml 配置后启动:
systemctl enable --now rke2-agent
八、验证 4 节点集群就绪
回到 rke2-server 上执行:
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
kubectl get nodes -o wide
实测回显:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
rke2-c8-agent1 Ready <none> 3h21m v1.37.1+rke2r1 172.24.0.3 <none> CentOS Linux 8 6.8.0-138-generic (amd64) containerd://2.3.4-k3s1
rke2-c8-agent2 Ready <none> 3h19m v1.37.1+rke2r1 172.24.0.4 <none> CentOS Linux 8 6.8.0-138-generic (amd64) containerd://2.3.4-k3s1
rke2-c8-agent3 Ready <none> 3h15m v1.37.1+rke2r1 172.24.0.5 <none> CentOS Linux 8 6.8.0-138-generic (amd64) containerd://2.3.4-k3s1
rke2-c8-server Ready control-plane,etcd 3h23m v1.37.1+rke2r1 172.24.0.2 <none> CentOS Linux 8 6.8.0-138-generic (amd64) containerd://2.3.4-k3s1
查看全部组件状态:
kubectl get pods -A
实测回显(摘要,全量见附录):
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-rke2-c8-server 1/1 Running 4 (44m ago) 3h23m
kube-system kube-apiserver-rke2-c8-server 1/1 Running 1 (45m ago) 3h23m
kube-system kube-controller-manager-rke2-c8-server 1/1 Running 14 3h23m
kube-system kube-scheduler-rke2-c8-server 1/1 Running 12 (10m ago) 3h23m
kube-system rke2-canal-2zpcm 2/2 Running 0 10m
kube-system rke2-coredns-rke2-coredns-75bc995bd6-xml5d 1/1 Running 1 (42m ago) 156m
kube-system rke2-metrics-server-755f587c9-dmjdl 1/1 Running 13 (13m ago) 148m
kube-system rke2-traefik-mc99x 1/1 Running 1 (45m ago) 137m
💡 canal(calico + flannel)DaemonSet 在每个节点 2/2 Running;
helm-install-*任务均为 Completed,属正常(一次性 chart 安装任务)。
九、部署示例应用验证
9.1 创建 nginx 部署
kubectl create deployment nginx-demo --image=nginx:1.25-alpine --replicas=2
kubectl expose deployment nginx-demo --type=NodePort --port=80 --target-port=80 --name=nginx-demo-svc
实测回显:
deployment.apps/nginx-demo created
service/nginx-demo-svc exposed
9.2 查看应用状态
kubectl get deployment,svc,pods -o wide
实测回显:
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/nginx-demo 2/2 2 2 163m nginx nginx:1.25-alpine app=nginx-demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 3h23m <none>
service/nginx-demo-svc NodePort 10.43.30.86 <none> 80:31779/TCP 163m app=nginx-demo
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-demo-557f845598-fpkm4 1/1 Running 1 (42m ago) 163m 10.42.3.38 rke2-c8-agent3 <none> <none>
pod/nginx-demo-557f845598-hp6hq 1/1 Running 1 (42m ago) 163m 10.42.1.39 rke2-c8-agent1 <none> <none>
9.3 访问验证(NodePort 31779)
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:31779/
curl -s http://127.0.0.1:31779/ | head -5
实测回显:
HTTP 200
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
💡 也可用
kubectl port-forward svc/nginx-demo-svc 8080:80在管理机本地访问:curl http://127.0.0.1:8080/。
十、多运行时方案
RKE2 默认内嵌 containerd 作为唯一运行时,同时支持对接外部 CRI 实现(CRI-O、containerd 外置实例等)。
10.1 containerd(默认,本指南实测)
- 版本:containerd v2.3.4-k3s1(内嵌,随 rke2 自动启动)
- socket:
/run/k3s/containerd/containerd.sock - 管理工具:
crictl(配 /etc/crictl.yaml)、ctr(ctr --address /run/k3s/containerd/containerd.sock -n k8s.io images list)
export PATH=$PATH:/var/lib/rancher/rke2/bin
crictl version
实测回显:
Version: 0.1.0
RuntimeName: containerd
RuntimeVersion: v2.3.4-k3s1
RuntimeApiVersion: v1
内嵌组件镜像(ctr 实测):
docker.io/rancher/hardened-calico:v3.32.2-build20260909
docker.io/rancher/hardened-etcd:v3.7.1-k3s3-build20260915
docker.io/rancher/hardened-flannel:v0.28.9-build20260909
docker.io/rancher/hardened-kubernetes:v1.37.1-rke2r1-build20260924
docker.io/rancher/klipper-helm:v0.13.3-build20260909
docker.io/rancher/mirrored-pause:3.10.2
docker.io/rancher/rke2-runtime:v1.37.1-rke2r1
10.2 CRI-O(备选方案,未实测)
RKE2 支持通过 --container-runtime-endpoint 关闭内嵌 containerd 并对接外部 CRI 运行时。以 CRI-O 为例:
yum install -y cri-o
配置 CRI-O 默认运行时(如需 cgroupfs 驱动):
# /etc/crio/crio.conf.d/01-runtime.toml
[crio.runtime.runtimes.runc]
runtime_path = "/usr/bin/runc"
runtime_type = "oci"
monitor_cgroup = "/"
[crio.runtime]
conmon_cgroup = "pod"
在 rke2-server/rke2-agent 的 config.yaml 中关闭内嵌 containerd 并指定 CRI-O socket:
container-runtime-endpoint: "unix:///var/run/crio/crio.sock"
⚠️ 本节为备选方案说明,未在本环境实测,实施前请以 RKE2 官方 CRI 对接文档为准,并确保 CRI-O 版本与 Kubernetes v1.37 兼容。
十一、配置说明
| 配置文件 | 路径 | 作用 |
|---|---|---|
| 启动配置 | /etc/rancher/rke2/config.yaml | server/agent 共用,等价于命令行参数 |
| 镜像加速 | /etc/rancher/rke2/registries.yaml | 仓库镜像与私有仓库认证 |
| containerd 参数 | /var/lib/rancher/rke2/agent/etc/containerd/config-v3.toml.d/*.toml | 内嵌 containerd 追加配置 |
| crictl 配置 | /etc/crictl.yaml | 指定内嵌 containerd socket |
| systemd 单元 | /usr/local/lib/systemd/system/rke2-server.service、rke2-agent.service | 服务托管 |
| kubeconfig | /etc/rancher/rke2/rke2.yaml | kubectl 访问集群凭据 |
各文件键值与参数的逐项详解见《RKE2 集群配置文件详解(CentOS 8)》;常用运维命令见《RKE2 常用 CLI 命令详解(CentOS 8)》。
十二、常见问题(FAQ)
Q1:yum 安装 rke2 提示 No match for argument?
A:RKE2 官方 yum 仓库对 CentOS 8 已停止发布(repodata 返回 404),实测 rpm.rancher.io/rke2/stable/stable/centos/8/x86_64/repodata/repomd.xml 404。请改用 tarball 安装(本文第四节)。
Q2:traefik 等使用 hostPort 的组件一直 ContainerCreating?
A:日志报 plugin type="portmap" failed (add): failed to open iptables: exec: "iptables": executable file not found in $PATH,说明服务器缺少 iptables 可执行文件。安装 iptables 包(见 2.3 节)并删除对应 Pod 让其重建即可。
Q3:etcd 沙箱反复终止(Pod for etcd not synced / pod sandbox not found)?
A:共享 cgroup 树环境下 containerd 默认 SystemdCgroup=true 导致 sandbox 反复被 SIGTERM。按 5.2 节投放 00-cgroupfs.toml(SystemdCgroup=false)并设置 kubelet-arg: cgroup-driver=cgroupfs 后重启 rke2-server。
Q4:Pod 一直 Pending,sandbox 报 no IP addresses available in range set?
A:flannel host-local IPAM 残留文件占满节点 Pod 网段(实测 10.42.0.1-10.42.0.254 被 255 个残留文件占满,位于 /var/lib/cni/networks/k8s-pod-network/)。清理非活动 IP 文件(保留 lock 与 last_reserved_ip.0)并删除卡住的 Pod 重建。
Q5:拉取镜像报 502 Bad Gateway from docker.m.daocloud.io? A:镜像加速端临时故障,kubelet 会自动退避重试(BackOff 后重新 Pulling),一般数分钟内恢复;可删除对应 Pod 强制重拉。
Q6:kubectl 报 connection refused localhost:8080?
A:未设置 kubeconfig。RKE2 的 kubeconfig 在 /etc/rancher/rke2/rke2.yaml,执行 export KUBECONFIG=/etc/rancher/rke2/rke2.yaml 或 kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml。
Q7:rke2-agent 服务启动失败(service did not take the steps required by its unit configuration)?
A:Type=notify 单元在共享 cgroup 树环境下偶发 notify 超时;实际 rke2 进程可能已在运行且已连上服务器。清理 /var/lib/rancher/rke2/agent 残留后重启 rke2-agent 即可。
Q8:如何查看 token 或用环境变量注入?
A:token 位于 /var/lib/rancher/rke2/server/token;也可通过 RKE2_TOKEN 环境变量或在 config.yaml 写 token: 注入(二者等价)。
十三、卸载
13.1 停止并清理 agent
systemctl disable --now rke2-agent
/usr/local/bin/rke2-uninstall.sh
13.2 停止并清理 server
systemctl disable --now rke2-server
/usr/local/bin/rke2-uninstall.sh
💡
rke2-uninstall.sh会自动停止服务、删除/var/lib/rancher/rke2数据目录、移除/usr/local/bin下 rke2 相关二进制与 systemd 单元文件。卸载 agent 与 server 时使用各自节点上的脚本,先卸载 agent 再卸载 server。
十四、参考链接
- RKE2 官方文档:https://docs.rke2.io/
- RKE2 安装说明:https://docs.rke2.io/install/methods
- RKE2 Release 下载:https://github.com/rancher/rke2/releases
- RKE2 config.yaml 参考:https://docs.rke2.io/install/configuration
- CRI-O 官网:https://cri-o.io/
- 清华 vault 源:https://mirrors.tuna.tsinghua.edu.cn/centos-vault/
十三、参考链接
- RKE2 官方文档:https://docs.rke2.io/
- RKE2 安装指南:https://docs.rke2.io/install/quickstart
- RKE2 GitHub Releases:https://github.com/rancher/rke2/releases
- Kubernetes 官方文档:https://kubernetes.io/zh-cn/docs/home/