在 Proxmox VE 上以 UPI + platform: none 安装 OpenShift 4.18:单网桥、单网段 方案,所有 VM 仅连接 vmbr0(10.10.10.0/24),无需 NAT 或第二块网桥。
前置条件: PVE 与 Ceph 已按 上一篇 PVE 部署指南 完成。
本文采用单桥单网段方案;所有 VM 单网卡连接 vmbr0。
1. 概述与规划 UPI + platform: none
项目
值
集群名
lab-ocp
baseDomain
example.com(须与 DNS 规划一致)
API
https://api.lab-ocp.example.com:6443
PVE
root@10.10.10.41,ssh -i deploy-key.pem root@10.10.10.41
Helper VM(§6 安装,§7 配置)
10.10.10.42(VMID 100);ssh -i deploy-key.pem root@10.10.10.42
OCP 节点(Bootstrap/Master/Worker)
10.10.10.43–.51(单网卡 vmbr0);ssh -i deploy-key.pem core@10.10.10.$((VMID-67))
企业代理
http://10.10.10.254:8080(CONNECT 隧道,无需额外 CA)
节点引导方式:
角色
引导方式
Bootstrap(110)
全程 Live PXE ,bootstrap-complete 后删除;不需要 coreos-installer
Master / Worker(111–118)
Live PXE 仅作安装介质 → coreos-installer 写入磁盘 → PVE 改 boot order 从磁盘启动(§10、§11)
Live 环境下存在 /run/ostree-live,MCO firstboot 无法完成 rpm-ostree 写盘,crio/kubelet 起不来。不要 让 Master/Worker 长期停在 Live 上运行。
2. 阶段 0 — 前置检查 2.1 硬件与 PVE 状态 1 2 ssh -i deploy-key.pem root@10.10.10.41 "pveversion; pvesm status; ceph -s"
2.2 网络连通性 1 ssh -i deploy-key.pem root@10.10.10.41 "curl -x http://10.10.10.254:8080 -I https://access.redhat.com"
2.3 Red Hat 账号
1 2 3 4 5 6 7 ssh-keygen -y -f deploy-key.pem > deploy-key.pub cat deploy-key.pubssh -i deploy-key.pem root@10.10.10.41 hostname ssh -i deploy-key.pem root@10.10.10.42 hostname
2.4 验收 1 2 3 4 5 6 7 8 9 10 ssh -i deploy-key.pem root@10.10.10.41 " echo '--- PVE ---' pveversion | head -1 pvesm status | grep vm-storage ceph -s | grep HEALTH curl -sS -o /dev/null -w 'corp-proxy: %{http_code}\n' -x http://10.10.10.254:8080 --connect-timeout 10 -I https://access.redhat.com " test -f deploy-key.pem && ssh-keygen -y -f deploy-key.pem >/dev/null && echo 'sshKey: OK' test -f pull-secret.txt 2>/dev/null && echo 'pull-secret: OK' || echo 'pull-secret: 待下载'
预期输出:
1 2 3 4 5 6 pve-manager/9.2.4/... # PVE 版本 vm-storage ... active # 存储池可用 HEALTH_OK # Ceph 健康 corp-proxy: 200 # 或 301/302,非 000/超时 sshKey: OK pull-secret: OK # 或「待下载」
3. 阶段 1 — 下载软件
在可访问 Red Hat 官网的工作站 上执行。所有文件版本须与 OCP 4.18.19 一致。
3.1 下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 OCP_VER=4.18.19 BASE=https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/${OCP_VER} mkdir -p ocp-artifacts && cd ocp-artifactscurl -LO ${BASE} /openshift-install-linux-${OCP_VER} .tar.gz curl -LO ${BASE} /openshift-client-linux-${OCP_VER} .tar.gz tar xzf openshift-install-linux-${OCP_VER} .tar.gz openshift-install && chmod +x openshift-install ./openshift-install coreos print-stream-json > rhcos-stream.json KERNEL_URL=$(python3 -c 'import json; d=json.load(open("rhcos-stream.json")); p=d["architectures"]["x86_64"]["artifacts"]["metal"]["formats"]["pxe"]; print(p["kernel"]["location"])' ) INITRD_URL=$(python3 -c 'import json; d=json.load(open("rhcos-stream.json")); p=d["architectures"]["x86_64"]["artifacts"]["metal"]["formats"]["pxe"]; print(p["initramfs"]["location"])' ) ROOTFS_URL=$(python3 -c 'import json; d=json.load(open("rhcos-stream.json")); p=d["architectures"]["x86_64"]["artifacts"]["metal"]["formats"]["pxe"]; print(p["rootfs"]["location"])' ) echo "KERNEL_URL=$KERNEL_URL " echo "ROOTFS_URL=$ROOTFS_URL " curl -L -o rhcos-live-kernel-x86_64 "$KERNEL_URL " curl -L -o rhcos-live-initramfs.x86_64.img "$INITRD_URL " curl -L -o rhcos-live-rootfs.x86_64.img "$ROOTFS_URL "
3.2 上传到 PVE 1 2 3 4 5 ISO_DIR="/var/lib/vz/template/iso" scp -i deploy-key.pem rhel-9.8-x86_64-boot.iso \ rhcos-live-kernel-x86_64 rhcos-live-initramfs.x86_64.img rhcos-live-rootfs.x86_64.img \ root@10.10.10.41:${ISO_DIR} /
3.3 验收(进入阶段 2 前) 1 2 3 4 5 6 7 ssh -i deploy-key.pem root@10.10.10.41 ' ISO=/var/lib/vz/template/iso for f in rhcos-live-kernel-x86_64 rhcos-live-initramfs.x86_64.img rhcos-live-rootfs.x86_64.img rhel-9.8-x86_64-boot.iso; do test -f $ISO/$f && echo "OK $f" || echo "MISSING $f" done '
预期输出:
1 2 3 4 OK rhcos-live-kernel-x86_64 OK rhcos-live-initramfs.x86_64.img OK rhcos-live-rootfs.x86_64.img OK rhel-9.8-x86_64-boot.iso
4. 阶段 2 — PVE 准备
PVE 安装与 Ceph 存储 见 A1_HP_DL380部署PVE.md(已完成可跳过)。本节仅确认 vmbr0 可用并 上传 ISO (本方案不需要 vmbr1 / NAT)。
4.1 网段规划(CIDR)
CIDR
类型
配置位置
用途
10.10.10.0/24
Machine Network
install-config.yaml
所有 VM 单网卡 vmbr0;网关 10.10.10.1;HAProxy 后端
172.28.0.0/16 + hostPrefix: 23
Cluster Network
install-config.yaml
Pod Overlay(OVN 分配)
172.29.0.0/16
Service Network
install-config.yaml
Kubernetes Service ClusterIP
网卡分工(所有 VM 单网卡):
组件
接口
桥接
地址示例
网关
用途
PVE
—
vmbr0
10.10.10.41/24
10.10.10.1
宿主机管理
Helper / OCP 节点
ens18
vmbr0
10.10.10.42/24(Helper)
10.10.10.1
DNS、HAProxy、API 后端、节点 node-ip;出站经企业代理
IP 分配( 10.10.10.0/24):
末段
用途
.41
PVE
.42
Helper(VM 100)
.43
Bootstrap(VM 110,临时)
.44–.46
Master(VM 111–113)
.47–.51
Worker(VM 114–118)
.52–.62
预留
IP 公式(OCP 节点): 10.10.10.$((VMID - 67))(110→.43,118→.51)。Helper 固定 .42。
4.2 确认 vmbr0(无需 vmbr1) 本方案不创建 vmbr1,不配置 NAT。所有 VM 仅接入 vmbr0,经网关 10.10.10.1 访问企业代理与外网。
1 2 3 ip -br addr show vmbr0 ip route | grep default
4.3 PVE 防火墙放行(如已启用) 确认内网 VM 所需端口不被 PVE 防火墙阻断(按实际策略调整)。
4.4 验收(进入阶段 3 前) 1 2 3 echo '--- vmbr0 ---' && ip -br addr show vmbr0echo '--- ISO ---' && ls -lh /var/lib/vz/template/iso/rhcos-live-kernel-x86_64
预期输出:
1 2 3 4 5 --- vmbr0 --- vmbr0 UP 10.10.10.41/24 ... --- ISO --- -rw-r--r-- 1 root root ... /var/lib/vz/template/iso/rhcos-live-kernel-x86_64
5. 阶段 3 — 创建 VM
PVE 规则: VMID 必须 ≥ 100。OCP 节点 IP 公式 10.10.10.$((VMID-67))(110→.43)。所有 VM 单网卡 net0→vmbr0。
5.1 IP 与 VMID 分配
VMID
IP
主机名
角色
—
10.10.10.41
pve-host-1
PVE Host
100
10.10.10.42
ocp-helper-node
Helper
110
10.10.10.43
ocp-bootstrap
Bootstrap(临时)
111
10.10.10.44
master-111
Master
112
10.10.10.45
master-112
Master
113
10.10.10.46
master-113
Master
114
10.10.10.47
worker-114
Worker
115
10.10.10.48
worker-115
Worker
116
10.10.10.49
worker-116
Worker
117
10.10.10.50
worker-117
Worker
118
10.10.10.51
worker-118
Worker
5.2 仅重装 Helper(可选) 若 OCP 节点 VM 已存在、只需重建 VM 100,在 PVE 上执行:
1 2 3 4 5 6 qm stop 100 2>/dev/null qm destroy 100 lvremove -f /dev/vm-storage/vm-100-disk-0 2>/dev/null || true ls /dev/vm-storage/vm-100-disk-0 2>/dev/null && echo 'WARN: 旧盘仍在,请先 lvremove' || echo 'OK: 无残留卷'
5.3 创建步骤 VM 100(Helper,空壳): 单网卡 + RHEL ISO + boot order。
1 2 3 4 5 6 7 qm create 100 --name ocp-helper-node --memory 16384 --cores 4 --cpu host \ --scsihw virtio-scsi-pci --agent enabled=1 --ostype l26 \ --net0 virtio,bridge=vmbr0 \ --ide2 "local:iso/rhel-9.8-x86_64-boot.iso,media=cdrom" --boot 'order=ide2;scsi0' lvcreate -V 120G -T vm-storage/data -n vm-100-disk-0 qm set 100 --scsi0 vm-storage:vm-100-disk-0,size=120G
OCP 节点(Bootstrap/Master/Worker): 每台 VM 三步创建,单网卡 vmbr0:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 qm create 110 --name ocp-bootstrap --memory 16384 --cores 8 --cpu host \ --scsihw virtio-scsi-pci --agent enabled=0 --ostype l26 \ --net0 virtio,bridge=vmbr0 --boot order=net0 lvcreate -V 100G -T vm-storage/data -n vm-110-disk-0 qm set 110 --scsi0 vm-storage:vm-110-disk-0,size=100G for i in 111 112 113; do qm create $i --name master-$i --memory 16384 --cores 8 --cpu host \ --scsihw virtio-scsi-pci --agent enabled=0 --ostype l26 \ --net0 virtio,bridge=vmbr0 --boot order=net0 lvcreate -V 80G -T vm-storage/data -n vm-$i -disk-0 qm set $i --scsi0 vm-storage:vm-$i -disk-0,size=80G done for i in 114 115 116 117 118; do qm create $i --name worker-$i --memory 32768 --cores 16 --cpu host \ --scsihw virtio-scsi-pci --agent enabled=0 --ostype l26 \ --net0 virtio,bridge=vmbr0 --boot order=net0 lvcreate -V 160G -T vm-storage/data -n vm-$i -disk-0 qm set $i --scsi0 vm-storage:vm-$i -disk-0,size=160G done
5.4 验收(进入阶段 4 前) 1 2 3 4 5 6 qm list echo '--- VM 100 nets ---' && qm config 100 | grep ^netecho '--- VM 111 nets ---' && qm config 111 | grep ^netecho '--- VM 110 nets ---' && qm config 110 | grep ^netecho '--- count ---' && qm list | grep -cE '100|110|111|112|113|114|115|116|117|118'
预期输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 VMID NAME STATUS MEM(MB) BOOTDISK(GB) PID 100 ocp-helper-node stopped 16384 120.00 0 110 ocp-bootstrap stopped 16384 100.00 0 111 master-111 stopped 16384 80.00 0 ...(112–118 同理,均为 stopped) --- VM 100 nets --- net0: virtio=...,bridge=vmbr0 --- VM 111 nets --- net0: virtio=...,bridge=vmbr0 --- VM 110 nets --- net0: virtio=...,bridge=vmbr0 --- count --- 10
6. 阶段 4 — 安装 Helper 6.1 启动并安装
6.2 安装参数
阶段
操作
Boot 菜单
直接选择安装,进入到图形化配置界面。
Network
ens18 :10.10.10.42/24,网关 10.10.10.1,DNS 10.10.10.3
Hostname
ocp-helper-node.lab-ocp.example.com(或短名 ocp-helper-node)
Software
登录redhat账号的时候,需要配置代理,注册账号成功后,需要等很长一段时间,installation source的cdn才会变成可操作按钮,然后选择Minimal Install。
Root
在 SSH key 栏粘贴 deploy-key.pub可不设置 root 密码
6.3 弹出安装 ISO 1 2 3 qm set 100 --ide2 none qm stop 100 && qm start 100
6.4 SSH 公钥 本方案统一使用 deploy-key.pem / deploy-key.pub。PVE、Helper、OCP 节点 均通过公钥登录。工作站上:
1 2 3 ssh -i deploy-key.pem root@10.10.10.41 ssh -i deploy-key.pem root@10.10.10.42 ssh -i deploy-key.pem core@10.10.10.44
Helper 安装时: 在 RHEL 安装界面 Root Password 步骤的 SSH key 栏,粘贴 deploy-key.pub 全文即可。PVE 上的公钥应在部署前已配置完成。
6.5 注册 Red Hat(需代理) 1 2 3 4 subscription-manager config --server.proxy_hostname=10.10.10.254 --server.proxy_port=8080 subscription-manager register --username=<REDHAT_USER> --password='<REDHAT_PASS>' subscription-manager attach --auto
6.6 验收 1 2 3 4 5 6 7 ssh -i deploy-key.pem root@10.10.10.42 " echo '--- IPs ---' ip -4 addr show ens18 | grep inet echo '--- RH sub ---' subscription-manager status 2>/dev/null | grep -E 'Overall|Status' "
预期输出:
1 2 3 4 5 --- IPs --- inet 10.10.10.42/24 ... --- RH sub --- Overall Status: Current
7. 阶段 5 — 配置 Helper 7.0 配置上游 DNS(可选)
若组织内有集中 DNS,将 api.lab-ocp.example.com、api-int.lab-ocp.example.com、*.apps.lab-ocp.example.com 解析到 Helper(10.10.10.42)即可。 实验环境可仅依赖 Helper 上的 BIND(§7.4),工作站将 DNS 指向 10.10.10.42 或配置 dig @10.10.10.42。
7.1 安装软件包 1 ssh -i deploy-key.pem root@10.10.10.42
1 2 3 4 5 6 7 8 9 export http_proxy=http://10.10.10.254:8080export https_proxy=http://10.10.10.254:8080dnf install -y bind bind-utils haproxy nginx firewalld jq policycoreutils-python-utils unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXYmkdir -p /var/www/html/{rhcos,ignition}
7.2 上传 OCP 工具与 RHCOS 文件 1 2 3 4 5 6 scp -i deploy-key.pem openshift-install-linux-4.18.19.tar.gz openshift-client-linux-4.18.19.tar.gz \ root@10.10.10.42:/root/ scp -i deploy-key.pem rhcos-live-kernel-x86_64 rhcos-live-initramfs.x86_64.img rhcos-live-rootfs.x86_64.img \ root@10.10.10.42:/var/www/html/rhcos/
1 2 3 4 restorecon -Rv /var/www/html chmod 755 /var/www/html /var/www/html/rhcos /var/www/html/ignitionls -laZ /var/www/html/rhcos/
1 2 3 4 5 6 cd /roottar xzf openshift-install-linux-4.18.19.tar.gz -C /usr/local/bin/ tar xzf openshift-client-linux-4.18.19.tar.gz -C /usr/local/bin/ chmod +x /usr/local/bin/openshift-install /usr/local/bin/ococ version
7.3 防火墙 1 2 3 4 5 6 7 8 9 10 11 systemctl enable --now firewalld firewall-cmd --permanent --add-service=dns firewall-cmd --permanent --add-port=6443/tcp firewall-cmd --permanent --add-port=22623/tcp firewall-cmd --permanent --add-port=80/tcp firewall-cmd --permanent --add-port=443/tcp firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --reload firewall-cmd --list-all
7.4 配置 BIND 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 cat > /etc/named.conf << 'EOF' options { listen-on port 53 { 127.0.0.1; 10.10.10.42; }; directory "/var/named" ; allow-query { any; }; allow-query-cache { any; }; recursion yes ; forwarders { 10.10.10.3; }; forward first; dnssec-enable no; dnssec-validation no; }; zone "lab-ocp.example.com" IN { type master; file "lab-ocp.example.com.zone" ; }; zone "lab.local" IN { type master; file "lab.local.zone" ; }; zone "10.10.10.in-addr.arpa" IN { type master; file "10.10.10.zone" ; }; EOF cat > /var/named/lab-ocp.example.com.zone << 'EOF' $TTL 300@ IN SOA ocp-helper-node. admin.lab-ocp.example.com. ( 2026071801 ; serial 3600 ; refresh 600 ; retry 86400 ; expire 300 ) ; minimum IN NS ocp-helper-node. ocp-helper-node IN A 10.10.10.42 api IN A 10.10.10.42 api-int IN A 10.10.10.42 *.apps IN A 10.10.10.42 EOF cat > /var/named/lab.local.zone << 'EOF' $TTL 1h@ IN SOA ocp-helper-node.lab.local. admin.lab.local. ( 2026071802 ; serial 1h ; refresh 30m ; retry 7d ; expire 5m ; minimum ) @ IN NS ocp-helper-node.lab.local. ocp-helper-node IN A 10.10.10.42 helper-node IN CNAME ocp-helper-node ocp-bootstrap IN A 10.10.10.43 bootstrap IN CNAME ocp-bootstrap master-111 IN A 10.10.10.44 master-111 IN CNAME master-111 master-112 IN A 10.10.10.45 master-112 IN CNAME master-112 master-113 IN A 10.10.10.46 master-113 IN CNAME master-113 worker-114 IN A 10.10.10.47 worker-114 IN CNAME worker-114 worker-115 IN A 10.10.10.48 worker-115 IN CNAME worker-115 worker-116 IN A 10.10.10.49 worker-116 IN CNAME worker-116 worker-117 IN A 10.10.10.50 worker-117 IN CNAME worker-117 worker-118 IN A 10.10.10.51 worker-118 IN CNAME worker-118 api IN A 10.10.10.42 api-int IN A 10.10.10.42 *.apps IN A 10.10.10.42 EOF cat > /var/named/10.10.10.zone << 'EOF' $TTL 1h@ IN SOA ocp-helper-node.lab.local. admin.lab.local. ( 2026071802 ; serial 1h ; refresh 30m ; retry 7d ; expire 5m ; minimum ) @ IN NS ocp-helper-node.lab.local. 42 IN PTR ocp-helper-node.lab.local. 43 IN PTR ocp-bootstrap.lab.local. 44 IN PTR master-111.lab.local. 45 IN PTR master-112.lab.local. 46 IN PTR master-113.lab.local. 47 IN PTR worker-114.lab.local. 48 IN PTR worker-115.lab.local. 49 IN PTR worker-116.lab.local. 50 IN PTR worker-117.lab.local. 51 IN PTR worker-118.lab.local. EOF chown named:named /var/named/lab-ocp.example.com.zone /var/named/lab.local.zone /var/named/10.10.10.zonerestorecon -v /var/named/*.zone 2>/dev/null || true named-checkconf /etc/named.conf named-checkzone lab-ocp.example.com /var/named/lab-ocp.example.com.zone named-checkzone lab.local /var/named/lab.local.zone named-checkzone 10.10.10.in-addr.arpa /var/named/10.10.10.zone systemctl enable --now named
7.5 配置 Nginx(Ignition + RHCOS HTTP 服务)
端口分工: HAProxy(§7.6)占用 80/443 (Ingress);Nginx 仅监听 10.10.10.42:8080(RHCOS/ignition)。须先于 HAProxy 配置 ,释放默认 :80。RHEL 9 的默认 listen 80 写在 /etc/nginx/nginx.conf 主配置 里(不是 conf.d/default.conf),须注释或删除该 server 块。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bakawk ' /^[[:space:]]*server[[:space:]]*\{/ { capture=1; buf=$0 ORS; depth=1; next } capture { buf=buf $0 ORS depth+=gsub(/\{/,"&",$0)-gsub(/\}/,"&",$0) if (depth<=0) { if (buf ~ /listen[[:space:]]+80;/) { print " # default :80 server removed (HAProxy uses 80/443)" } else { printf "%s", buf } capture=0; buf="" } next } { print } ' /etc/nginx/nginx.conf.bak > /etc/nginx/nginx.confgrep -q 'listen[[:space:]]*80;' /etc/nginx/nginx.conf && \ echo 'WARN: default :80 server block may still exist in nginx.conf' mv -f /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak 2>/dev/null || true nginx -t semanage port -a -t http_port_t -p tcp 8080 2>/dev/null || semanage port -m -t http_port_t -p tcp 8080 cat > /etc/nginx/conf.d/ocp-bootstrap.conf << 'EOF' server { listen 10.10.10.42:8080; root /var/www/html; location /rhcos/ { autoindex on; } location /ignition/ { autoindex on; types { application/json ign; } default_type application/json; } } EOF systemctl enable --now nginx restorecon -Rv /var/www/html chmod 755 /var/www/html /var/www/html/rhcos /var/www/html/ignition
7.6 配置 HAProxy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 cat > /etc/haproxy/haproxy.cfg << 'EOF' global log 127.0.0.1 local2 chroot /var/lib/haproxy stats socket /var/lib/haproxy/admin.sock mode 600 level admin user haproxy group haproxy maxconn 50000 defaults mode tcp log global option dontlognull timeout connect 5s timeout client 300s timeout server 300s frontend api_frontend bind *:6443 default_backend api_backend backend api_backend balance roundrobin server ocp-bootstrap 10.10.10.43:6443 check server master111 10.10.10.44:6443 check server master112 10.10.10.45:6443 check server master113 10.10.10.46:6443 check frontend mcs_frontend bind *:22623 default_backend mcs_backend backend mcs_backend balance roundrobin server ocp-bootstrap 10.10.10.43:22623 check server master111 10.10.10.44:22623 check server master112 10.10.10.45:22623 check server master113 10.10.10.46:22623 check frontend ingress_http bind *:80 mode http default_backend ingress_http_backend frontend ingress_https bind *:443 mode tcp default_backend ingress_https_backend backend ingress_http_backend balance roundrobin mode http server worker114 10.10.10.47:80 check server worker115 10.10.10.48:80 check server worker116 10.10.10.49:80 check server worker117 10.10.10.50:80 check server worker118 10.10.10.51:80 check backend ingress_https_backend balance roundrobin mode tcp server worker114 10.10.10.47:443 check server worker115 10.10.10.48:443 check server worker116 10.10.10.49:443 check server worker117 10.10.10.50:443 check server worker118 10.10.10.51:443 check EOF rm -rf /var/lib/haproxy/statsrm -f /etc/haproxy/conf.d/*.cfg 2>/dev/null || true ss -tlnp | grep ':80 ' || true haproxy -c -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ setsebool -P haproxy_connect_any 1 systemctl enable --now haproxy
验证:
1 2 systemctl status haproxy ss -tlnp | grep -E '6443|22623|80|443'
7.7 验收
说明: 此阶段 不检查 bootstrap.ign(ignition 在 §8 生成后才存在)。仅验证 Helper 基础服务与 RHCOS HTTP。不部署 registry-proxy。
1 2 3 4 5 6 7 echo "=== DNS ===" && dig api.lab-ocp.example.com @10.10.10.42 +shortecho "=== Nginx RHCOS ===" && curl -s -o /dev/null -w '%{http_code}\n' http://10.10.10.42:8080/rhcos/rhcos-live-rootfs.x86_64.imgecho "=== HAProxy ===" && ss -tlnp | grep -cE '6443|22623' echo "=== corp proxy ===" && curl -x http://10.10.10.254:8080 -s -o /dev/null -w '%{http_code}\n' https://quay.io/v2/ --max-time 15echo "=== CLI ===" && openshift-install version && oc version --clientecho "=== Firewall ===" && firewall-cmd --list-all | grep -E '8080|6443'
预期输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 === DNS === 10.10.10.42 === Nginx RHCOS === 200 === HAProxy === 2 # 6443 与 22623 均在监听 === corp proxy === 200 # 或 401 === CLI === openshift-install 4.18.19 Client Version: 4.18.19 === Firewall === 8080/tcp 6443/tcp 22623/tcp ...
8. 阶段 6 — install-config 8.1 编写 install-config.yaml 1 2 mkdir -p /root/ocp-install && cd /root/ocp-install
将 Pull Secret、SSH 公钥(ssh-keygen -y -f deploy-key.pem)填入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 apiVersion: v1 baseDomain: example.com metadata: name: lab-ocp platform: none: {} compute: - name: worker replicas: 5 controlPlane: name: master replicas: 3 networking: clusterNetwork: - cidr: 172.28 .0 .0 /16 hostPrefix: 23 serviceNetwork: - 172.29 .0 .0 /16 machineNetwork: - cidr: 10.10 .10 .0 /24 networkType: OVNKubernetes pullSecret: '<从 console.redhat.com 获取的 JSON,单行>' sshKey: '<deploy-key.pub 内容>' proxy: httpProxy: http://10.10.10.254:8080 httpsProxy: http://10.10.10.254:8080 noProxy: .example.com,.lab-ocp.example.com,10.10.10.0/24,172.28.0.0/16,172.29.0.0/16,localhost,127.0.0.1,.svc,.cluster.local
禁止添加 publish: 字段 (none 平台不支持 Integrated/Internal)。proxy 指向企业 HTTP 代理 10.10.10.254:8080。
8.2 生成 Ignition 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cd /root/ocp-installcp install-config.yaml install-config.yaml.bakexport http_proxy=http://10.10.10.254:8080export https_proxy=http://10.10.10.254:8080openshift-install create ignition-configs --log-level=info unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXYls -l auth/kubeconfig auth/kubeadmin-passwordcp -v *.ign /var/www/html/ignition/chmod 644 /var/www/html/ignition/*.ign restorecon -Rv /var/www/html/ignition
8.3 验收 1 2 3 4 5 for f in bootstrap master worker; do curl -s -o /dev/null -w "${f} .ign: %{http_code}\n" http://10.10.10.42:8080/ignition/${f} .ign done grep -E 'baseDomain|name:' install-config.yaml.bak
预期输出:
1 2 3 4 5 bootstrap.ign: 200 master.ign: 200 worker.ign: 200 name: lab-ocp baseDomain: example.com
9. 阶段 7 — Bootstrap
Bootstrap 全程 Live PXE ,bootstrap-complete 后删除即可,不需要 coreos-installer 写盘。
9.0 启动 Bootstrap 1 2 3 4 5 6 7 8 9 10 11 12 qm config 110 >/dev/null 2>&1 || { echo 'ERROR: VM 110 不存在,请先完成 §5.3 创建 VM' ; exit 1; } KERNEL="/var/lib/vz/template/iso/rhcos-live-kernel-x86_64" INITRD="/var/lib/vz/template/iso/rhcos-live-initramfs.x86_64.img" VMID=110 NODE_IP="10.10.10.$((VMID-67) )" APPEND="coreos.live.rootfs_url=http://10.10.10.42:8080/rhcos/rhcos-live-rootfs.x86_64.img ignition.config.url=http://10.10.10.42:8080/ignition/bootstrap.ign ignition.firstboot ignition.platform.id=qemu rd.neednet=1 nameserver=10.10.10.42 nameserver=10.10.10.3 ip=${NODE_IP} ::10.10.10.1:255.255.255.0::ens18:none console=tty0" qm stop 110 2>/dev/null || true qm set 110 --args "-kernel ${KERNEL} -initrd ${INITRD} -append \"${APPEND} \"" qm start 110
9.1 验收
启动后约 5–15 分钟 再验收。通过即可并行启动 Master(§10.1);bootstrap-complete 在 §10.6 等待。
1 2 3 4 5 6 7 8 9 10 11 12 13 ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no -i deploy-key.pem core@10.10.10.43 ' echo "=== network ===" ip -4 -br addr show dev ens18 echo "=== default route ===" ip route | grep default echo "=== resolv ===" cat /etc/resolv.conf echo "=== services ===" sudo systemctl is-active crio release-image bootkube echo "=== pods ===" sudo crictl pods 2>/dev/null | head -5 '
预期输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 === network === ens18 10.10.10.43/24 ... === default route === default via 10.10.10.1 dev ens18 ... === resolv === nameserver 10.10.10.42 nameserver 10.10.10.3 === services === active active active === pods === POD ID ... etcd-... # 或 kube-apiserver 等 static pod 开始出现
10. 阶段 8 — Master
与 Bootstrap 的区别: Bootstrap(110)可全程 Live PXE。Master(111–113)不能长期停在 Live 环境 ——存在 /run/ostree-live 时 MCO firstboot 无法完成 rpm-ostree 写盘,systemctl start crio 会无输出一直卡住 (在等 firstboot)。正确流程:
1 Live PXE 引导(安装介质)→ 验收网络 → coreos-installer 写盘 → PVE 改 boot order → 磁盘启动 → kubelet 加入集群
Master 可与 Bootstrap 并行 ;镜像从 quay.io 经企业代理拉取(install-config.yaml 的 proxy → 节点 /etc/mco/proxy.env)。
10.1 Live PXE 引导(安装介质) 1 2 3 4 5 6 7 8 9 10 11 12 KERNEL="/var/lib/vz/template/iso/rhcos-live-kernel-x86_64" INITRD="/var/lib/vz/template/iso/rhcos-live-initramfs.x86_64.img" for VMID in 111 112 113; do qm stop "$VMID " 2>/dev/null || true qm set "$VMID " --delete args 2>/dev/null || true NODE_IP="10.10.10.$((VMID-67) )" APPEND="coreos.live.rootfs_url=http://10.10.10.42:8080/rhcos/rhcos-live-rootfs.x86_64.img ignition.config.url=http://10.10.10.42:8080/ignition/master.ign ignition.firstboot ignition.platform.id=qemu rd.neednet=1 nameserver=10.10.10.42 nameserver=10.10.10.3 ip=${NODE_IP} ::10.10.10.1:255.255.255.0::ens18:none console=tty0" qm set "$VMID " --args "-kernel ${KERNEL} -initrd ${INITRD} -append \"${APPEND} \"" qm start "$VMID " done
10.2 验收 Live 网络(尚未装盘)
Live 起来后约 5 分钟 再验收。此阶段不要求 kubelet/crio 为 active。
1 2 3 4 5 6 7 8 9 10 11 ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no -i deploy-key.pem core@10.10.10.44 ' echo "=== network ===" ip -4 -br addr show dev ens18 ip route | grep default cat /etc/resolv.conf echo "=== live check ===" test -e /run/ostree-live && echo "Live 环境(预期,继续 §10.3 装盘)" curl -sf -o /dev/null http://10.10.10.42:8080/ignition/master.ign && echo "master.ign OK" lsblk /dev/sda '
预期:
1 2 3 4 ens18 10.10.10.44/24 ... default via 10.10.10.1 dev ens18 ... Live 环境(预期,继续 §10.3 装盘) master.ign OK
排障: resolv.conf 缺失 → 检查 APPEND 是否含 nameserver=;Ignition 未拉 master.ign → 检查是否含 ignition.firstboot(
10.3 coreos-installer 安装到磁盘 每台 Master 分别 SSH 执行 (以 111 为例):
1 ssh -i deploy-key.pem core@10.10.10.44
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 VMID=111 NODE_IP="10.10.10.$((VMID-67) )" sudo mkdir -p /etc/NetworkManager/system-connections/ sudo tee /etc/NetworkManager/system-connections/ens18.nmconnection << EOF [connection] id=ens18 type=ethernet interface-name=ens18 autoconnect=true [ipv4] method=manual addresses=${NODE_IP}/24 gateway=10.10.10.1 dns=10.10.10.42;10.10.10.3; dns-search=lab.local; [ipv6] method=disabled EOF sudo chmod 600 /etc/NetworkManager/system-connections/ens18.nmconnection export NO_PROXY="*" sudo coreos-installer install \ --ignition-url=http://10.10.10.42:8080/ignition/master.ign \ --insecure-ignition \ --insecure \ --copy-network \ /dev/sda
112 / 113: SSH 至 core@10.10.10.45 / core@10.10.10.46,仅改 VMID。
VMID
SSH 目标
VMID 变量
111
core@10.10.10.44
111
112
core@10.10.10.45
112
113
core@10.10.10.46
113
现象
处理
connection refused / 代理超时
确认已 export NO_PROXY="*"
No such file: /dev/sda
lsblk 确认磁盘设备名
安装较慢
正常,需从网络拉取 RHCOS 镜像
10.4 PVE 改 boot order(从磁盘启动)
PVE 的 --args 会让 VM 始终走 Live PXE ,绕过磁盘。装盘后必须删除 args 并设 boot order=scsi0。
1 2 3 4 5 6 7 8 9 10 11 12 for VMID in 111 112 113; do qm stop "$VMID " qm set "$VMID " --delete args --boot order=scsi0 qm start "$VMID " done for VMID in 111 112 113; do echo "=== VM $VMID ===" qm config "$VMID " | grep -E '^args|^boot' done
预期: 无 args: 行;boot: order=scsi0
10.5 验收 Master 加入集群
磁盘引导后约 15–30 分钟 (Ignition → MCS api-int:22623 → 拉镜像 → kubelet)。此时不应存在 /run/ostree-live。
1 2 3 4 5 6 ssh -i deploy-key.pem core@10.10.10.44 ' test ! -e /run/ostree-live && echo "disk boot OK" || echo "WARN: still live" systemctl is-active kubelet crio sudo crictl pods 2>/dev/null | head -5 '
1 2 3 4 export KUBECONFIG=/root/ocp-install/auth/kubeconfigoc get nodes -o wide oc get csr 2>/dev/null | grep -i pending || true
预期:
1 2 3 4 disk boot OK active active (static pod 列表)
10.6 监控 Bootstrap 完成 1 2 3 cd /root/ocp-installopenshift-install wait-for bootstrap-complete --dir =/root/ocp-install --log-level=info
并行监控(另开终端,Helper 上):
1 2 3 export KUBECONFIG=/root/ocp-install/auth/kubeconfigwatch -n15 'oc get nodes 2>/dev/null; echo; oc get csr 2>/dev/null | grep -i pending || true' curl -sk https://api.lab-ocp.example.com:6443/healthz
10.7 bootstrap-complete 后更新 HAProxy
前置: §10.6 bootstrap-complete 已成功。
从 API/MCS 后端删除 Bootstrap(Red Hat 要求):
1 2 3 4 5 6 7 sed -i '/server ocp-bootstrap/d' /etc/haproxy/haproxy.cfg systemctl reload haproxy grep bootstrap /etc/haproxy/haproxy.cfg || echo 'bootstrap removed: OK' export KUBECONFIG=/root/ocp-install/auth/kubeconfigoc get nodes
10.8 验收 1 2 3 4 5 6 export KUBECONFIG=/root/ocp-install/auth/kubeconfigCLUSTER=lab-ocp echo "=== API healthz ===" && curl -sk https://api.${CLUSTER} .example.com:6443/healthzecho "=== nodes ===" && oc get nodesecho "=== HAProxy ===" && ! grep -q bootstrap /etc/haproxy/haproxy.cfg && echo 'bootstrap removed: OK'
预期输出:
1 2 3 4 5 6 7 8 9 10 === API healthz === ok === nodes === master-111 Ready control-plane,master ... master-112 Ready control-plane,master ... master-113 Ready control-plane,master ... === HAProxy === bootstrap removed: OK
11. 阶段 9 — Worker
前置: §10.8 已完成(bootstrap-complete、3 Master Ready、HAProxy 已移除 bootstrap 后端)。Worker 与 Master 相同:Live PXE 仅作安装介质 → coreos-installer 写盘 → 磁盘启动 (见 §10.3–§10.4)。
11.1 删除 Bootstrap VM
若 §10.7 已执行,本节可跳过,仅确认 VM 110 不存在。
1 2 3 4 qm stop 110 2>/dev/null || true qm destroy 110 qm list | grep 110 || echo 'OK: VM 110 gone'
11.2 Live PXE 引导 Worker(安装介质) 1 2 3 4 5 6 7 8 9 10 11 12 KERNEL="/var/lib/vz/template/iso/rhcos-live-kernel-x86_64" INITRD="/var/lib/vz/template/iso/rhcos-live-initramfs.x86_64.img" for VMID in 114 115 116 117 118; do qm stop "$VMID " 2>/dev/null || true qm set "$VMID " --delete args 2>/dev/null || true NODE_IP="10.10.10.$((VMID-67) )" APPEND="coreos.live.rootfs_url=http://10.10.10.42:8080/rhcos/rhcos-live-rootfs.x86_64.img ignition.config.url=http://10.10.10.42:8080/ignition/worker.ign ignition.firstboot ignition.platform.id=qemu rd.neednet=1 nameserver=10.10.10.42 nameserver=10.10.10.3 ip=${NODE_IP} ::10.10.10.1:255.255.255.0::ens18:none console=tty0" qm set "$VMID " --args "-kernel ${KERNEL} -initrd ${INITRD} -append \"${APPEND} \"" qm start "$VMID " done
11.3 coreos-installer 安装到磁盘 每台 Worker 分别 SSH 执行 。以 114 为例:
1 ssh -i deploy-key.pem core@10.10.10.47
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 VMID=114 NODE_IP="10.10.10.$((VMID-67) )" sudo mkdir -p /etc/NetworkManager/system-connections/ sudo tee /etc/NetworkManager/system-connections/ens18.nmconnection << EOF [connection] id=ens18 type=ethernet interface-name=ens18 autoconnect=true [ipv4] method=manual addresses=${NODE_IP}/24 gateway=10.10.10.1 dns=10.10.10.42;10.10.10.3; dns-search=lab.local; [ipv6] method=disabled EOF sudo chmod 600 /etc/NetworkManager/system-connections/ens18.nmconnection export NO_PROXY="*" sudo coreos-installer install \ --ignition-url=http://10.10.10.42:8080/ignition/worker.ign \ --insecure-ignition \ --insecure \ --copy-network \ /dev/sda
115–118: SSH 至 core@10.10.10.48–.51,VMID 改为 115–118。
VMID
SSH 目标
114
core@10.10.10.47
115
core@10.10.10.48
116
core@10.10.10.49
117
core@10.10.10.50
118
core@10.10.10.51
11.4 PVE 改 boot order(从磁盘启动) 1 2 3 4 5 6 for VMID in 114 115 116 117 118; do qm stop "$VMID " qm set "$VMID " --delete args --boot order=scsi0 qm start "$VMID " done
11.5 批准 Worker CSR 磁盘引导后约 10–20 分钟 ,Worker 陆续注册;CSR 需人工批准:
1 2 3 4 5 6 7 8 9 export KUBECONFIG=/root/ocp-install/auth/kubeconfigwhile true ; do oc get csr -o json 2>/dev/null | jq -r '.items[] | select(.status == {}) | .metadata.name' | \ xargs -r oc adm certificate approve sleep 10 done
11.6 验收 1 2 3 4 5 export KUBECONFIG=/root/ocp-install/auth/kubeconfigecho "=== nodes ===" && oc get nodes -o wideecho "=== pending CSR ===" && oc get csr 2>/dev/null | grep -i pending || echo 'no pending CSR' echo "=== bootstrap VM ===" && ssh -i deploy-key.pem root@10.10.10.41 '! qm list | grep -q 110 && echo EXISTS || echo gone'
预期:
1 2 3 4 5 6 7 8 9 === nodes === master-111/112/113 Ready control-plane,master worker-114–118 Ready worker (共 8 节点) === pending CSR === no pending CSR === bootstrap VM === gone
12. 阶段 10 — 完成安装
前置: §11.6 已完成(8 节点 Ready、无 Pending CSR)。本节在 Helper 上执行 install-complete 并做最终验收。
12.1 等待安装完成 1 2 3 cd /root/ocp-installopenshift-install wait-for install-complete --dir =/root/ocp-install --log-level=info
12.2 获取 kubeadmin 凭据
openshift-install create ignition-configs(§8.2)执行后即生成管理员凭据,不必等待 install-complete。§12.1 成功时终端会再次打印同一密码。
项目
值
用户名
kubeadmin(固定)
密码文件
/root/ocp-install/auth/kubeadmin-password
kubeconfig
/root/ocp-install/auth/kubeconfig
Web Console
https://console-openshift-console.apps.lab-ocp.example.com
API
https://api.lab-ocp.example.com:6443
1 2 3 4 5 6 cat /root/ocp-install/auth/kubeadmin-passwordexport KUBECONFIG=/root/ocp-install/auth/kubeconfigoc whoami
TLS 说明: Master pivot 后 API 证书由 kube-apiserver-lb-signer 签发。裸执行 oc login(不带 CA)会报 x509: certificate signed by unknown authority。Helper 上请优先用上面的 KUBECONFIG;若必须用 oc login -u kubeadmin,见 §12.4。
安全提示: kubeadmin 为临时管理员账号;生产环境应创建正式用户或对接 IdP 后停用 kubeadmin。凭据文件须纳入 §12.5 备份并限制访问权限。
12.3 集群健康检查 1 2 3 4 5 6 7 8 9 10 export KUBECONFIG=/root/ocp-install/auth/kubeconfigoc get nodes -o wide oc get clusterversion oc get clusteroperators oc get co | grep -v -E 'True.*False.*False' || echo "All operators OK" oc get co ingress authentication
12.4 控制台访问验证 Helper 上(推荐):
1 2 3 export KUBECONFIG=/root/ocp-install/auth/kubeconfigoc whoami curl -skI https://console-openshift-console.apps.lab-ocp.example.com | head -1
须以 kubeadmin 密码登录时 (Helper 或工作站;须能解析 API FQDN):
1 2 3 4 5 6 7 8 9 10 11 export KUBECONFIG=/root/ocp-install/auth/kubeconfigoc get configmap kube-root-ca.crt -n openshift-config-managed \ -o jsonpath='{.data.ca\.crt}' > /root/ocp-install/auth/api-ca-bundle.crt oc login https://api.lab-ocp.example.com:6443 \ -u kubeadmin \ -p "$(cat /root/ocp-install/auth/kubeadmin-password) " \ --certificate-authority=/root/ocp-install/auth/api-ca-bundle.crt oc whoami
工作站登录时,将 api-ca-bundle.crt 与 kubeadmin-password 拷到本机,路径相应修改即可。勿 在生产环境长期使用 --insecure-skip-tls-verify(仅排障临时可用)。
12.5 备份关键文件
auth/ 目录含 kubeconfig 与 kubeadmin-password ,丢失后无法从安装目录恢复 kubeadmin 密码。
1 2 3 4 5 6 tar czf /root/ocp-install-backup-$(date +%Y%m%d).tar.gz \ /root/ocp-install/auth/ \ /root/ocp-install/install-config.yaml.bak \ /etc/haproxy/haproxy.cfg \ /etc/named.conf /var/named/lab-ocp.example.com.zone
12.6 验收 1 2 3 4 5 6 7 8 export KUBECONFIG=/root/ocp-install/auth/kubeconfigCLUSTER=lab-ocp echo "=== clusterversion ===" && oc get clusterversionecho "=== nodes ===" && oc get nodesecho "=== operators ===" && oc get co | grep -v -E 'True.*False.*False' || echo 'all CO OK' echo "=== API ===" && curl -sk https://api.${CLUSTER} .example.com:6443/healthzecho "=== console ===" && curl -skI https://console-openshift-console.apps.${CLUSTER} .example.com | head -1
预期:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 === clusterversion === version 4.18.19 True ... Completed True === nodes === (8 节点均为 Ready) === operators === all CO OK === API === ok === console === HTTP/2 200 # 或 HTTP/1.1 200 / 302
13. 阶段 11 — Ceph CSI
前置: §12.6 集群安装已完成。PVE 上已部署 Ceph(ocp-pool,Monitor 在 10.10.10.41)。OCP 通过 Ceph CSI 消费外部 Ceph 存储。
可与核心安装分开执行;若暂不需要动态存储,可跳过本章。
前置检查(任意 Worker 上,须能连通 Ceph Monitor):
13.1 在 PVE 上创建 Ceph 用户 1 2 3 4 ceph auth get-or-create client.openshift mon 'profile rbd' osd 'profile rbd pool=ocp-pool' \ -o /etc/pve/ceph/openshift.client.openshift.keyring ceph auth get client.openshift
记录 key 值,以及 Ceph FSID:
13.2 创建 Ceph 密钥 Secret 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export KUBECONFIG=/root/ocp-install/auth/kubeconfigCEPH_KEY="<client.openshift 的 key>" FSID="<ceph fsid>" cat <<EOF | oc apply -f - apiVersion: v1 kind: Secret metadata: name: csi-ceph-secret namespace: default stringData: userID: openshift userKey: ${CEPH_KEY} EOF
13.3 安装 Ceph CSI RBD Provisioner 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 export KUBECONFIG=/root/ocp-install/auth/kubeconfigcurl -LO https://raw.githubusercontent.com/ceph/ceph-csi/v3.13.0/deploy/rbd/kubernetes/csi-provisioner-rbac.yaml curl -LO https://raw.githubusercontent.com/ceph/ceph-csi/v3.13.0/deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml curl -LO https://raw.githubusercontent.com/ceph/ceph-csi/v3.13.0/deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml curl -LO https://raw.githubusercontent.com/ceph/ceph-csi/v3.13.0/deploy/rbd/kubernetes/csi-rbdplugin.yaml cat <<EOF | oc apply -f - apiVersion: v1 kind: ConfigMap metadata: name: ceph-csi-config namespace: default data: config.json: | [ { "clusterID": "${FSID}", "monitors": ["10.10.10.41:6789"], "cephFS": {}, "rbd": {} } ] --- apiVersion: v1 kind: ConfigMap metadata: name: ceph-config namespace: default data: ceph.conf: | [global] auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx keyring: | --- apiVersion: v1 kind: ConfigMap metadata: name: ceph-csi-encryption-kms-config namespace: default data: config.json: |- {} EOF oc apply -f csi-provisioner-rbac.yaml oc apply -f csi-nodeplugin-rbac.yaml oc apply -f csi-rbdplugin.yaml oc apply -f csi-rbdplugin-provisioner.yaml
13.4 创建 StorageClass 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 export KUBECONFIG=/root/ocp-install/auth/kubeconfigcat <<EOF | oc apply -f - apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ceph-rbd-ocp annotations: storageclass.kubernetes.io/is-default-class: "true" provisioner: rbd.csi.ceph.com parameters: clusterID: ${FSID} pool: ocp-pool imageFeatures: layering csi.storage.k8s.io/provisioner-secret-name: csi-ceph-secret csi.storage.k8s.io/provisioner-secret-namespace: default csi.storage.k8s.io/controller-expand-secret-name: csi-ceph-secret csi.storage.k8s.io/controller-expand-secret-namespace: default csi.storage.k8s.io/node-stage-secret-name: csi-ceph-secret csi.storage.k8s.io/node-stage-secret-namespace: default reclaimPolicy: Delete allowVolumeExpansion: true volumeBindingMode: Immediate EOF
13.5 验证 StorageClass 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 export KUBECONFIG=/root/ocp-install/auth/kubeconfigoc get sc oc get pods -n default | grep csi-rbd cat <<EOF | oc apply -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-pvc spec: accessModes: [ReadWriteOnce] resources: requests: storage: 5Gi storageClassName: ceph-rbd-ocp EOF oc get pvc test-pvc
13.6 验收 1 2 3 4 5 export KUBECONFIG=/root/ocp-install/auth/kubeconfigecho "=== StorageClass ===" && oc get sc ceph-rbd-ocpecho "=== CSI pods ===" && oc get pods -n default -l app=csi-rbdpluginecho "=== test PVC ===" && oc get pvc test-pvc
预期:
1 2 3 4 5 6 7 8 9 === StorageClass === ceph-rbd-ocp rbd.csi.ceph.com ... (default) === CSI pods === csi-rbdplugin-... Running csi-rbdplugin-provisioner-... Running === test PVC === test-pvc Bound ... ceph-rbd-ocp 5Gi
14. 阶段 12 — 节点防火墙(可选)
时机: §12.6 集群 install-complete 且全部节点 Ready 之后。安装过程中不要 启用。
目标:拒绝管理网段以外 的入站流量,出站不限制(仍经 10.10.10.1 访问企业代理)。
注意: 仅允许 Helper(.42)入站不够 ——Master 间 etcd、节点间 kubelet/OVN 等仍需 10.10.10.43–.51 互访 。推荐入站白名单为整个 **10.10.10.0/24**(含 Helper、PVE、工作站管理 IP)。
在节点上验证(以 Master 为例):
1 2 3 4 5 ssh -i deploy-key.pem core@10.10.10.44 sudo iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT sudo iptables -I INPUT 2 -i lo -j ACCEPT sudo iptables -I INPUT 3 -s 10.10.10.0/24 -j ACCEPT sudo iptables -A INPUT -j DROP
确认集群健康后,通过 MachineConfig 或配置管理固化到全部 Master/Worker(Master 与 Worker 各一份,role 标签分别对应)。
1 2 3 4 5 export KUBECONFIG=/root/ocp-install/auth/kubeconfigoc get nodes oc get co network curl -sk https://api.lab-ocp.example.com:6443/healthz