Skip to content

第三部分 RKE2 从入门到精通

RKE2(Rancher Kubernetes Engine 2,又名 RKE Government)是 Rancher 推出的第二代 Kubernetes 发行版。它把"安全、合规、简单"刻进了基因:控制平面以静态 Pod 运行在 containerd 之上,默认开启 CIS 加固基线,提供 FIPS 140-2 认证的加密模块,一条安装命令即可拉起一个生产级集群。本部分将带你从 RKE2 的设计哲学出发,完整走过安装、HA 部署、配置调优、私有仓库接入、etcd 备份恢复、升级维护、安全加固与故障排查的全流程——这也是成为一名合格的 K8s 运维工程师的必经之路。


第 1 章 RKE2 简介

1.1 什么是 RKE2

RKE2 是 SUSE Rancher 公司开源的 Kubernetes 发行版,是 RKE1(Rancher Kubernetes Engine)的下一代产品。它完全兼容上游 Kubernetes API,同时做了以下关键改造:

特性说明
控制平面形态kube-apiserver / kube-controller-manager / kube-scheduler / etcd 以静态 Pod 形式运行在 containerd 上,不再是 Docker 容器
容器运行时内置并仅支持 containerd(RKE1 依赖 Docker)
安全基线内置 CIS Kubernetes Benchmark 加固 profile(cis profile)
FIPS提供通过 FIPS 140-2 认证的 Go 加密模块(BoringCrypto)构建版本
分发形态单一二进制 rke2,安装后以 systemd 服务(rke2-server / rke2-agent)运行
版本号形如 v1.35.6+rke2r1,前半部分是 Kubernetes 版本,后半部分是 RKE2 打包修订号

1.2 RKE2 与 RKE1、k3s、kubeadm 对比

对比维度RKE1RKE2k3skubeadm
厂商RancherRancherRancherKubernetes 社区
容器运行时Dockercontainerd(内置)containerd(内置)需自行安装(containerd/CRI-O)
控制平面部署Docker 容器静态 Pod单进程内嵌systemd 直跑二进制 + 静态 Pod(自托管可选)
组件形态多组件容器单二进制 + 内置组件单二进制(极简)多个独立二进制
etcd容器化嵌入式 etcd(静态 Pod)可选嵌入式 etcd / SQLite静态 Pod 或外部 etcd
CIS 加固需手工内置 cis profile部分支持需手工
FIPS 140-2不支持支持不支持不支持
默认 CNICanal/Calico/Flannel 可选Canal(可换 Calico/Cilium/Multus)Flannel无(需自行安装)
资源占用极小(适合边缘/IoT)
适用场景存量集群生产环境、政企合规边缘、开发测试学习、完全自定义

选型建议:

  • 企业生产集群、有等保/CIS/FIPS 合规要求 → RKE2
  • 边缘节点、资源受限、轻量测试 → k3s
  • 深入理解 K8s 组件细节、做 CKA 备考 → kubeadm
  • 已有 RKE1 集群 → 规划向 RKE2 迁移(RKE1 已进入维护期)

1.3 RKE2 设计哲学

  1. 安全第一(Secure by Default)

    • 默认启用 SELinux 支持,提供 cis profile 一键满足 CIS Benchmark 大部分检查项。
    • 所有组件间通信使用双向 TLS,证书由 RKE2 自动生成与轮换。
    • 控制平面静态 Pod 清单只读挂载,kubelet 直接管理,杜绝手工篡改。
  2. 一切皆静态 Pod

    • 控制平面组件(etcd、kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、cloud-controller-manager)的清单由 RKE2 渲染到 /var/lib/rancher/rke2/agent/pod-manifests/,由 kubelet 拉起。这意味着你可以用 crictl ps 直接看到控制平面容器。
  3. 声明式组件管理

    • 内置 helm-controller,集群插件(CoreDNS、ingress-nginx、metrics-server 等)以 HelmChart CRD 形式声明在 /var/lib/rancher/rke2/server/manifests/,可被用户自定义覆盖。
  4. 离线友好

    • 提供 tarball 离线安装包(含全部系统镜像),支持完全离线(air-gapped)部署,适合政企内网环境。

1.4 RKE2 架构

RKE2 集群有两种节点角色:

  • server 节点:运行控制平面(etcd + apiserver + controller-manager + scheduler),同时也默认承担 worker 负载(可打污点禁止调度)。
  • agent 节点:纯 worker 节点,只运行 kubelet + kube-proxy + CNI。
                        ┌────────────────────────────────────────────┐
                        │            固定注册地址 (VIP/LB)            │
                        │        https://<vip>:9345  (注册引导)       │
                        │        https://<vip>:6443  (kube-apiserver) │
                        └───────────────┬────────────────────────────┘

        ┌───────────────────────────────┼───────────────────────────────┐
        │                               │                               │
┌───────▼────────┐            ┌────────▼───────┐             ┌────────▼───────┐
│  server-1      │            │   server-2     │             │   server-3     │
│ (首节点/引导)   │◄──etcd────►│ control-plane  │◄───etcd────►│ control-plane  │
│                │  2379/2380 │     + etcd     │   2379/2380 │     + etcd     │
│ 静态 Pod:      │            │ 静态 Pod:      │             │ 静态 Pod:      │
│  etcd          │            │  etcd          │             │  etcd          │
│  kube-apiserver│            │  kube-apiserver│             │  kube-apiserver│
│  controller-mgr│            │  controller-mgr│             │  controller-mgr│
│  scheduler     │            │  scheduler     │             │  scheduler     │
│  kube-proxy    │            │  kube-proxy    │             │  kube-proxy    │
│ kubelet+containerd           │ kubelet+containerd           │ kubelet+containerd
└───────┬────────┘            └────────┬───────┘             └────────┬───────┘
        │       CNI (Canal/Calico VXLAN 8472 / WireGuard 51820)       │
┌───────▼────────┐            ┌────────▼───────┐
│   agent-1      │            │   agent-2      │
│ kubelet        │            │ kubelet        │
│ kube-proxy     │            │ kube-proxy     │
│ containerd     │            │ containerd     │
└────────────────┘            └────────────────┘

server 节点上的静态 Pod 清单目录:

bash
ls /var/lib/rancher/rke2/agent/pod-manifests/
# cloud-controller-manager.yaml  etcd.yaml  kube-apiserver.yaml
# kube-controller-manager.yaml   kube-proxy.yaml  kube-scheduler.yaml

集群级组件清单目录(helm-controller 托管):

bash
ls /var/lib/rancher/rke2/server/manifests/
# coredns.yaml  rke2-canal.yaml  rke2-ingress-nginx.yaml
# rke2-metrics-server.yaml  ...

注意事项:以上两个目录中的文件由 RKE2 自动渲染,不要手工修改。要自定义组件,应使用 HelmChartConfig CRD(见第 9 章)或 disable 配置项。


第 2 章 安装详解

2.1 安装方式总览

方式适用场景核心命令
在线脚本(官方源)可访问 GitHubcurl -sfL https://get.rke2.io | sh -
在线脚本(国内镜像)国内网络INSTALL_RKE2_MIRROR=cn curl -sfL https://rancher-mirror.rancher.cn/rke2/install.sh | sh -
Tarball 离线安装离线/内网环境预下载 tar 包 + INSTALL_RKE2_ARTIFACT_PATH
RPM 安装RHEL/Rocky 9yum install rke2-server(较少用)

2.2 安装脚本环境变量

环境变量说明示例
INSTALL_RKE2_VERSION指定版本v1.35.6+rke2r1
INSTALL_RKE2_CHANNEL指定通道(与 VERSION 二选一)stable / latest / v1.35
INSTALL_RKE2_TYPE安装类型server(默认)/ agent
INSTALL_RKE2_MIRROR镜像源cn(使用 rancher-mirror.rancher.cn)
INSTALL_RKE2_ARTIFACT_PATH本地离线包路径/opt/rke2-artifacts
INSTALL_RKE2_EXEC启动命令参数注入server / agent 及其参数
INSTALL_RKE2_SKIP_ENABLE只安装不 enable 服务true

2.3 在线安装(官方源)

bash
# 安装 server(最新 stable 通道)
curl -sfL https://get.rke2.io | sh -

