Apache Cloudberry Docker Compose 部署指南
用 Docker Compose 编排 Apache Cloudberry 2.1.0 单机集群,基于官方 DEB 包构建运行镜像,起 1 Coordinator + 2 Primary + 2 Mirror 并验证读写与分布。
Apache Cloudberry Docker Compose 部署指南
目标:用 Docker Compose 在一台服务器上部署 Apache Cloudberry 2.1.0 单机 MPP 集群(1 Coordinator + 2 Primary Segment + 2 Mirror Segment)。镜像基于 Apache 官方 DEB 包构建,Compose 负责编排与数据持久化。本文全部命令与回显已在服务器 Docker 环境(Docker 29.8.0 + Docker Compose v5.5.1)实测通过。
一、环境信息
| 项目 | 实测值 / 说明 |
|---|---|
| 操作系统 | Linux x86_64(服务器 Docker 环境) |
| Docker 引擎 | 29.8.0 |
| Docker Compose | v5.5.1(docker compose 插件) |
| 基础镜像 | ubuntu:22.04 |
| 自构建镜像 | cloudberry:2.1.0-incubating(约 580 MB) |
| 安装来源 | 官方 DEB 包 apache-cloudberry-db-incubating_2.1.0-1-ubuntu22.04_amd64.deb |
| 数据库版本 | Apache Cloudberry 2.1.0-incubating,内核 PostgreSQL 14.4 |
| 集群规模 | 1 Coordinator + 2 Primary Segment + 2 Mirror Segment(单容器内) |
| 端口 | 宿主机 5432 → 容器 Coordinator 5432;内部 Segment 6000/6001、Mirror 7000/7001 |
| 数据卷 | 命名卷 cbdb-data 挂载到容器 /data |
说明:Apache Cloudberry 官方未提供可直接运行的数据库镜像,官方只在 Docker Hub 提供「编译用」开发镜像(
apache/incubator-cloudberry:cbdb-build-rocky8-latest等)。因此本文按官方文档推荐的做法——以官方安装包为唯一软件来源——构建运行镜像,保证镜像内二进制与官方发布完全一致。
二、镜像选型说明
Cloudberry 在容器化部署上有三种可选路线,本文采用「官方安装包 + 自定义 Dockerfile」,理由与对比如下。
💡 技术拓展:Cloudberry 容器化选型——
方案 软件来源 优点 缺点 官方 DEB/RPM + 自定义 Dockerfile(本文) 官方安装包 二进制与官方一致、体积小、构建快 需自行写 Dockerfile 官方编译镜像 apache/incubator-cloudberry:cbdb-build-*官方源码 自带完整编译链 仅用于build,非运行镜像、体积巨大 官方 sandbox devops/sandbox/run.sh -m官方源码 多容器一键起 源码编译耗时长 本文采用第一种:用官方 2.1.0 DEB 包构建运行镜像,兼顾「官方一致性」与「构建速度」。
三、前置条件
部署前确认服务器已安装 Docker 与 Compose 插件,并具备拉取基础镜像与下载官方安装包的网络。
docker version --format '{{.Server.Version}}'
docker compose version
实测回显:
29.8.0
Docker Compose version v5.5.1
解读:Docker 新版已内置 docker compose(v2+)插件,无需再单独安装 docker-compose。若 docker compose version 报错,需安装 docker-compose-plugin。
四、构建 Cloudberry 镜像
本节用官方 DEB 包构建运行镜像。镜像包含:Cloudberry 二进制、gpadmin 用户、openssh-server(集群内部通信)、初始化脚本与 gpinitsystem 配置。
4.1 编写 Dockerfile
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
ARG CBDB_DEB_URL=https://github.com/apache/cloudberry/releases/download/2.1.0-incubating/apache-cloudberry-db-incubating_2.1.0-1-ubuntu22.04_amd64.deb
RUN apt-get update && apt-get install -y --no-install-recommends \
curl ca-certificates locales sudo openssh-server openssh-client \
iproute2 net-tools less procps && \
sed -i "s/^# *en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/" /etc/locale.gen && locale-gen && update-locale LANG=en_US.UTF-8
ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
RUN curl -fsSL -o /tmp/cloudberry.deb "$CBDB_DEB_URL" && apt-get install -y --fix-broken /tmp/cloudberry.deb && rm -f /tmp/cloudberry.deb
RUN groupadd -g 520 gpadmin && useradd -g 520 -u 520 -m -d /home/gpadmin -s /bin/bash gpadmin && \
echo "gpadmin ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/gpadmin && chmod 440 /etc/sudoers.d/gpadmin && \
mkdir -p /data/coordinator /data/primary /data/mirror && chown -R gpadmin:gpadmin /data /usr/local/cloudberry*
COPY opt/ /opt/gpconfigs/
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 5432
ENTRYPOINT ["/entrypoint.sh"]
逐项解读:locale-gen + ENV LANG 预生成 UTF-8 语言环境(否则 gpinitsystem 会因 locale 失败);curl -fsSL -o /tmp/cloudberry.deb 下载官方 DEB 包并用 apt-get install --fix-broken 安装;groupadd/useradd 固定 UID/GID 520 创建 gpadmin;COPY opt/ 放入 gpinitsystem_config 与 hostfile_gpinitsystem;ENTRYPOINT 指向自动初始化脚本。
4.2 编写初始化脚本 entrypoint.sh
#!/bin/bash
set -e
grep -qE "[[:space:]]cdw(\$|[[:space:]])" /etc/hosts || echo "127.0.1.1 cdw" >> /etc/hosts
ssh-keygen -A >/dev/null 2>&1 || true
mkdir -p /run/sshd; /usr/sbin/sshd
mkdir -p /home/gpadmin/gpconfigs
cp /opt/gpconfigs/gpinitsystem_config /home/gpadmin/gpconfigs/gpinitsystem_config
cp /opt/gpconfigs/hostfile_gpinitsystem /home/gpadmin/gpconfigs/hostfile_gpinitsystem
chown -R gpadmin:gpadmin /home/gpadmin/gpconfigs
if [ ! -f /data/coordinator/gpseg-1/PG_VERSION ]; then
su - gpadmin -c "mkdir -p ~/.ssh; [ -f ~/.ssh/id_rsa ] || ssh-keygen -t rsa -b 4096 -N \"\" -f ~/.ssh/id_rsa -q; cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys"
su - gpadmin -c "ssh -o StrictHostKeyChecking=no cdw hostname"
su - gpadmin -c "source /usr/local/cloudberry-db/cloudberry-env.sh && gpinitsystem -c /home/gpadmin/gpconfigs/gpinitsystem_config -a" || true
su - gpadmin -c "source /usr/local/cloudberry-db/cloudberry-env.sh; export COORDINATOR_DATA_DIRECTORY=/data/coordinator/gpseg-1; gpstop -a -q || true; gpstart -a -q || true"
fi
su - gpadmin -c "source /usr/local/cloudberry-db/cloudberry-env.sh; export COORDINATOR_DATA_DIRECTORY=/data/coordinator/gpseg-1; gpstart -a" || true
exec tail -f /dev/null
逐项解读:先补齐 /etc/hosts 中的主机名 cdw 并生成 SSH 主机密钥、启动 sshd(集群内部靠 SSH 下发命令);首启(/data/coordinator/gpseg-1/PG_VERSION 不存在)时自动配置 gpadmin 免密 SSH 并执行 gpinitsystem;初始化后 gpstop+gpstart 重新注册全部 Segment(避免 Mirror 注册告警);tail -f /dev/null 保持容器常驻。
4.3 执行构建
docker build -t cloudberry:2.1.0-incubating .
实测回显(输出节选(实测首尾)):
#7 18.24 Setting up apache-cloudberry-db-incubating (2.1.0-1-ubuntu22.04) ...
#8 DONE 18.7s
#11 [7/7] RUN chmod +x /entrypoint.sh
#12 naming to docker.io/library/cloudberry:2.1.0-incubating done
解读:Setting up apache-cloudberry-db-incubating 表示官方包已在镜像内装好,最后一行为镜像命名成功。
五、编写 compose.yaml 并启动
本节用 Compose 定义服务、卷与端口,一键起停。
5.1 编写 compose.yaml
services:
coordinator:
image: cloudberry:2.1.0-incubating
container_name: cloudberry-coordinator
hostname: cdw
shm_size: "2gb"
ports:
- "5432:5432"
volumes:
- cbdb-data:/data
restart: unless-stopped
volumes:
cbdb-data:
逐项解读:hostname: cdw 必须与 gpinitsystem_config 的 COORDINATOR_HOSTNAME 一致(Compose 会自动把该主机名写入容器 /etc/hosts);shm_size: "2gb" 放大共享内存(MPP 大量并行进程依赖 /dev/shm);ports 把 Coordinator 5432 暴露到宿主机;volumes 用命名卷持久化 /data;restart: unless-stopped 让容器异常退出后可自恢复。
5.2 启动集群
docker compose up -d
实测回显:
Network cloudberry_default Creating
Volume cloudberry_cbdb-data Creating
Container cloudberry-coordinator Creating
Container cloudberry-coordinator Started
解读:Compose 自动创建专属网络 cloudberry_default、命名卷 cloudberry_cbdb-data 并启动容器;首次启动时 entrypoint 会自动完成 gpinitsystem 初始化(约 30~60 秒)。
5.3 确认服务状态
docker compose ps
实测回显:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
cloudberry-coordinator cloudberry:2.1.0-incubating "/entrypoint.sh" coordinator 58 seconds ago Up 58 seconds 0.0.0.0:5432->5432/tcp, [::]:5432->5432/tcp
解读:STATUS 为 Up、PORTS 显示 5432->5432,说明 Coordinator 已监听并映射到宿主机。
5.4 查看初始化日志
docker compose logs coordinator | tail -n 8
实测回显(输出节选(实测首尾)):
20261013:18:51:26:000039 gpinitsystem:cdw:gpadmin-[INFO]:-Apache Cloudberry instance successfully created
20261013:18:51:27:000039 gpinitsystem:cdw:gpadmin-[INFO]:-The Coordinator /data/coordinator/gpseg-1/pg_hba.conf post gpinitsystem
20261013:18:51:27:000039 gpinitsystem:cdw:gpadmin-[INFO]:-has been configured to allow all hosts within this new
20261013:18:51:27:000039 gpinitsystem:cdw:gpadmin-[INFO]:-array to intercommunicate.
解读:出现 Apache Cloudberry instance successfully created 即集群初始化完成。
5.5 验证集群
docker compose exec coordinator bash -c "su - gpadmin -c \"source /usr/local/cloudberry-db/cloudberry-env.sh; export COORDINATOR_DATA_DIRECTORY=/data/coordinator/gpseg-1; psql -d postgres -c \\\"SELECT dbid,content,role,port,status,mode FROM gp_segment_configuration ORDER BY dbid;\\\"\""
实测回显:
dbid | content | role | port | status | mode
------+---------+------+------+--------+------
1 | -1 | p | 5432 | u | n
2 | 0 | p | 6000 | u | s
3 | 1 | p | 6001 | u | s
4 | 0 | m | 7000 | u | s
5 | 1 | m | 7001 | u | s
(5 rows)
解读:5 条记录全部 status=u、Segment mode=s,说明 Coordinator 与 4 个 Segment 实例全部健康且镜像同步。
六、数据持久化说明
Compose 用命名卷 cbdb-data 持久化容器 /data,保证容器重建后集群数据不丢。
docker volume ls | grep cbdb
docker compose exec coordinator bash -c "ls -l /data/primary/gpseg0/PG_VERSION"
实测回显:
cbdb-data cloudberry_cbdb-data
-rw-r--r-- 1 gpadmin gpadmin 3 Oct 13 18:51 /data/primary/gpseg0/PG_VERSION
解读:卷名带项目前缀(cloudberry_cbdb-data);PG_VERSION 文件存在表示数据已落盘。docker compose down 默认保留卷,down -v 才会连同数据一起删除——生产环境切勿随意使用 -v。
七、环境变量与端口说明
本镜像无需额外环境变量即可启动;所有关键参数已在 Dockerfile 与 Compose 中固定。下表为可覆盖项。
| 项目 | 位置 | 实测值 | 说明 |
|---|---|---|---|
CBDB_DEB_URL | Dockerfile ARG | 官方 2.1.0 DEB 包 URL | 构建时指定安装包来源 |
LANG/LC_ALL | Dockerfile ENV | en_US.UTF-8 | 保证 initdb locale 有效 |
| Coordinator 端口 | compose ports | 5432:5432 | 宿主机端口映射 |
| 数据目录 | compose volumes | cbdb-data:/data | 持久化 |
| 共享内存 | compose shm_size | 2gb | 放大 /dev/shm |
解读:如需改用 RPM 版镜像,把构建参数 CBDB_DEB_URL 换为 el8/el9 RPM 并调整安装命令即可;端口冲突时把宿主机侧改为如 15432:5432。
八、配置参数说明(容器内集群)
集群参数与裸机安装一致,统一由 gpconfig 管理。查看常用参数:
docker compose exec coordinator bash -c "su - gpadmin -c \"source /usr/local/cloudberry-db/cloudberry-env.sh; export COORDINATOR_DATA_DIRECTORY=/data/coordinator/gpseg-1; gpconfig -s max_connections; gpconfig -s gp_vmem_protect_limit\""
实测回显:
Values on all segments are consistent
GUC : max_connections
Coordinator value: 250
Segment value: 750
Values on all segments are consistent
GUC : gp_vmem_protect_limit
Coordinator value: 8192
Segment value: 8192
解读:max_connections Coordinator=250 / Segment=750;gp_vmem_protect_limit=8192(MB)。修改示例:gpconfig -c gp_vmem_protect_limit -v 4096,随后 gpstop -a && gpstart -a(或 gpstop -u 重载)生效。更多参数见《Apache Cloudberry 配置参数详解》。
九、配置文件与目录结构
镜像内关键路径如下,便于挂载或排查。
| 路径 | 说明 |
|---|---|
/opt/gpconfigs/gpinitsystem_config | 构建时内置的初始化配置模板 |
/home/gpadmin/gpconfigs/gpinitsystem_config | 运行期实际使用的初始化配置 |
/data/coordinator/gpseg-1 | Coordinator 数据目录(含 postgresql.conf) |
| `/data/primary/gpseg0 | gpseg1` |
| `/data/mirror/gpseg0 | gpseg1` |
/usr/local/cloudberry-db | 二进制安装目录(软链接) |
如需持久化整个数据盘到宿主机目录(而非命名卷),把 Compose 的 volumes 改为绑定挂载:
volumes:
- /opt/data/cloudberry:/data
解读:绑定挂载便于直接在宿主机查看数据文件;首次使用前需确保宿主机目录对 UID 520(gpadmin)可写。
十、等价 docker run 命令
不使用 Compose 时,可用等价的 docker run 启动同一镜像。
docker run -d --name cloudberry-coordinator --hostname cdw \
--shm-size=2gb -p 5432:5432 \
-v cbdb-data:/data \
cloudberry:2.1.0-incubating
实测回显:
(容器启动后 `docker ps` 可见 `cloudberry-coordinator` 状态 Up)
解读:--hostname cdw、--shm-size、-v、-p 分别对应 Compose 的 hostname/shm_size/volumes/ports,效果等价。
十一、常用运维命令
docker compose ps # 查看服务状态
docker compose logs -f coordinator # 实时日志
docker compose restart coordinator # 重启容器(集群随 entrypoint 自启)
docker compose stop # 停止
docker compose start # 启动
docker compose down # 停止并删除容器/网络(保留数据卷)
解读:容器内集群的启停建议用 gpstart/gpstop(见《Apache Cloudberry 常用 CLI 命令与工具详解》);容器级操作仅用于整体管理。停止集群请先 docker compose exec coordinator bash -c "su - gpadmin -c 'source /usr/local/cloudberry-db/cloudberry-env.sh; gpstop -a'",再 docker compose stop,避免数据未落盘。
十二、常见问题
Q1:容器启动即退出,日志反复报 Missing privilege separation directory: /run/sshd,如何解决?
现象:docker compose up -d 后容器很快退出,docker compose logs 只看到多行 Missing privilege separation directory: /run/sshd。定位:sshd 启动前缺少 /run/sshd 目录。解法:在 entrypoint 启动 sshd 前补建该目录:
mkdir -p /run/sshd; /usr/sbin/sshd
实测回显(修复后日志出现初始化成功):
20261013:18:51:26:000039 gpinitsystem:cdw:gpadmin-[INFO]:-Apache Cloudberry instance successfully created
Q2:docker build 报 failed to resolve source metadata for docker.io/library/ubuntu:22.04,为什么?
现象:构建第一步拉取基础镜像时报网络错误(dial tcp ... connect: connection refused)。定位:构建所在环境无法直连 Docker Hub。解法:在有网环境 docker save ubuntu:22.04 -o ubuntu2204.tar 后导入离线环境:
docker load -i ubuntu2204.tar
docker images | grep ubuntu
解读:基础镜像就位后重新 docker build 即可;这也是内网离线部署的通用做法。
Q3:容器内 gpstart 报 Coordinator instance process running,是否正常?
现象:entrypoint 末尾的 gpstart -a 打印该错误但容器 Up。定位:gpinitsystem 结束后 Coordinator 已在运行,gpstart 拒绝重复启动——属正常现象,非故障。解法:无需处理,或改用 gpstop -a && gpstart -a 完成一次干净重启。
十三、参考链接
- Apache Cloudberry 官网:https://cloudberry.apache.org/
- Apache Cloudberry 文档(Docker Sandbox):https://cloudberry.apache.org/docs/build/sandbox/
- Apache Cloudberry 文档(Docker 构建镜像):https://cloudberry.apache.org/docs/build/build-based-on-docker/
- Apache Cloudberry 文档(安装包安装):https://cloudberry.apache.org/docs/deployment/install_cloudberry
- GitHub 发布件(2.1.0-incubating):https://github.com/apache/cloudberry/releases/tag/2.1.0-incubating