主题
Rancher on RKE2 部署运维手册:cert-manager 自签证书、内外网域名分离、密码重置
适用场景:RKE2 集群上的 Rancher 使用自签 CA 证书(cert-manager 签发),外网经 frp 隧道访问 UI,内网托管集群经内网 DNS 直连。
1. 总体架构
外网 UI:浏览器 → https://ai-ear.cn:30443
→ 公网服务器 frps:30443(云安全组需放行)
→ frp 隧道(工作站 frpc:30443 → 192.168.122.20:443)
→ 集群 ingress-nginx(TLS 终止,出示 CN=ai-ear.cn 自签证书)
→ Rancher pods(3 副本)
内网部署:VM → https://ai-ear.cn(443)
→ libvirt dnsmasq 静态解析 → 192.168.122.20/21/22
→ 集群 ingress-nginx → Rancher podsRancher 关键配置:hostname=ai-ear.cn、privateCA=true、server-url=https://ai-ear.cn。
2. cert-manager 安装与自签 CA
bash
# chart 来自私有 OCI 仓库(HTTP 需 --plain-http)
helm pull oci://192.168.122.156:30000/cert-manager/cert-manager --version v1.20.3 --plain-http
helm install cert-manager ./cert-manager-v1.20.3.tgz \
--namespace cert-manager --create-namespace \
--set crds.enabled=true \
--set global.imageRegistry=192.168.122.156:30000自签 CA 链(selfsigned → 根 CA → CA Issuer → 服务证书):
yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata: { name: selfsigned-issuer }
spec: { selfSigned: {} }
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata: { name: rancher-root-ca, namespace: cert-manager }
spec:
isCA: true
commonName: rancher-ai-ear-root-ca
secretName: rancher-root-ca
duration: 87600h # 10 年
renewBefore: 720h
privateKey: { algorithm: ECDSA, size: 256 }
issuerRef: { name: selfsigned-issuer, kind: ClusterIssuer }
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata: { name: rancher-ca-issuer }
spec: { ca: { secretName: rancher-root-ca } }
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata: { name: tls-rancher-ingress, namespace: cattle-system }
spec:
secretName: tls-rancher-ingress # 与 Rancher ingress 约定同名,直接接管
commonName: ai-ear.cn
dnsNames: [ai-ear.cn, rancher.ai-ear.cn]
duration: 2160h
renewBefore: 360h
privateKey: { algorithm: ECDSA, size: 256 }
issuerRef: { name: rancher-ca-issuer, kind: ClusterIssuer }3. Rancher 开启 privateCA 的必做项
--set privateCA=true 后 chart 会挂载 secret tls-ca(key 必须为 cacerts.pem),缺失则 Pod 报 FailedMount: secret "tls-ca" not found:
bash
kubectl -n cert-manager get secret rancher-root-ca -o jsonpath='{.data.tls\.crt}' | base64 -d > rancher-root-ca.crt
kubectl -n cattle-system create secret generic tls-ca --from-file=cacerts.pem=rancher-root-ca.crt开启后 /cacerts 端点下发根 CA,新节点注册使用 --ca-checksum。
4. 内外网域名分离
server-url 指向内网地址(agent 回连、注册命令均使用):
bashkubectl patch settings.management.cattle.io server-url \ --type merge -p '{"value":"https://ai-ear.cn"}'内网 DNS 集中下发(libvirt dnsmasq,热生效+持久化,新 VM 免配置):
bashfor ip in 192.168.122.20 192.168.122.21 192.168.122.22; do virsh -c qemu:///system net-update default add dns-host \ "<host ip='$ip'><hostname>ai-ear.cn</hostname></host>" --live --config done⚠️ 坑:静态解析对 libvirt 宿主机本机同样生效(systemd-resolved 会转发查询到 192.168.122.1),导致宿主机访问公网
ai-ear.cn站点走错路径。修复:宿主机/etc/hosts固定公网 IP(files 优先级高于 DNS):bashecho "8.153.84.140 ai-ear.cn" | sudo tee -a /etc/hosts⚠️ 坑:NodePort 直连不能作为入口——直连 rancher NodePort 时 TLS 出示的是 dynamiclistener 内置证书(
CN=dynamic,与 SNI 无关),ingress 证书只在 ingress-nginx 层出示,隧道必须指向节点 443。
5. Chrome 证书警告处理
自签 CA 不在系统信任库,报 ERR_CERT_AUTHORITY_INVALID 属预期。临时「高级 → 继续访问」;彻底解决:将根 CA(rancher-root-ca.crt)导入客户端信任库:
bash
# Rocky/RHEL
sudo cp rancher-root-ca.crt /etc/pki/ca-trust/source/anchors/ && sudo update-ca-trust
# Ubuntu/Debian
sudo cp rancher-root-ca.crt /usr/local/share/ca-certificates/ && sudo update-ca-certificates
# Windows:双击 → 安装证书 → 受信任的根证书颁发机构;macOS:钥匙串 → 始终信任根 CA 有效期 10 年,导入一次即可;服务证书由 cert-manager 自动续期。
6. admin 密码重置
bootstrap 引导密码失效的常见根因:admin 用户对象 password 字段为空(引导流程异常)。CATTLE_BOOTSTRAP_PASSWORD 环境变量方式对此场景无效,直接写入 bcrypt 哈希:
bash
# 找到 admin 用户(username=xxx
kubectl get users.management.cattle.io -o json | \
python3 -c "import json,sys; [print(u['metadata']['name'], u.get('username')) for u in json.load(sys.stdin)['items']]"
NEWPW=$(openssl rand -hex 12)
HASH=$(htpasswd -bnBC 10 "" "$NEWPW" | tr -d ':\n') # 无 htpasswd 则 dnf install -y httpd-tools
kubectl patch users.management.cattle.io <admin用户名> \
--type merge -p "{\"password\":\"$HASH\",\"mustChangePassword\":true}"
# 验证(HTTP 200 即成功)
curl -sk --cacert rancher-root-ca.crt -X POST \
"https://ai-ear.cn/v3-public/localProviders/local?action=login" \
-H "Content-Type: application/json" \
-d "{\"username\":\"admin\",\"password\":\"$NEWPW\"}" -o /dev/null -w "%{http_code}\n"mustChangePassword=xxx UI 强制改密。若曾注入 CATTLE_BOOTSTRAP_PASSWORD 环境变量,事后务必移除(kubectl set env deploy/rancher -n cattle-system CATTLE_BOOTSTRAP_PASSWORD-`),否则每次重启都会再次重置密码。
7. 验证清单
| 项 | 命令 | 预期 |
|---|---|---|
| 证书 | echo | openssl s_client -connect <节点IP>:443 -servername ai-ear.cn 2>/dev/null | openssl x509 -noout -subject | CN=ai-ear.cn |
| 内网 | 节点上 curl --cacert rancher-root-ca.crt https://ai-ear.cn/healthz | HTTP 200,remote_ip 为集群节点 |
| 外网 | curl --cacert rancher-root-ca.crt https://ai-ear.cn:30443/healthz | HTTP 200 |
| server-url | kubectl get settings.management.cattle.io server-url | https://ai-ear.cn |
| 下游 agent | Rancher 管理对象 Connected/Ready/AgentDeployed | 全 True |