# 指定版本
curl -sfL https://get.rke2.io | INSTALL_RKE2_VERSION="v1.35.6+rke2r1" sh -

# 安装 agent
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh -

2.4 国内镜像源安装

国内环境推荐使用 Rancher 中国镜像站:

bash
# 方式一:INSTALL_RKE2_MIRROR=cn(脚本内部自动切换到 rancher-mirror.rancher.cn)
curl -sfL https://get.rke2.io | INSTALL_RKE2_MIRROR=cn sh -

# 方式二:直接从中国镜像站获取脚本
curl -sfL https://rancher-mirror.rancher.cn/rke2/install.sh | \
  INSTALL_RKE2_MIRROR=cn \
  INSTALL_RKE2_VERSION="v1.35.6+rke2r1" \
  sh -

系统镜像(容器镜像)仍会默认从 docker.io/rancher 拉取,离线或内网环境需要配合 system-default-registry(见第 5、6 章)。

2.5 Tarball 离线安装(生产内网推荐)

第一步:在能联网的机器下载制品

bash
mkdir -p /opt/rke2-artifacts && cd /opt/rke2-artifacts

# 安装脚本
curl -sfL https://get.rke2.io -o install.sh

# RKE2 二进制包
curl -sfLO https://github.com/rancher/rke2/releases/download/v1.35.6+rke2r1/rke2.linux-amd64.tar.gz
# 校验文件
curl -sfLO https://github.com/rancher/rke2/releases/download/v1.35.6+rke2r1/sha256sum-amd64.txt
# 系统镜像包(containerd 会从中预导入镜像,无需联网拉取)
curl -sfLO https://github.com/rancher/rke2/releases/download/v1.35.6+rke2r1/rke2-images.linux-amd64.tar.zst
# 若使用 calico CNI 还需:
curl -sfLO https://github.com/rancher/rke2/releases/download/v1.35.6+rke2r1/rke2-images-calico.linux-amd64.tar.zst

第二步:拷贝到目标机器并安装

bash
cd /opt/rke2-artifacts
INSTALL_RKE2_ARTIFACT_PATH=/opt/rke2-artifacts \
INSTALL_RKE2_VERSION="v1.35.6+rke2r1" \
INSTALL_RKE2_TYPE=server \
sh install.sh

systemctl enable rke2-server --now

镜像包也可以放到 /var/lib/rancher/rke2/agent/images/ 目录,RKE2 启动时会自动导入 containerd。

本仓库实战参考rke2/README.md 记录了使用本地 Nginx 作为软件源(INSTALL_RKE2_ARTIFACT_PATH=/opt/rke2-artifacts)的完整离线安装流程;rke2/install-server.shrke2/install-agent.sh 是可直接执行的自动化脚本。

2.6 systemd 单元

安装脚本会创建并注册 systemd 服务:

服务节点角色单元文件
rke2-server.serviceserver 节点/usr/lib/systemd/system/rke2-server.service
rke2-agent.serviceagent 节点/usr/lib/systemd/system/rke2-agent.service
bash
systemctl enable rke2-server --now   # 启动 server
systemctl status rke2-server         # 查看状态
journalctl -u rke2-server -f         # 跟踪日志
systemctl restart rke2-agent         # 重启 agent

注意事项:server 首次启动需要导入镜像、生成证书、引导 etcd,耗时可能长达 1~5 分钟,期间 systemctl status 显示 activating 是正常现象。

2.7 二进制与目录结构

路径说明
/usr/local/bin/rke2RKE2 主二进制(安装脚本通常软链到 /usr/bin/rke2
/usr/local/bin/{kubectl,crictl,ctr}包装命令软链
/etc/rancher/rke2/config.yaml主配置文件
/etc/rancher/rke2/registries.yaml私有镜像仓库配置
/etc/rancher/rke2/rke2.yaml管理员 kubeconfig
/var/lib/rancher/rke2/bin/内置 kubectl/crictl/ctr 等工具
/var/lib/rancher/rke2/data/解压的组件二进制(按版本分目录)
/var/lib/rancher/rke2/agent/pod-manifests/控制平面静态 Pod 清单
/var/lib/rancher/rke2/agent/images/离线镜像包放置目录
/var/lib/rancher/rke2/agent/containerd/containerd 数据目录
/var/lib/rancher/rke2/server/manifests/集群组件 HelmChart 清单
/var/lib/rancher/rke2/server/tokenserver token
/var/lib/rancher/rke2/server/node-token节点注册 token
/var/lib/rancher/rke2/server/agent-tokenagent 注册 token
/var/lib/rancher/rke2/server/db/etcd 数据与快照
/var/lib/rancher/rke2/server/tls/集群 CA 与组件证书
/var/log/pods/Pod 日志
/var/log/syslog 或 journald系统日志

kubeconfig 位置与使用:

bash
# server 节点上的管理员 kubeconfig
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
kubectl get nodes

# 或写入 root 的默认位置
mkdir -p ~/.kube
cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
# 注意:rke2.yaml 中 server 地址默认是 https://127.0.0.1:6443,
# 拷贝到集群外使用时要改成 https://<server-ip 或 VIP>:6443(且该地址必须在 tls-san 中)

rke2 包装命令:

bash
rke2 kubectl get nodes                 # 等价于内置 kubectl
rke2 crictl ps                         # 操作内置 containerd(自动带正确 endpoint)
rke2 crictl images
rke2 ctr -n k8s.io images ls           # 底层 ctr
rke2 etcd-snapshot save --name snap1   # etcd 快照子命令
rke2 certificate rotate                # 证书轮换
rke2 secrets-encrypt rotate            # 加密密钥轮换

最佳实践:把下面几行加入 /root/.bashrc,避免每次手敲长路径:

bash
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
export PATH=$PATH:/var/lib/rancher/rke2/bin
export CRI_CONFIG_FILE=/var/lib/rancher/rke2/agent/etc/crictl.yaml

第 3 章 单节点与 HA 集群部署

3.1 节点规划示例

以本仓库 rke2/README.md 中的真实环境为例:

节点名IP 地址角色说明
rocky9-vm-04192.168.122.190control-plane,etcd第一个 server 节点
rocky9-vm-05192.168.122.96workeragent 节点
rocky9-vm-06192.168.122.231workeragent 节点

集群 CIDR:10.12.0.0/16;Service CIDR:10.13.0.0/16(生产环境建议避免使用默认的 10.42/10.43,以便与现有网络区分并方便排障)。

3.2 部署前准备(RHEL/Rocky 9)

bash
# 关闭或配置防火墙(生产建议放行端口而非直接关闭,端口列表见第 11 章)
systemctl disable firewalld --now

# 关闭 swap
swapoff -a
sed -i '/swap/d' /etc/fstab

# SELinux:RKE2 原生支持 SELinux,保持 enforcing 即可(需安装容器策略包)
dnf install -y container-selinux selinux-policy-base
# 若使用 cis profile 需安装:
dnf install -y rke2-selinux   # 通常随 rke2 自动安装

# NetworkManager 配置(Calico/Canal 要求忽略 CNI 接口,防止 veth 被 NM 干扰)
cat > /etc/NetworkManager/conf.d/rke2-canal.conf <<EOF
[keyfile]
unmanaged-devices=interface-name:cali*;interface-name:flannel*
EOF
systemctl reload NetworkManager

# 时间同步(etcd 对时钟敏感)
dnf install -y chrony && systemctl enable chronyd --now

Ubuntu 24.04 类似(apt install chronyufw disable 或放行端口)。

3.3 首台 server(引导节点)

编写 /etc/rancher/rke2/config.yaml(本仓库 rke2/server-config.yaml 的实战版本):

yaml
node-name: rocky9-vm-04
node-ip: 192.168.122.190
advertise-address: 192.168.122.190
tls-san:
  - 192.168.122.190
  - rocky9-vm-04
  # 如果有 VIP/LB,必须加在这里!
  # - 192.168.122.200
  # - rke2-api.example.com
cluster-cidr: 10.12.0.0/16
service-cidr: 10.13.0.0/16
kube-proxy-arg:
  - "proxy-mode=ipvs"
system-default-registry: 192.168.122.156:30000
etcd-snapshot-retention: 5
etcd-snapshot-schedule-cron: "0 */6 * * *"

启动:

bash
systemctl enable rke2-server --now
# 等待 kubeconfig 生成
until [ -f /etc/rancher/rke2/rke2.yaml ]; do sleep 2; done
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
kubectl get nodes

3.4 固定注册地址(Fixed Registration Address)

这是 HA 部署中最容易被忽视、却最关键的设计。 每个 agent 和后续加入的 server 都需要一个 server: https://<地址>:9345 来注册。如果直接写首节点 IP:

  • 首节点宕机后,新节点无法加入;
  • kubectl 通过首节点 6443 访问,首节点挂了控制面不可达(即使其余 server 正常)。

方案对比:

方案优点缺点适用
kube-vip无额外机器、ARP/BGP 宣告 VIP仅 L2/需交换机配合裸金属/虚拟化同网段
haproxy + keepalived经典稳定、可健康检查需 2 台 LB 机器(可与 server 复用)通用生产
云 LB(SLB/NLB)免运维云厂商绑定公有云
DNS 轮询简单无健康检查、切换慢不推荐生产

haproxy + keepalived 配置示例(部署在两台 LB 上,VIP 192.168.122.200):

bash
# /etc/haproxy/haproxy.cfg
frontend rke2-frontend
    bind *:9345
    mode tcp
    default_backend rke2-server-9345
frontend rke2-apiserver
    bind *:6443
    mode tcp
    default_backend rke2-server-6443

backend rke2-server-9345
    mode tcp
    balance roundrobin
    server s1 192.168.122.190:9345 check
    server s2 192.168.122.191:9345 check
    server s3 192.168.122.192:9345 check

backend rke2-server-6443
    mode tcp
    balance roundrobin
    server s1 192.168.122.190:6443 check
    server s2 192.168.122.191:6443 check
    server s3 192.168.122.192:6443 check
bash
# /etc/keepalived/keepalived.conf(主节点;备节点 state BACKUP、priority 90)
vrrp_instance VI_RKE2 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass rke2vip1
    }
    virtual_ipaddress {
        192.168.122.200/24
    }
}

