CentOS 8 安装 RKE2 集群指南

在 CentOS 8 上使用 RKE2 v1.37.1+rke2r1 从零搭建 Kubernetes 集群:环境准备、安装与启动、节点组网、运行时方案、就绪验证与示例应用访问,命令与回显实测验证。

RKE2RKE2Kubernetesk8s2026/10/11

CentOS 8 安装 RKE2 集群指南

目标:在 4 台 CentOS 8 服务器上从零搭建一套 RKE2 v1.37.1+rke2r1 集群(1 控制平面 + 3 工作节点),并完成基础验证与示例应用部署。本文所有命令与回显均在 CentOS 8(内核 6.8.0-138-generic)实测通过。

一、环境信息与主机规划

主机名角色内网 IP规格建议
rke2-c8-serverserver(control-plane + etcd)172.24.0.24 核 8 GB
rke2-c8-agent1agent(工作节点)172.24.0.32 核 4 GB
rke2-c8-agent2agent(工作节点)172.24.0.42 核 4 GB
rke2-c8-agent3agent(工作节点)172.24.0.52 核 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 使用):

端口用途
6443kube-apiserver HTTPS
9345supervisor(agent 通过 wss 接入控制平面)
10250kubelet
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"

三、版本选型

组件版本说明
RKE2v1.37.1+rke2r1当前 stable 渠道版本(2026-09 发布)
Kubernetesv1.37.1rke2 二进制内置(kubectl Kustomize v5.8.1)
containerdv2.3.4-k3s1内嵌运行时(socket 位于 /run/k3s/containerd/containerd.sock)
etcdv3.7.1-k3s3hardened-etcd 构建 build20260915
CoreDNSv1.14.7集群 DNS
CNIcalico v3.32.2 + flannel v0.28.9canal 模式(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: nativecontainerd 快照器使用 native,兼容共享 cgroup 树等受限内核环境(默认 overlayfs)
kubelet-arg: cgroup-driver=cgroupfskubelet 使用 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.yamlserver/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.yamlkubectl 访问集群凭据

各文件键值与参数的逐项详解见《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。

十四、参考链接

十三、参考链接