Oracle RAC 21.3 双节点集群 Docker Desktop 部署指南本文提供一份在 Windows Docker DesktopWSL2 后端上部署 Oracle RAC 21.3 的完整可执行步骤先部署单节点集群racnode1再实测扩展第二个节点racnode2最终得到真实可用的双节点 RAC 集群Grid Infrastructure 21.3 数据库 ORCLCDBORCLCDB1/ORCLCDB2 双实例GV$ 视图、Cache Fusion、DLM 全部可用。一、环境要求项要求操作系统Windows 10/11 桌面版容器引擎Docker DesktopWSL2 后端物理内存建议 32GB单节点阶段容器内可见 15G双节点阶段建议将 WSL 内存调到 24GBRAC 镜像registry.cn-hangzhou.aliyuncs.com/hd2020/ka:rac21.3.0阿里云镜像仓库部署形态单节点 RACracnode1起步 → 扩展为双节点集群racnode1 racnode2二、准备 ASM 磁盘3 × 10GBRAC 的 OCR、Voting Disk 与数据库文件都存放在 ASM 磁盘组。先准备 3 个 10GB 的磁盘镜像文件以D:\RAC\oradata\为例D:\RAC\oradata\asm_disk01.img D:\RAC\oradata\asm_disk02.img D:\RAC\oradata\asm_disk03.img在宿主机的docker-desktopWSL distro 中将镜像文件绑定为 loop 设备容器内无法执行losetupwsl -d docker-desktop -u root -- sh -c losetup /dev/loop2 /mnt/host/d/RAC/oradata/asm_disk01.img wsl -d docker-desktop -u root -- sh -c losetup /dev/loop3 /mnt/host/d/RAC/oradata/asm_disk02.img wsl -d docker-desktop -u root -- sh -c losetup /dev/loop4 /mnt/host/d/RAC/oradata/asm_disk03.img绑定完成后容器内即可看到/dev/loop2、/dev/loop3、/dev/loop4三个块设备。该绑定在宿主机侧持久生效容器重启、重建都不受影响。三、创建 Docker 网络RAC 需要两套网络公共网络PUBLIC/SCAN/VIP与私有互连网络PRIVATE节点间 Cache Fusion 通信docker network create rac_pub1_nw --subnet 172.16.1.0/24 docker network create rac_priv1_nw --subnet 192.168.17.0/24四、启动容器完整 docker rundocker run -d --name racnode1 --hostname racnode1 --privileged --shm-size4g \ --network rac_pub1_nw --ip 172.16.1.100 \ -e OP_TYPEINSTALL \ -e ASM_DISCOVERY_DIR/dev \ -e ASM_DEVICE_LIST/dev/loop2,/dev/loop3,/dev/loop4 \ -e PUBLIC_IP172.16.1.100 \ -e PRIV_IP192.168.17.100 \ -e PRIV_HOSTNAMEracnode1-priv \ -e NODE_VIP172.16.1.130 \ -e VIP_HOSTNAMEracnode1-vip \ -e SCAN_IP172.16.1.230 \ -e SCAN_NAMEracnodec1-scan \ -e DOMAINexample.com \ -v D:\RAC\oradata\asm_disk01.img:/oradata/asm_disk01.img \ -v D:\RAC\oradata\asm_disk02.img:/oradata/asm_disk02.img \ -v D:\RAC\oradata\asm_disk03.img:/oradata/asm_disk03.img \ -v D:\RAC\custom_entrypoint.sh:/custom_entrypoint.sh \ --entrypoint /custom_entrypoint.sh \ registry.cn-hangzhou.aliyuncs.com/hd2020/ka:rac21.3.0 # 追加私有网络第二网卡 docker network connect rac_priv1_nw racnode1 --ip 192.168.17.100关键参数说明参数值说明--hostnameracnode1必须显式指定节点名否则集群配置节点名错乱--privileged-RAC 需要操作块设备、挂载等系统能力--shm-size4gOracle 需要较大共享内存默认 64MB 不够-e PRIV_HOSTNAMEracnode1-priv必须通过-e传入镜像启动程序会重建配置文件手动改文件无效-e PUBLIC_IP172.16.1.100容器 eth0-e PRIV_IP192.168.17.100容器 eth1 私有互连-e NODE_VIP172.16.1.130节点虚拟 IPracnode1-vip-e SCAN_IP172.16.1.230SCAN IPracnodec1-scan单 IP-e ASM_DEVICE_LIST/dev/loop2,/dev/loop3,/dev/loop4ASM 磁盘设备-e DOMAINexample.com域名注意本镜像的内核环境WSL2不支持 CPU CFS 带宽控制不要加--cpus参数否则容器无法启动。自定义 entrypoint可选D:\RAC\custom_entrypoint.sh内容示例loop 设备由宿主侧绑定容器内只需启动镜像自带的安装程序#!/bin/bash # loop 设备已在宿主 WSL 侧绑定这里无需 losetup chown grid:asmadmin /dev/loop2 /dev/loop3 /dev/loop4 2/dev/null || true chmod 660 /dev/loop2 /dev/loop3 /dev/loop4 2/dev/null || true exec /usr/sbin/oracleinit五、等待自动安装约 1 小时容器启动后镜像自带的configGrid.sh会自动执行完整安装无需人工干预Pre-Grid Setup系统准备 → 生成 OS 随机密码 → 网络检查eth0 public / eth1 private → SSH 互信设置grid / oracle 用户 → CVU 预检查 → gridSetup.shGrid 软件配置 → root.sh → rootcrs.pl19 步配置 CRS 集群 → 集群状态检查 → DBCA 创建 RAC 数据库 ORCLCDB → ORACLE RAC DATABASE IS READY TO USE!观察安装进度docker logs -f racnode1成功标志—— 容器日志出现#################################### ORACLE RAC DATABASE IS READY TO USE! ####################################以及 rootcrs 日志中的CLSRSC-325: Configure Oracle Grid Infrastructure for a Cluster ... succeeded DBCA_PROGRESS : 100% Database creation complete. Global Database Name:ORCLCDB安装中段可能出现PROC-26 Insufficient quorum to open OCR devices的告警这是 OCR 初始化过程中的正常中间状态安装程序会自动继续最终 OCR 会落在DATA磁盘组并通过完整性检查无需干预。六、验证部署6.1 CRS 集群栈docker exec racnode1 bash -c export PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/u01/app/21.3.0/grid/bin; crsctl check crs CRS-4638: Oracle High Availability Services is online CRS-4537: Cluster Ready Services is online CRS-4529: Cluster Synchronization Services is online CRS-4533: Event Manager is online6.2 OCR集群注册表docker exec racnode1 bash -c export PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/u01/app/21.3.0/grid/bin; ocrcheck Status of Oracle Cluster Registry is as follows : Version : 4 Total space (kbytes) : 901284 Device/File Name : DATA Device/File integrity check succeeded6.3 RAC 数据库GV$ 视图docker exec -u oracle racnode1 bash -c \ export ORACLE_HOME/u01/app/oracle/product/21.3.0/dbhome_1; export ORACLE_SIDORCLCDB1; \ sqlplus -s / as sysdba EOF select instance_name, status, host_name from v$instance; select name, open_mode from v$database; select inst_id, instance_name, status, host_name from gv$instance; EOF INSTANCE_NAME STATUS HOST_NAME ORCLCDB1 OPEN racnode1 NAME OPEN_MODE ORCLCDB READ WRITE INST_ID INSTANCE_NAME STATUS HOST_NAME 1 ORCLCDB1 OPEN racnode1GV$ 视图可查 集群数据库模式确认单节点 RACinst_id1。6.4 进程与监听器# 数据库实例进程 ora_pmon_ORCLCDB1 # 监听器数据库 SCAN ASM tnslsnr LISTENER / LISTENER_SCAN1 / ASMNET1LSNR_ASM七、连接信息项值数据库名ORCLCDB实例名ORCLCDB1SID集群节点racnode1ASM 实例ASM1ASM 磁盘组DATA3 × 10GB管理员登录docker exec -u oracle racnode1 bash -c export ORACLE_HOME/u01/app/oracle/product/21.3.0/dbhome_1; export ORACLE_SIDORCLCDB1; sqlplus / as sysdba监听端口1521LISTENER/ 1521SCAN八、扩展第二节点 racnode2双节点集群实战单节点 RAC 验证通过后按下述步骤扩展第二个节点形成真正意义上的双节点 RAC 集群Cache Fusion / DLM 双实例运行。以下每一步都在 Docker Desktop WSL2 环境实测成功。8.1 前提条件项要求宿主内存建议 ≥ 32GB双节点各 4-8GB 实际占用另加监控栈共享 ASM 磁盘沿用单节点的 loop2/3/4racnode2 与 racnode1 共享同一组 ASM 磁盘这是 RAC 的基本要求网络rac_pub1_nw/rac_priv1_nw已创建racnode2 接入同一网段内存调优可选修改C:\Users\user\.wslconfig为memory24GB、processors6重启 Docker Desktop 生效8.2 创建 racnode2 容器ADDNODE 模式镜像入口支持OP_TYPEADDNODE容器启动后自动执行AddNode.sh把新节点加入现有集群docker run -d --name racnode2 --hostname racnode2 --privileged --shm-size4g \ --network rac_pub1_nw --ip 172.16.1.101 \ -e OP_TYPEADDNODE \ -e PUBLIC_HOSTNAMEracnode2 \ -e PUBLIC_IP172.16.1.101 \ -e PRIV_HOSTNAMEracnode2-priv \ -e PRIV_IP192.168.17.101 \ -e NODE_VIP172.16.1.131 \ -e VIP_HOSTNAMEracnode2-vip \ -e SCAN_NAMEracnodec1-scan \ -e SCAN_IP172.16.1.230 \ -e DOMAINexample.com \ -e EXISTING_CLS_NODESracnode1 \ -e ASM_DEVICE_LIST/dev/loop2,/dev/loop3,/dev/loop4 \ -e ASM_DISCOVERY_DIR/dev \ -v D:\RAC\custom_entrypoint.sh:/custom_entrypoint.sh \ -v D:\RAC\oradata\asm_disk01.img:/oradata/asm_disk01.img \ -v D:\RAC\oradata\asm_disk02.img:/oradata/asm_disk02.img \ -v D:\RAC\oradata\asm_disk03.img:/oradata/asm_disk03.img \ --entrypoint /custom_entrypoint.sh \ registry.cn-hangzhou.aliyuncs.com/hd2020/ka:rac21.3.0 # 追加私有网络第二网卡eth1 docker network connect --ip 192.168.17.101 rac_priv1_nw racnode2与 racnode1 的关键差异参数值说明OP_TYPEADDNODE以 “加入现有集群” 模式运行racnode1 是INSTALLEXISTING_CLS_NODESracnode1告诉 AddNode 流程现有节点是谁ASM_DEVICE_LIST/dev/loop2,/dev/loop3,/dev/loop4与 racnode1共享同一组ASM 磁盘新 IP 规划PUBLIC 172.16.1.101 / PRIV 192.168.17.101 / VIP 172.16.1.131每节点独立8.3 重建 SSH 互信必做镜像出厂密钥不匹配ADDNODE 流程第一步是 SSH 互信grid /oracle 双用户、双向。实测镜像出厂公钥不匹配setupSSH会报SSH check failed for the gridracnode1 ... permission denied。需要手动重建authorized_keys# 1. 提取双方公钥到宿主机临时目录 docker cp racnode1:/home/grid/.ssh/id_rsa.pub /tmp/n1.pub docker cp racnode2:/home/grid/.ssh/id_rsa.pub /tmp/n2.pub docker cp racnode1:/home/oracle/.ssh/id_rsa.pub /tmp/o1.pub docker cp racnode2:/home/oracle/.ssh/id_rsa.pub /tmp/o2.pub # 2. 拷入对方容器 docker cp /tmp/n2.pub racnode1:/tmp/n2.pub docker cp /tmp/n1.pub racnode2:/tmp/n1.pub docker cp /tmp/o2.pub racnode1:/tmp/o2.pub docker cp /tmp/o1.pub racnode2:/tmp/o1.pub # 3. 重建 grid 用户互信docker exec 默认用户就是 grid可直接写 docker exec racnode1 bash -c cat /tmp/n2.pub /home/grid/.ssh/id_rsa.pub /home/grid/.ssh/authorized_keys; chown grid:oinstall /home/grid/.ssh/authorized_keys; chmod 600 /home/grid/.ssh/authorized_keys docker exec racnode2 bash -c cat /tmp/n1.pub /home/grid/.ssh/id_rsa.pub /home/grid/.ssh/authorized_keys; chown grid:oinstall /home/grid/.ssh/authorized_keys; chmod 600 /home/grid/.ssh/authorized_keys # 4. 重建 oracle 用户互信必须 -u root否则 700 权限目录进不去 docker exec -u root racnode1 bash -c cat /tmp/o2.pub /home/oracle/.ssh/id_rsa.pub /home/oracle/.ssh/authorized_keys; chown oracle:oinstall /home/oracle/.ssh/authorized_keys; chmod 600 /home/oracle/.ssh/authorized_keys docker exec -u root racnode2 bash -c cat /tmp/o1.pub /home/oracle/.ssh/id_rsa.pub /home/oracle/.ssh/authorized_keys; chown oracle:oinstall /home/oracle/.ssh/authorized_keys; chmod 600 /home/oracle/.ssh/authorized_keys # 5. 验证双向互信grid / oracle 都要全部输出 OK docker exec racnode2 bash -c ssh -o BatchModeyes gridracnode1 echo OK docker exec racnode1 bash -c ssh -o BatchModeyes gridracnode2 echo OK docker exec -u oracle racnode2 bash -c ssh -o BatchModeyes oracleracnode1 echo OK docker exec -u oracle racnode1 bash -c ssh -o BatchModeyes oracleracnode2 echo OK全部 OK 后重启 racnode2重新执行 ADDNODEdocker restart racnode2日志观察点docker logs -f racnode2SSH check fine for the racnode1 / racnode2 # 互信通过 Running GridSetup.sh on racnode1 ... # Grid 节点添加 Node Addition performed # Grid addNode 完成 Running root.sh on node racnode2 # root.sh 执行8.4 三个必踩的坑及修复坑 1共享 loop 设备属主被重置 → racnode1 的 ASM 掉盘 → CRSD PANICdocker restart racnode2以及容器重建会把共享的/dev/loop2-4设备节点重建为属主root:disk。racnode1 的 ASM 实例grid 用户读不到磁盘 → DATA 磁盘组卸载 → OCR 打不开 → CRSD 崩溃退出CRSD00111 ... PROC-26。修复每次重启 racnode2 后立即执行# 恢复共享设备属主在 racnode1 内 docker exec -u root racnode1 chown grid:asmadmin /dev/loop2 /dev/loop3 /dev/loop4 docker exec -u root racnode1 chmod 660 /dev/loop2 /dev/loop3 /dev/loop4 # 重挂 DATA 磁盘组 docker exec -u grid racnode1 bash -lc export ORACLE_HOME/u01/app/21.3.0/grid; export ORACLE_SIDASM1; sqlplus -s / as sysasm EOF alter diskgroup all mount; select name, state from v$asm_diskgroup_stat; EOF # 若 CRSD 已崩溃则重启它 docker exec -u root racnode1 /u01/app/21.3.0/grid/bin/crsctl start crsd docker exec -u grid racnode1 /u01/app/21.3.0/grid/bin/crsctl check crs # 应全 online坑 2racnode2 重启后接口顺序颠倒eth0 变成 privateDocker Desktop 重启容器后网络接口可能重排出现 eth0private、eth1public。GPNPD 报CRS-42216 No interfaces are configured ... available interface definitions are [eth0...192.168.17.0][eth1...172.16.1.0]并反复崩溃重启。修复disconnect 两个网络按「先 public 后 private」重连再重启容器docker network disconnect rac_pub1_nw racnode2 docker network disconnect rac_priv1_nw racnode2 docker network connect --ip 172.16.1.101 rac_pub1_nw racnode2 # 先接 public docker network connect --ip 192.168.17.101 rac_priv1_nw racnode2 # 再接 private docker restart racnode2验证接口顺序eth0 必须 public IPdocker exec racnode2 ip -4 addr show # 期望 # 2: eth0 ... inet 172.16.1.101/24 # 3: eth1 ... inet 192.168.17.101/24坑 3racnode1 的 CRS 在 addNode 期间短暂不可用AddNode /root.sh 会触发 CRS 滚动重启期间crsctl check crs可能报通信失败CRS-4535 等属正常窗口期等 1-2 分钟自动恢复重新crsctl check crs全 online 即可继续。8.5 补齐 ADDNODE 中断的收尾步骤若 ADDNODE 日志停在CRSD Check failed!但 racnode2 的/u01/app/21.3.0/grid/bin/crsctl已存在Grid 已装好、root.sh 已跑说明只是后续步骤被中断手动补齐即可# 1. ASM 扩展到全部节点拉起 ASM2 docker exec -u grid racnode1 /u01/app/21.3.0/grid/bin/srvctl modify asm -count ALL # 2. 补齐 racnode2 的 VIPnodeapps docker exec -u root racnode1 /u01/app/21.3.0/grid/bin/srvctl add nodeapps -n racnode2 -A 172.16.1.131/255.255.255.0/eth0 docker exec -u grid racnode2 /u01/app/21.3.0/grid/bin/srvctl start nodeapps -n racnode2 # 3. 启动 racnode2 本地监听 docker exec -u grid racnode2 /u01/app/21.3.0/grid/bin/srvctl start listener -n racnode2 # 4. 数据库实例扩展创建 ORCLCDB2 docker exec -u oracle racnode1 bash -lc export ORACLE_HOME/u01/app/oracle/product/21.3.0/dbhome_1; export PATH$ORACLE_HOME/bin:$PATH; dbca -addInstance -silent -nodeName racnode2 -gdbName ORCLCDBdbca 输出Instance ORCLCDB2 added successfully on node racnode2即成功。8.6 验证双节点集群# 集群节点 docker exec -u grid racnode1 /u01/app/21.3.0/grid/bin/olsnodes -n # racnode1 1 # racnode2 2 # 双实例数据库GV$ 视图 docker exec -u oracle racnode1 bash -lc export ORACLE_HOME/u01/app/oracle/product/21.3.0/dbhome_1; export ORACLE_SIDORCLCDB1; sqlplus -s / as sysdba EOF select inst_id, instance_name, status from gv$instance order by 1; EOF # INST_ID INSTANCE_NAME STATUS # 1 ORCLCDB1 OPEN # 2 ORCLCDB2 OPEN # 集群资源全景orclcdb.db / ora.DATA.dg / ora.asm 应双节点 ONLINE docker exec -u grid racnode1 /u01/app/21.3.0/grid/bin/crsctl stat res -t8.7 双节点连接与监控项值集群节点racnode1 / racnode2实例ORCLCDB1racnode1/ ORCLCDB2racnode2SCAN 连接172.16.1.230:1521/ORCLCDB自动负载均衡到双实例监听各节点 1521 SCAN Listener注意扩容后节点监听改绑定 VIP原先直连节点公共 IP如172.16.1.100:1521的方式会失效。外部连接统一走SCAN IP。监控程序Prometheus exporter /python-oracledb把连接串改为 SCAN 地址后即可自动看到双实例GV$ 指标带 inst_id 标签Cache Fusion / DLM 指标随之出现。部署完成后即可连接数据库进行业务验证。如对本文档有任何疑问欢迎评论区交流