kube-vip 方案(无需独立 LB 节点):在每个 server 节点上以静态 Pod 形式运行 kube-vip(ARP 模式),或由 RKE2 的 HelmChart 部署。社区常用做法:

yaml
# /var/lib/rancher/rke2/server/manifests/kube-vip.yaml(server 启动后自动部署)
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: kube-vip
  namespace: kube-system
spec:
  chart: kube-vip
  repo: https://kube-vip.github.io/helm-charts
  set:
    config.address: "192.168.122.200"

最佳实践:无论用哪种方案,首节点的 tls-san 中必须包含 VIP 和 VIP 对应域名,否则 kubectl 走 VIP 时证书校验失败。事后补加 tls-san 需要重启所有 server 触发证书重新生成。

3.5 多 server 加入

后续 server 节点 /etc/rancher/rke2/config.yaml

yaml
server: https://192.168.122.200:9345      # 固定注册地址(或首节点 IP)
token: <首节点 /var/lib/rancher/rke2/server/node-token 的内容>
node-name: rocky9-vm-07
node-ip: 192.168.122.191
tls-san:
  - 192.168.122.200
cluster-cidr: 10.12.0.0/16                # 必须与首节点完全一致!
service-cidr: 10.13.0.0/16                # 必须与首节点完全一致!
kube-proxy-arg:
  - "proxy-mode=ipvs"
system-default-registry: 192.168.122.156:30000
bash
systemctl enable rke2-server --now

注意事项(真实踩坑):新增 server 时 cluster-cidrservice-cidrcnidisable 列表等关键配置必须与既有 server 完全一致,否则 rke2-server 会反复重启并报 critical configuration value mismatch between servers。详见仓库案例 k8s-issues/rke2-master-join-fails-critical-configuration-mismatch.md 和节点添加手册 k8s-issues/rke2-node-addition-operation-manual.md

server 节点数量与 etcd 仲裁:server 数量应为奇数(1/3/5),3 节点可容忍 1 台故障,5 节点可容忍 2 台。生产推荐 3 台 server

3.6 agent 加入

agent 节点 /etc/rancher/rke2/config.yaml(本仓库 rke2/agent-config.yaml 的实战版本):

yaml
server: https://192.168.122.200:9345
token: xxx      # node-token 或 agent-token 均可
node-name: rocky9-vm-05
node-ip: 192.168.122.96
kube-proxy-arg:
  - "proxy-mode=ipvs"
system-default-registry: 192.168.122.156:30000
bash
systemctl enable rke2-agent --now
# 在 server 上验证
kubectl get nodes -o wide

注意事项(真实踩坑):新节点加入后长时间 NotReady、日志反复出现 Pod for etcd not synced (pod sandbox not found),往往是离线镜像导入耗时导致的正常现象,耐心等待 rke2-images tar 包导入完成即可。详见 k8s-issues/rke2-master-join-notready-image-import-delay.md

3.7 token 管理

token 文件用途说明
/var/lib/rancher/rke2/server/node-tokenserver/agent 注册格式 K10<ca-hash>::server:<password>,含 CA 指纹,可防中间人
/var/lib/rancher/rke2/server/agent-tokenagent 注册仅 agent 角色权限,最小权限推荐用它注册 agent
/var/lib/rancher/rke2/server/token内部 tokenserver 间通信用
bash
cat /var/lib/rancher/rke2/server/node-token
# xxx
  • 可在首节点 config.yaml 中用 token: xxx 预置自定义 token(本仓库 install-server.sh` 即如此),后续节点使用同一 token。
  • token 轮换:修改所有节点 config.yaml 中的 token 并逐台重启;旧节点在重启前仍用旧 token 通信。

第 4 章 config.yaml 配置详解

4.1 配置文件基础

  • 位置:/etc/rancher/rke2/config.yaml
  • 格式:YAML,key: value;列表用 -[a, b]
  • 修改后必须 systemctl restart rke2-server(或 rke2-agent)生效
  • 几乎所有命令行 flag 都可写成配置项:--tls-san=xtls-san: x

4.2 常用 server 配置项

配置项说明示例
cluster-cidrPod IP 段10.12.0.0/16
service-cidrService IP 段10.13.0.0/16
cluster-dnsCoreDNS Service IP10.13.0.10
cluster-domain集群域名cluster.local
tls-sanapiserver 证书附加 SAN[192.168.122.200, rke2.example.com]
cniCNI 插件canal / calico / cilium / none / multus,canal
disable禁用内置组件[rke2-ingress-nginx, rke2-servicelb]
disable-cloud-controller禁用内置 CCMtrue(对接外部 CCM 时)
etcd-snapshot-schedule-cronetcd 定时快照"0 */6 * * *"
etcd-snapshot-retention快照保留份数5
etcd-snapshot-dir快照目录/var/lib/rancher/rke2/server/db/snapshots
etcd-s3快照上传 S3见第 7 章
kube-apiserver-arg透传 apiserver 参数["audit-log-path=/var/lib/rancher/rke2/server/logs/audit.log"]
kube-controller-manager-arg透传 KCM 参数["node-cidr-mask-size=24"]
kube-scheduler-arg透传调度器参数
kube-proxy-arg透传 kube-proxy 参数["proxy-mode=ipvs"]
kubelet-arg透传 kubelet 参数["max-pods=220", "eviction-hard=memory.available<500Mi"]
profile安全基线cis
selinux强制启用 SELinux 上下文true
system-default-registry系统镜像默认仓库192.168.122.156:30000
node-name / node-ip节点名/节点 IP双栈时 node-ip: 192.168.1.10,fd00::10
node-label / node-taint节点标签/污点node-taint: ["CriticalAddonsOnly=true:NoExecute"]
write-kubeconfig-moderke2.yaml 权限0644(默认 0600
secrets-encryption启用 secret 静态加密true
embedded-registry启用内嵌分布式镜像仓库true

4.3 常用 agent 配置项

agent 支持的子集:servertokennode-namenode-ipnode-labelnode-taintkubelet-argkube-proxy-argcontainer-runtime-endpointsystem-default-registryselinux 等。与集群数据相关的项(cluster-cidr 等)只对 server 有意义。

4.4 CNI 选择

cni 值说明
canal默认,Flannel(VXLAN) + Calico 网络策略,开箱即用
calico纯 Calico,支持 BGP/VXLAN,网络策略强大
ciliumeBPF 数据面,可替代 kube-proxy,观测性强(Hubble)
multus,canalMultus + Canal 组合,支持多网卡 Pod
none不安装 CNI,自行部署(如 Calico 官方 manifest)

4.5 disable 内置组件

yaml
disable:
  - rke2-ingress-nginx    # 不用内置 ingress(改用自建 ingress 或 traefik)
  - rke2-servicelb        # 不用 klipper-lb(改用 MetalLB)
  - rke2-metrics-server   # 自建 metrics-server
  - rke2-coredns          # 极少见

注意事项disable 列表在所有 server 节点上必须一致

4.6 etcd 相关参数

yaml
etcd-arg:
  - "quota-backend-bytes=4294967296"   # etcd 存储上限调大到 4GB(默认 2GB)
  - "auto-compaction-retention=8"      # 自动压缩保留 8 小时
etcd-snapshot-schedule-cron: "0 */6 * * *"
etcd-snapshot-retention: 10

4.7 kubelet 调优示例

yaml
kubelet-arg:
  - "max-pods=220"
  - "eviction-hard=memory.available<500Mi,nodefs.available<10%"
  - "system-reserved=cpu=500m,memory=1Gi"
  - "kube-reserved=cpu=500m,memory=1Gi"
  - "image-gc-high-threshold=80"
  - "serialize-image-pulls=false"

4.8 镜像加速(国内环境)

方式一:system-default-registry 统一改系统镜像源(见第 6 章)。

方式二:registries.yamldocker.io 配置 mirror(见第 6 章),对所有业务镜像生效。

4.9 配置加载顺序与环境变量

RKE2 参数来源优先级(后者覆盖前者):

  1. 内置默认值
  2. 配置文件 /etc/rancher/rke2/config.yaml(可用 -c 指定其他路径)
  3. 环境变量(如 RKE2_TOKENRKE2_URL,对应 tokenserver
  4. 命令行参数(如 rke2 server --cluster-cidr=...

最佳实践

  • 集群初始化前就把 cluster-cidr/service-cidr/tls-san/cni 定好——这些项集群建成后不可更改(更改会导致新 server 无法加入或网络重建)。
  • 用 Ansible/脚本统一渲染 config.yaml,保证所有 server 关键配置一致(参考本仓库 rke2/install-server.shrke2/install-agent.sh)。
  • config.yaml 是 YAML,布尔值写 true/false,带特殊字符的 cron 表达式务必加引号。

4.10 常见面试题(本章)

  1. RKE2 的 config.yaml 修改后如何生效? 重启对应 systemd 服务;集群级配置(cluster-cidr 等)建成后不可变。
  2. tls-san 的作用?忘记加 VIP 怎么办? apiserver 证书的 Subject Alternative Name;补加后需重启所有 server 重新签发证书。
  3. RKE2 token 的格式与安全意义? K10<CA-SHA256>::server:<secret>,前置 CA 哈希让新节点可校验对端身份,防中间人。

第 5 章 私有镜像仓库:registries.yaml

5.1 为什么需要 registries.yaml

生产环境几乎都使用私有仓库(Harbor 等),常见问题:

  • 仓库使用 HTTP 或自签名证书 → containerd 默认拒绝;
  • docker.io 拉不动 → 需要 mirror 加速;
  • 私有仓库需要认证 → 需要配置凭据。

RKE2 通过 /etc/rancher/rke2/registries.yaml 统一配置 containerd 的 registry 行为,无需重启服务即可热加载(RKE2 会 watch 该文件变更)。

5.2 registries.yaml 完整结构

yaml
# mirrors:定义"拉取某仓库镜像时,实际去哪些 endpoint 找"
mirrors:
  docker.io:
    endpoint:
      - "https://harbor.example.com"      # 优先从 Harbor 代理仓库拉
      - "https://registry-1.docker.io"    # 兜底回源
      # rewrite:                           # 可选:路径重写
      #   "^rancher/(.*)": "library/rancher/$1"
  "192.168.122.156:30000":
    endpoint:
      - "http://192.168.122.156:30000"    # HTTP 仓库直接写 http://

# configs:定义"访问某仓库时的认证与 TLS 行为"
configs:
  "harbor.example.com":
    auth:
      username: xxx
      password: xxx
      # 也可用 auth: <base64(user:pass)> 或 identitytoken
    tls:
      cert_file: /etc/rancher/rke2/harbor-client.crt   # 双向 TLS 时
      key_file:  /etc/rancher/rke2/harbor-client.key
      ca_file:   /etc/rancher/rke2/harbor-ca.crt       # 自签名 CA
      insecure_skip_verify: true                        # 跳过证书校验(二选一)

本仓库 rke2/registries.yamlrke2/README.md 中的真实配置(HTTP Harbor 仓库):

yaml
configs:
  "192.168.122.156:30000":
    tls:
      insecure_skip_verify: true
mirrors:
  "192.168.122.156:30000":
    endpoint:
      - "http://192.168.122.156:30000"
  "docker.io":
    endpoint:
      - "http://192.168.122.156:30000"

5.3 mirror 与 endpoint 的工作机制

  • mirrors.<name> 中的 name 是镜像引用里的仓库名(如 docker.iogcr.ioquay.io、私有仓库地址)。
  • 拉取 nginx:1.27(等价于 docker.io/library/nginx:1.27)时,containerd 按 endpoint 顺序尝试:
    1. 先请求 https://harbor.example.com/v2/library/nginx/manifests/1.27
    2. 全部 endpoint 失败后报错(不会自动回到未列出的默认源——除非你把默认源也写进 endpoint 列表)。
  • endpoint 的 scheme 决定协议:http:// 即明文 HTTP(自动视为 insecure);https:// 配合 configs 中的 TLS 设置。

5.4 system-default-registry 与 registries.yaml 的区别

机制作用范围典型用途
system-default-registry只影响 RKE2 系统组件镜像(如 rancher/hardened-coredns系统镜像全部从 Harbor 拉取,离线环境必备
registries.yaml mirrors影响 所有容器镜像(系统 + 业务)docker.io 加速、私有仓库 HTTP/自签名支持

最佳实践:离线环境两者都要配——system-default-registry 指向 Harbor(系统镜像已推送过去),registries.yaml 配置 Harbor 的 HTTP/TLS 访问方式。本仓库 rke2/server-config.yaml 就是该组合的实战样例。

5.5 底层原理:containerd 配置生成

RKE2 启动时根据 registries.yaml 生成 containerd 的 hosts 目录配置:

bash
ls /var/lib/rancher/rke2/agent/etc/containerd/certs.d/
# docker.io/  192.168.122.156:30000/  ...
cat /var/lib/rancher/rke2/agent/etc/containerd/certs.d/docker.io/hosts.toml

生成的 hosts.toml 等价于 containerd 原生的 registry hosts 配置(servercapabilitiesca/skip_verify)。理解这一点后,你可以直接用 crictl 验证:

bash
rke2 crictl pull 192.168.122.156:30000/library/nginx:1.27
# 排查拉取失败
journalctl -u rke2-server | grep -i "pulling image"
rke2 crictl images | grep nginx

注意事项:registries.yaml 中仓库地址的 key 必须带端口(如 192.168.122.156:30000),与镜像引用中的写法完全一致,否则匹配不上。


第 6 章 etcd 管理与备份恢复

6.1 嵌入式 etcd

RKE2 server 节点默认运行嵌入式 etcd(静态 Pod),多个 server 自动组成 etcd 集群:

server-1 etcd ──2380(raft peer)── server-2 etcd ──2380── server-3 etcd
     │                                │                      │
     └──── 2379 (client) ──── kube-apiserver(本机) ──────────┘
  • etcd 数据目录:/var/lib/rancher/rke2/server/db/etcd/
  • 快照目录:/var/lib/rancher/rke2/server/db/snapshots/
  • 默认监听:127.0.0.1:2379(本机 apiserver 访问)、节点 IP :2380(peer 通信)

查看 etcd 状态:

bash
# 使用 etcd Pod 内的 etcdctl
ETCDCTL_API=3 rke2 kubectl -n kube-system exec etcd-rocky9-vm-04 -- \
  etcdctl --cacert=/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt \
          --cert=/var/lib/rancher/rke2/server/tls/etcd/client.crt \
          --key=/var/lib/rancher/rke2/server/tls/etcd/client.key \
          --endpoints=https://127.0.0.1:2379 \
          endpoint status --cluster -w table

# 成员列表
... etcdctl member list -w table

6.2 快照:save / list / prune

bash
# 手动快照
rke2 etcd-snapshot save --name pre-upgrade-snapshot
# 快照保存在 /var/lib/rancher/rke2/server/db/snapshots/

# 列出快照
rke2 etcd-snapshot list
# 或 etcd-snapshot ls

# 清理旧快照(保留最近 5 份)
rke2 etcd-snapshot prune --snapshot-retention 5

# 删除指定快照
rke2 etcd-snapshot delete --name pre-upgrade-snapshot

定时快照(config.yaml):

yaml
etcd-snapshot-schedule-cron: "0 */6 * * *"   # 每 6 小时
etcd-snapshot-retention: 10                   # 保留 10 份

6.3 S3 快照(异地备份)

yaml
# config.yaml
etcd-s3: true
etcd-s3-endpoint: "s3.example.com"
etcd-s3-bucket: "rke2-etcd-backup"
etcd-s3-access-key: "xxx"
etcd-s3-secret-key: "xxx"
etcd-s3-region: "us-east-1"
etcd-s3-folder: "prod-cluster"
etcd-s3-insecure: true          # 自签名 https 时

手动上传快照到 S3:

bash
rke2 etcd-snapshot save --name manual-s3 \
  --s3 --s3-endpoint=s3.example.com --s3-bucket=rke2-etcd-backup ...

最佳实践:定时本地快照 + S3 异地快照双保险;升级集群前务必手动 etcd-snapshot save

6.4 从快照恢复

场景:整个集群数据损坏或误删,从快照回滚。

步骤(以首节点 .190 为例):

bash
# 1. 停止所有 server 节点的 rke2-server
systemctl stop rke2-server

# 2. 在首节点执行恢复(指定快照文件)
rke2 server --cluster-reset \
  --cluster-reset-restore-path=/var/lib/rancher/rke2/server/db/snapshots/pre-upgrade-snapshot

# 输出提示 "Managed etcd cluster membership has been reset..." 后退出

# 3. 首节点正常启动
systemctl start rke2-server

# 4. 其余 server 节点:删除 etcd 数据目录后重新加入
systemctl stop rke2-server
rm -rf /var/lib/rancher/rke2/server/db/etcd
systemctl start rke2-server

# 5. agent 节点无需操作,自动重连
kubectl get nodes

注意事项--cluster-reset 会把 etcd 集群成员重置为单节点,其余 server 必须删掉本地 etcd 数据再加入,否则会出现成员冲突。

6.5 etcd 仲裁(quorum)丢失恢复思路

etcd 集群 3 节点容忍 1 节点故障;若 2 台以上同时宕机(或数据损坏),剩余节点因无法达成多数派(quorum),rke2-server 全部无法启动,典型报错:

text
etcdserver: request timed out
transport: authentication handshake failed: context deadline exceeded
dial tcp 127.0.0.1:2379: connect: connection refused

恢复思路(详细实战见仓库 k8s-issues/rke2-disaster-recovery-control-plane-quorum-loss.md):

  1. 抢救数据:选一台数据最新的节点,确认其 etcd 数据目录完整(db/etcd/member/snap/db 存在且不太旧)。
  2. 单节点强制重置:在该节点执行 rke2 server --cluster-reset(可带 --cluster-reset-restore-path 指定快照;不指定则用本地现有数据重置为单成员集群)。
  3. 拉起首节点systemctl start rke2-server,验证 kubectl get nodes、关键 workload 是否还在。
  4. 重建其余 control-plane:其余节点 rm -rf /var/lib/rancher/rke2/server/db/etcd 后重新加入。
  5. 修复业务:恢复后检查 Deployment/DaemonSet 状态,必要时重新 rollout。
  6. 复盘加固:落实定时快照 + S3 备份、节点电源/网络冗余、升级前手动快照制度。

经验教训(来自真实案例):quorum 丢失是 K8s 运维的"终极大考",平时没有可验证的备份 = 没有备份。建议每季度演练一次快照恢复。

6.6 常见面试题(本章)

  1. RKE2 的 etcd 部署形态?与 kubeadm 有何异同? 嵌入式静态 Pod;kubeadm 也支持 stacked etcd,但 RKE2 自动管理成员引导。
  2. cluster-reset 的原理? 将 etcd 集群成员列表重置为仅本节点,从快照/现有数据重建单节点集群,其余节点清空数据后加入。
  3. etcd 为什么要求 server 节点数为奇数? Raft 多数派机制,偶数不增加容错能力却增加写入延迟。

第 7 章 升级与维护

7.1 版本与 channel

RKE2 版本格式:v<K8s版本>+rke2r<修订号>,如 v1.35.6+rke2r1

channel说明
stable生产推荐,经过充分验证的次新版本
latest最新版本,适合测试
v1.35锁定到某个 K8s 小版本的通道
testing预发布版本,勿用于生产
bash
# 查看 channel 对应版本
curl -s https://update.rke2.io/v1-release/channels | python3 -m json.tool
# 国内镜像
curl -s https://rancher-mirror.rancher.cn/rke2-release/channels | python3 -m json.tool

注意事项:Kubernetes 升级不可跨小版本(如 v1.33 → v1.35 需先升 v1.34)。

7.2 手动升级

升级顺序:先逐台 server(先升级非首节点亦可,官方推荐先升级首节点),再逐台 agent。

bash
# 1. 升级前快照
rke2 etcd-snapshot save --name before-upgrade-$(date +%F)

# 2. 在一台 server 上执行新版本安装脚本
curl -sfL https://get.rke2.io | INSTALL_RKE2_VERSION="v1.35.7+rke2r1" sh -
# 离线环境:下载新 tar 包后用 INSTALL_RKE2_ARTIFACT_PATH 安装

# 3. 重启服务(安装脚本不会自动重启正在运行的服务)
systemctl restart rke2-server

# 4. 验证后逐台重复
kubectl get nodes -o wide
kubectl -n kube-system get pods

7.3 system-upgrade-controller 自动升级

Rancher 提供 system-upgrade-controller(SUC),通过 Plan CRD 声明式滚动升级集群:

bash
kubectl apply -f https://github.com/rancher/system-upgrade-controller/releases/latest/download/system-upgrade-controller.yaml
yaml
# server 升级 Plan
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: rke2-server-plan
  namespace: system-upgrade
spec:
  concurrency: 1                      # 一次只升级一台
  nodeSelector:
    matchExpressions:
      - { key: node-role.kubernetes.io/control-plane, operator: Exists }
  serviceAccountName: system-upgrade
  cordon: true                        # 升级前 cordon
  upgrade:
    image: rancher/rke2-upgrade
  version: v1.35.7+rke2r1
---
# agent 升级 Plan(channel 方式)
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: rke2-agent-plan
  namespace: system-upgrade
spec:
  concurrency: 2
  nodeSelector:
    matchExpressions:
      - { key: node-role.kubernetes.io/control-plane, operator: DoesNotExist }
  serviceAccountName: system-upgrade
  prepare:
    image: rancher/rke2-upgrade
    args: ["prepare", "rke2-server-plan"]   # 等 server 全部升完
  cordon: true
  upgrade:
    image: rancher/rke2-upgrade
  channel: https://update.rke2.io/v1-release/channels/stable
bash
kubectl -n system-upgrade get plans
kubectl -n system-upgrade get jobs

7.4 证书轮换

RKE2 自动生成的证书默认有效期 1 年。查看与轮换:

bash
# 查看各证书有效期
rke2 certificate rotate --help
for f in /var/lib/rancher/rke2/server/tls/*.crt; do
  echo "== $f"; openssl x509 -in "$f" -noout -enddate 2>/dev/null
done
# 更直接的方式
curl --cacert /var/lib/rancher/rke2/server/tls/server-ca.crt \
  https://127.0.0.1:6443 -v 2>&1 | grep "expire date"

# 轮换全部证书(需停止服务)
systemctl stop rke2-server
rke2 certificate rotate
systemctl start rke2-server
# 每台 server 都要执行;agent 证书由 server 自动签发,重启 rke2-agent 即可

轮换后需重新分发 /etc/rancher/rke2/rke2.yaml(kubeconfig 内嵌证书已变化)。

7.5 节点维护:drain / cordon

bash
# 维护节点(驱逐 Pod,daemonset 除外)
kubectl drain rocky9-vm-05 --ignore-daemonsets --delete-emptydir-data

# 维护操作...
systemctl restart rke2-agent

# 恢复调度
kubectl uncordon rocky9-vm-05

# 仅禁止调度不驱逐
kubectl cordon rocky9-vm-05

7.6 卸载

脚本作用
/usr/bin/rke2-killall.sh杀掉所有 RKE2 相关进程、卸载容器与网络(保留数据)
/usr/bin/rke2-uninstall.sh完整卸载:killall + 删除二进制、数据目录、systemd 单元
bash
# 节点从集群下线
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
kubectl delete node <node>
# 节点上执行
rke2-uninstall.sh        # server/agent 均适用

注意事项rke2-uninstall.sh 会删除 /var/lib/rancher/rke2 全部数据(含 etcd 数据与快照)。server 节点卸载前请确认快照已备份到其他位置。

7.7 常见面试题(本章)

  1. RKE2 升级顺序是什么? 先快照 → 逐台 server → 逐台 agent;不可跨 K8s 小版本。
  2. 证书快过期了怎么办? rke2 certificate rotate + 重启服务 + 重新分发 kubeconfig。
  3. system-upgrade-controller 的并发控制靠什么? concurrency 字段 + prepare 机制保证 server 先于 agent。

第 8 章 网络与内置组件

8.1 默认内置组件一览

组件命名空间作用禁用方式
CoreDNSkube-system集群 DNSdisable: [rke2-coredns]
ingress-nginxkube-systemIngress 控制器disable: [rke2-ingress-nginx]
metrics-serverkube-systemHPA/top 指标disable: [rke2-metrics-server]
servicelb (klipper-lb)kube-system裸机 LoadBalancer(占用节点主机端口)disable: [rke2-servicelb]
cloud-controller-managerkube-system节点生命周期/路由(无云厂商时的 stub)disable-cloud-controller: true
helm-controllerkube-system管理 HelmChart CRD不建议禁用
snapshot-validation / csi 相关kube-system快照 CRD 校验

8.2 helm-controller 与 HelmChart CRD

RKE2 把集群插件做成 HelmChart CRD,由 helm-controller 自动渲染部署。文件位于 /var/lib/rancher/rke2/server/manifests/

自定义内置组件的正确姿势——HelmChartConfig:

yaml
# 例如:修改 ingress-nginx 使用 hostNetwork,并开启指标
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: rke2-ingress-nginx
  namespace: kube-system
spec:
  valuesContent: |-
    controller:
      hostNetwork: true
      metrics:
        enabled: true
      config:
        use-forwarded-headers: "true"
bash
kubectl apply -f ingress-nginx-config.yaml
# helm-controller 会自动重渲染 rke2-ingress-nginx 这个 HelmChart
kubectl -n kube-system get helmchart,helmchartconfig

注意事项:HelmChartConfig 的 name 必须与内置 HelmChart 同名(如 rke2-ingress-nginx),namespace 必须是 kube-system。不要直接改 /var/lib/rancher/rke2/server/manifests/ 下的文件(会被覆盖)——除非你有意覆盖整个 chart(放同名文件进去确实可以"shadow"内置清单,但不推荐,升级时容易踩坑)。

完全自定义组件:在 /var/lib/rancher/rke2/server/manifests/ 放入任意 YAML 或 HelmChart CRD,RKE2 会自动 apply 到集群(类似 kubelet 的 static manifest 机制,适合离线环境的组件部署)。

8.3 CNI 插件切换与 Cilium 集成

切换到 Cilium(config.yaml):

yaml
cni: cilium
# 可选:禁用 kube-proxy,让 Cilium eBPF 接管
# disable-kube-proxy: true

Cilium 的 HelmChartConfig 示例:

yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: rke2-cilium
  namespace: kube-system
spec:
  valuesContent: |-
    kubeProxyReplacement: "true"
    k8sServiceHost: "192.168.122.200"
    k8sServicePort: "6443"
    hubble:
      enabled: true
      relay:
        enabled: true
      ui:
        enabled: true

注意事项:CNI 是集群初始化时决定的,建成后切换 CNI 相当于重建网络(需全部节点清空 CNI 状态),生产环境务必在首节点部署前确定。

8.4 Multus 多网卡

yaml
# config.yaml
cni:
  - multus
  - canal        # 主网络用 canal,multus 负责附加网卡

然后正常创建 NetworkAttachmentDefinition 供 Pod 注解使用:

yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: macvlan-conf
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "type": "macvlan",
      "master": "eth1",
      "mode": "bridge",
      "ipam": { "type": "static", "addresses": [ { "address": "10.10.0.100/24" } ] }
    }

8.5 ServiceLB(klipper-lb)与 MetalLB 的取舍

  • 默认 servicelb 通过在每个节点起 svclb-* Pod 占用主机端口实现 LoadBalancer,适合测试;
  • 生产裸金属建议 disable: [rke2-servicelb],改用 MetalLB(L2/BGP 模式),参见本系列 metaLB 相关教材。

8.6 常见面试题(本章)

  1. 如何修改 RKE2 内置 ingress-nginx 的参数? HelmChartConfig CRD(name 同 chart、namespace kube-system),由 helm-controller 重渲染。
  2. klipper-lb 的实现原理与局限? DaemonSet 占用主机端口 + iptables 转发;端口冲突、无 IP 池管理,生产建议 MetalLB。
  3. RKE2 支持哪些 CNI,如何多网络? canal/calico/cilium/none,配合 multus 实现多网卡。

第 9 章 安全加固

9.1 CIS Profile

yaml
# config.yaml
profile: cis

启用后 RKE2 自动完成:

  • apiserver/controller-manager/scheduler/etcd 按 CIS Benchmark 设置安全参数(如 --profiling=false、审计策略、加密提供者等);
  • 自动应用 PodSecurity 准入(restricted 级别的豁免命名空间配置);
  • 校验系统内核参数(vm.panic_on_oom=0kernel.panic=10kernel.panic_on_oops=1),不满足时启动报错并提示。

前置系统配置(RHEL/Rocky 9):

bash
# 创建 etcd 专用用户(cis profile 要求)
useradd -r -c "etcd user" -s /sbin/nologin -M etcd -U

# 内核参数
cat > /etc/sysctl.d/90-rke2-cis.conf <<EOF
vm.panic_on_oom=0
vm.overcommit_memory=1
kernel.panic=10
kernel.panic_on_oops=1
EOF
sysctl --system

9.2 SELinux 支持

RKE2 是少数原生支持 SELinux enforcing 的发行版:

bash
# RHEL/Rocky 9:保持 SELinux enforcing
getenforce    # Enforcing

# config.yaml 中显式开启(新版默认根据系统状态自动启用)
selinux: true
bash
# 验证容器带正确 SELinux 上下文
ps -eZ | grep containerd | head -5
# 排查 SELinux 拒绝
ausearch -m avc -ts recent

9.3 Pod Security Standards

RKE2(cis profile)默认通过 Pod Security Admission 强制执行策略。手工配置示例:

yaml
# /etc/rancher/rke2/pod-security-admission-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
  - name: PodSecurity
    configuration:
      apiVersion: pod-security.admission.config.k8s.io/v1
      kind: PodSecurityConfiguration
      defaults:
        enforce: "baseline"
        enforce-version: "latest"
        audit: "restricted"
        audit-version: "latest"
        warn: "restricted"
        warn-version: "latest"
      exemptions:
        usernames: []
        runtimeClasses: []
        namespaces:
          - kube-system
          - cattle-system
yaml
# config.yaml 引用
kube-apiserver-arg:
  - "admission-control-config-file=/etc/rancher/rke2/pod-security-admission-config.yaml"

9.4 审计策略

bash
cat > /etc/rancher/rke2/audit-policy.yaml <<'EOF'
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Metadata
    omitStages:
      - RequestReceived
  - level: RequestResponse
    verbs: ["create", "update", "patch", "delete"]
    resources:
      - group: ""
        resources: ["secrets", "configmaps"]
EOF
yaml
# config.yaml
kube-apiserver-arg:
  - "audit-policy-file=/etc/rancher/rke2/audit-policy.yaml"
  - "audit-log-path=/var/lib/rancher/rke2/server/logs/audit.log"
  - "audit-log-maxage=30"
  - "audit-log-maxbackup=10"
  - "audit-log-maxsize=100"

9.5 Secret 静态加密

yaml
# config.yaml(首节点初始化时或之后启用均可)
secrets-encryption: true
bash
# 启用后重写所有 Secret 完成加密
kubectl get secrets --all-namespaces -o json | kubectl replace -f -

# 密钥轮换
rke2 secrets-encrypt rotate     # 需先 stop rke2-server

9.6 FIPS 140-2

RKE2 提供 FIPS 构建版本:Go 二进制使用通过 FIPS 140-2 认证的 BoringCrypto 模块编译。

bash
# 验证二进制是否为 FIPS 构建
rke2 --version
# 启用 FIPS 模式(需操作系统层面也启用 FIPS:fips-mode-setup --enable)
# config.yaml 无需特殊配置,系统层启用后 RKE2 自动使用 FIPS 加密

适用场景:政府、金融等对加密模块有强制认证要求的环境。

9.7 加固清单速查表

项目措施
合规基线profile: cis + 内核参数 + etcd 用户
强制访问控制SELinux enforcing + selinux: true
Pod 准入Pod Security restricted/baseline
审计audit-policy + 日志轮转 + 外发日志系统
数据加密secrets-encryption: true + 定期密钥轮换
传输加密全部组件 TLS(默认)+ FIPS 构建(可选)
网络隔离NetworkPolicy(Calico/Cilium)+ 节点防火墙只放行必要端口
权限RBAC 最小化、禁用匿名访问(默认)、service account token 绑定
镜像私有 Harbor + 镜像扫描(Trivy/Harbor 内置)+ 可信签名

第 10 章 故障排查大全

10.1 排查工具箱

工具命令
服务日志journalctl -u rke2-server -f / journalctl -u rke2-agent -f / journalctl -u rke2-server --since "1 hour ago"
容器运行时rke2 crictl ps -arke2 crictl logs <id>rke2 crictl inspect <id>
Pod 日志kubectl logs -n kube-system <pod>/var/log/pods/
系统日志/var/log/messages(RHEL 系)/ /var/log/syslog(Ubuntu)
静态 Pod 清单/var/lib/rancher/rke2/agent/pod-manifests/
etcd 健康见第 6 章 etcdctl endpoint status
网络ss -lntp(端口监听)、iptables -L -nipvsadm -Ln

10.2 server 无法启动

现象systemctl start rke2-server 卡住或反复重启。

排查步骤:

bash
journalctl -u rke2-server -n 200 --no-pager   # 找 fatal/error 行
ls -lh /var/lib/rancher/rke2/agent/images/    # 离线包是否在
df -h                                          # 磁盘是否满(etcd 敏感)
free -m                                        # 内存是否足够(server 建议 ≥4GB)
常见报错原因解决
failed to validate token ... dial tcp <ip>:9345: connect: no route to host防火墙拦截 9345放行端口(见 10.6),参考 k8s-issues/rke2-master-join-fails-iptables-firewall-blocking.md
critical configuration value mismatch between servers新 server 配置与集群不一致对齐 cluster-cidr/service-cidr/cni/disable,参考 k8s-issues/rke2-master-join-fails-critical-configuration-mismatch.md
etcdserver: request timed outetcd quorum 丢失走 cluster-reset 恢复流程,参考 k8s-issues/rke2-disaster-recovery-control-plane-quorum-loss.md
failed to get CA certstoken 错误或 9345 不通核对 node-token,测试 curl -k https://<server>:9345/cacerts
cis profile 下提示内核参数不达标sysctl 未配置按 9.1 配置内核参数与 etcd 用户

10.3 节点 NotReady

现象kubectl get nodes 显示 NotReady。

排查步骤:

bash
kubectl describe node <node>          # 看 Conditions 与 Events
journalctl -u rke2-agent -n 100       # agent 节点日志
rke2 crictl ps -a | head              # 容器是否拉起
kubectl -n kube-system get pods -o wide | grep <node>   # CNI Pod 是否正常
常见原因特征解决
镜像导入中(新节点)日志反复 pod sandbox not found, retrying耐心等待离线镜像导入完成,参考 k8s-issues/rke2-master-join-notready-image-import-delay.md
CNI 未就绪node 上无 calico/canal Pod查 CNI Pod 日志、镜像是否拉取成功
镜像拉取失败ImagePullBackOff检查 registries.yaml、Harbor 可达性,参考 k8s-issues/rke2-ingress-nginx-controller-ContainerCreating.md
节点证书过期kubelet 日志证书错误重启服务触发重新签发,或 rke2 certificate rotate
磁盘压力DiskPressure 条件清理镜像 rke2 crictl rmi --prune、清理日志

10.4 证书过期

现象:kubectl 报 x509: certificate has expired,kubelet 无法连接 apiserver。

bash
# 确认过期时间
openssl x509 -in /var/lib/rancher/rke2/server/tls/client-admin.crt -noout -enddate

# 轮换(每台 server)
systemctl stop rke2-server
rke2 certificate rotate
systemctl start rke2-server

# agent 节点
systemctl restart rke2-agent

10.5 etcd 健康问题

bash
# 成员状态
ETCDCTL_API=3 kubectl -n kube-system exec -it etcd-<node> -- etcdctl \
  --cacert=/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt \
  --cert=/var/lib/rancher/rke2/server/tls/etcd/client.crt \
  --key=/var/lib/rancher/rke2/server/tls/etcd/client.key \
  --endpoints=https://127.0.0.1:2379 endpoint status --cluster -w table

# 关注:DB SIZE、RAFT TERM 是否一致、IS LEADER
# 碎片整理(DB 膨胀时)
... etcdctl defrag --cluster
# 告警检查
... etcdctl alarm list

NOSPACE 告警:etcd 达到 quota(默认 2GB)→ 先 compact + defrag,或调大 quota-backend-bytes

10.6 加入失败:防火墙端口清单

RKE2 节点间所需端口(firewalld/iptables 必须放行):

端口协议方向用途
9345TCPagent/server → serverRKE2 supervisor/注册
6443TCP所有 → serverkube-apiserver
10250TCPserver ↔ agentkubelet API(metrics/logs/exec)
2379TCPserver ↔ serveretcd client
2380TCPserver ↔ serveretcd peer
2381TCPserveretcd metrics
8472UDP所有节点间Canal/Flannel VXLAN
51820UDP所有节点间WireGuard(Calico/Cilium 加密)
179TCP所有节点间Calico BGP
9099TCP节点本机Calico 健康检查
5001/5473TCP节点间嵌入式 registry/Spegel、Calico Typha
bash
# firewalld 放行示例(Rocky 9)
firewall-cmd --permanent --add-port={9345,6443,10250,2379,2380,2381}/tcp
firewall-cmd --permanent --add-port={8472,51820}/udp
firewall-cmd --reload

# iptables 快速验证:先临时放开判断是否为防火墙问题
iptables -I INPUT -j ACCEPT   # 测试用,验证后务必恢复策略

真实案例k8s-issues/rke2-master-join-fails-iptables-firewall-blocking.md 完整记录了"9345 no route to host → iptables 默认 DROP → 放行端口后成功加入"的排查全过程。

10.7 containerd / crictl 排查

bash
# RKE2 的 containerd socket(不是默认的 /run/containerd/containerd.sock!)
rke2 crictl ps -a                              # 包装命令自动指定 socket
# 手动方式
export CONTAINER_RUNTIME_ENDPOINT=unix:///run/k3s/containerd/containerd.sock
crictl ps

# 镜像列表与清理
rke2 crictl images
rke2 crictl rmi --prune                        # 清理无用镜像

# 查看容器日志(静态 Pod 故障时 kubectl 不可用,靠这个)
rke2 crictl logs <container-id>

# containerd 命名空间
rke2 ctr namespaces ls                         # k8s.io
rke2 ctr -n k8s.io containers ls

10.8 kubelet 证书与 token 问题

现象原因解决
Unauthorized (apiserver 日志)节点 token 失效/被轮换用 server 上当前 node-token 更新 agent 配置并重启
kubelet 报 certificate signed by unknown authorityCA 被重建后 agent 未更新删除 /var/lib/rancher/rke2/agent/ 下 kubelet 证书与 client kubeconfig,重启 agent 重新引导
节点重复注册/名字冲突node-name 变化kubectl delete node <旧名>,保持 node-name 稳定

10.9 日志位置速查

内容位置
rke2-server/agent 主日志journalctl -u rke2-server / -u rke2-agent
Pod 标准输出/var/log/pods/<namespace>_<pod>_<uid>/
审计日志/var/lib/rancher/rke2/server/logs/audit.log(需启用)
系统日志RHEL/Rocky:/var/log/messages;Ubuntu:/var/log/syslog
静态 Pod 容器日志rke2 crictl logs/var/log/pods/kube-system_...
镜像导入/启动阶段journalctl -u rke2-server 中的 importing images

10.10 通用排障决策树

集群异常
├─ kubectl 不可用?
│   ├─ apiserver 不通 → 检查 6443、rke2-server 状态、证书
│   └─ etcd 报错 → endpoint status → quorum? → cluster-reset
├─ 节点 NotReady?
│   ├─ 新节点 → 等镜像导入(crictl images 观察)
│   ├─ CNI Pod 异常 → describe pod / 镜像拉取
│   └─ kubelet 异常 → journalctl -u rke2-agent
├─ Pod 异常?
│   ├─ ImagePullBackOff → registries.yaml / Harbor
│   ├─ ContainerCreating → CNI、挂载、镜像
│   └─ CrashLoopBackOff → logs / describe events
└─ 网络不通?
    ├─ Pod 间不通 → CNI、8472/51820 端口、NetworkPolicy
    └─ Service 不通 → kube-proxy(ipvsadm/iptables)、endpoints

第 11 章 常见面试题(综合)

  1. RKE2 与 RKE1、k3s 的核心区别是什么? RKE2 使用 containerd + 静态 Pod 控制平面,内置 CIS/FIPS 安全能力;RKE1 依赖 Docker;k3s 是裁剪版单二进制面向边缘。

  2. RKE2 控制平面组件是如何运行的?如何查看它们? 以静态 Pod 形式由 kubelet 管理,清单在 /var/lib/rancher/rke2/agent/pod-manifests/,用 rke2 crictl pskubectl -n kube-system get pods 查看。

  3. RKE2 的 9345 端口是干什么的?与 6443 有什么区别? 9345 是 supervisor/注册端口(节点加入、CA 分发、引导数据),6443 是 Kubernetes API。新节点先连 9345 验证 token 拿 CA,再与 6443 建立正式通信。

  4. HA 场景下 agent 的 server 地址应该填什么?为什么? 固定注册地址(VIP/LB),而非某台 server 的 IP;否则该 server 宕机后新节点无法加入、kubectl 不可达。

  5. tls-san 忘记配置 VIP,事后如何补救? 在所有 server 的 config.yaml 补加 tls-san,逐台重启 rke2-server 触发 apiserver 证书重签;旧 kubeconfig 需重新分发。

  6. registries.yaml 与 system-default-registry 的区别? 前者作用于全部镜像的仓库访问(mirror/auth/TLS);后者只把 RKE2 系统组件镜像的前缀改为私有仓库。离线环境两者配合。

  7. RKE2 如何做 etcd 备份与恢复?rke2 etcd-snapshot save/list/prune + 定时 cron + S3;恢复用 rke2 server --cluster-reset --cluster-reset-restore-path=...,其余 server 清 etcd 数据后重新加入。

  8. etcd quorum 丢失如何恢复? 选数据最新节点 --cluster-reset 重置为单成员集群拉起,其余节点删除 /var/lib/rancher/rke2/server/db/etcd 再加入。参见 k8s-issues/rke2-disaster-recovery-control-plane-quorum-loss.md

  9. 如何修改内置 ingress-nginx 的参数?直接改 manifests 文件可以吗? 用 HelmChartConfig CRD(kube-system 命名空间、与 HelmChart 同名);直接改 /var/lib/rancher/rke2/server/manifests/ 会被覆盖。

  10. RKE2 升级的正确顺序与注意事项? 快照 → 逐台 server → 逐台 agent;不可跨 K8s 小版本;离线环境提前准备新版本 tar 包;可用 system-upgrade-controller 自动化。

  11. 证书有效期多久?如何轮换? 默认 1 年;systemctl stop rke2-server && rke2 certificate rotate && systemctl start rke2-server,agent 重启即重新签发。

  12. 新增 server 报 critical configuration value mismatch 是什么原因? 新节点 config.yaml 中 cluster-cidr/service-cidr/cni/disable 等与既有集群不一致,必须完全对齐。参见 k8s-issues/rke2-master-join-fails-critical-configuration-mismatch.md

  13. RKE2 默认容器运行时 socket 在哪里?为什么 crictl 直接连不上?/run/k3s/containerd/containerd.sock(RKE2 与 k3s 共用路径),不是 containerd 默认路径;用 rke2 crictl 包装命令或设置 CONTAINER_RUNTIME_ENDPOINT

  14. CIS profile 启用前后的准备工作? 创建 etcd 用户、配置内核参数(panic/overcommit)、评估 Pod Security 对存量 workload 的影响。

  15. 节点维护的标准流程?kubectl drain --ignore-daemonsets --delete-emptydir-data → 维护 → kubectl uncordon;下线节点还需 kubectl delete node + rke2-uninstall.sh


附录 A 本仓库相关参考资料索引

资料内容
rke2/README.mdRKE2 v1.35.6 完整部署文档(离线源 + Harbor)
rke2/install-server.sh / rke2/install-agent.sh自动化安装脚本
rke2/server-config.yaml / rke2/agent-config.yaml真实配置样例
rke2/registries.yamlHarbor HTTP 仓库配置样例
k8s-issues/rke2-master-join-fails-iptables-firewall-blocking.md防火墙导致 master 加入失败案例
k8s-issues/rke2-master-join-fails-critical-configuration-mismatch.md配置不一致导致加入失败案例
k8s-issues/rke2-master-join-notready-image-import-delay.md镜像导入耗时导致 NotReady 案例
k8s-issues/rke2-disaster-recovery-control-plane-quorum-loss.md三 control-plane 全挂后灾后恢复实录
k8s-issues/rke2-ingress-nginx-controller-ContainerCreating.mdingress-nginx Pod 无法创建排查
k8s-issues/rke2-node-addition-operation-manual.md节点添加操作手册

附录 B 常用命令速查

bash
# 服务管理
systemctl enable rke2-server --now
journalctl -u rke2-server -f

# 集群访问
export KUBECONFIG=/etc/rancher/rke2/rke2.yaml
kubectl get nodes -o wide

# etcd
rke2 etcd-snapshot save --name snap-$(date +%F)
rke2 etcd-snapshot list
rke2 server --cluster-reset --cluster-reset-restore-path=<快照路径>

# 证书
rke2 certificate rotate

# 容器
rke2 crictl ps -a
rke2 crictl rmi --prune

# 卸载
rke2-killall.sh
rke2-uninstall.sh

结语:RKE2 的学习曲线可以概括为"安装五分钟,精通三个月"。把本部分的环境亲手搭一遍(建议至少 3 server + 2 agent 的 HA 拓扑)、把每个故障案例复现一次,你对生产级 Kubernetes 发行版的理解将超过绝大多数面试者。下一部分我们将进入 K8s 辅助工具(Helm、Kustomize、Rancher、监控日志栈)的世界。