Apache Doris 容器化部署实战:从Docker到Kubernetes的完整指南

张开发
2026/6/20 23:11:44 15 分钟阅读
Apache Doris 容器化部署实战:从Docker到Kubernetes的完整指南
1. 为什么选择容器化部署Apache Doris第一次接触Apache Doris时我被它极速易用的标签吸引但真正在物理机上部署时却遇到了不少麻烦。从依赖库冲突到配置文件修改光是让一个三节点集群跑起来就花了大半天。直到尝试了容器化部署才发现原来整个过程可以如此简单高效。容器化技术为Apache Doris带来的核心优势主要体现在三个方面首先是环境一致性Docker镜像打包了所有运行时依赖彻底告别在我机器上能跑的尴尬其次是快速部署一个docker-compose命令就能拉起完整集群特别适合开发测试场景最后是资源隔离Kubernetes能够智能调度计算资源避免BE节点间相互干扰。在实际业务场景中我推荐这些情况优先考虑容器化需要频繁创建销毁的临时测试环境资源有限的本地开发环境需要快速扩展的数据分析沙箱多版本并行的功能验证环境不过也要注意生产环境部署仍需谨慎。去年我们有个客户在Kubernetes上跑生产集群因为没正确配置持久化卷一次意外重启导致数据丢失。所以接下来我会详细讲解从开发到生产的全链路部署方案包括那些容易踩坑的细节。2. 构建定制化Docker镜像2.1 准备工作硬件与基础环境在开始构建镜像前建议准备一台4核16G的构建机2核4G也能跑但会慢很多。我常用AWS的c5.xlarge实例按小时计费构建完就释放成本不到1美元。关键是要确保Docker版本≥20.10旧版本对多阶段构建支持不完善磁盘空间≥50GB一个完整镜像链大约占用15GB网络通畅需要从Apache镜像站下载二进制包对于国内用户建议配置镜像加速mkdir -p /etc/docker cat /etc/docker/daemon.json EOF { registry-mirrors: [https://registry.cn-hangzhou.aliyuncs.com] } EOF systemctl restart docker2.2 FE镜像构建实战Frontend(FE)是Doris的元数据管理中心构建时要注意使用OpenJDK 8官方镜像实测JDK 11会有兼容性问题预装MySQL客户端用于元数据初始化正确设置JVM内存参数这是我的标准构建目录结构doris-fe/ ├── Dockerfile ├── config/ │ └── fe.conf ├── scripts/ │ ├── init_fe.sh │ └── healthcheck.sh └── resources/ └── apache-doris-2.0.3-bin-fe.tar.gz关键Dockerfile片段FROM openjdk:8u342-jdk ENV FE_HOME/opt/doris/fe \ JAVA_OPTS-Xmx4G -XX:UseG1GC # 安装依赖 RUN apt-get update \ apt-get install -y mysql-client \ rm -rf /var/lib/apt/lists/* # 添加Doris二进制包 ADD resources/apache-doris-2.0.3-bin-fe.tar.gz /opt/doris RUN mv /opt/doris/apache-doris-* /opt/doris/fe # 添加配置和脚本 COPY config/fe.conf $FE_HOME/conf/ COPY scripts/* $FE_HOME/bin/ RUN chmod x $FE_HOME/bin/*.sh # 暴露端口 EXPOSE 8030 9030 9010 ENTRYPOINT [/opt/doris/fe/bin/init_fe.sh]init_fe.sh脚本需要处理首次启动的元数据初始化#!/bin/bash set -e # 检查元数据目录是否存在 if [ ! -d $FE_HOME/doris-meta ]; then echo Initializing FE metadata... $FE_HOME/bin/start_fe.sh --daemon sleep 30 mysql -h127.0.0.1 -P9030 -uroot -e ALTER SYSTEM ADD FOLLOWER ${FE_HOST}:9010 $FE_HOME/bin/stop_fe.sh fi exec $FE_HOME/bin/start_fe.sh构建命令docker build -t doris-fe:2.0.3 .2.3 BE与Broker镜像构建技巧Backend(BE)镜像构建有几个特殊注意点需要挂载存储目录到宿主机必须设置swappiness防止内存交换建议预分配大页内存BE的Dockerfile关键配置FROM openjdk:8u342-jdk ENV BE_HOME/opt/doris/be \ JAVA_OPTS-Xmx8G -XX:UseG1GC \ SWAPINESS0 RUN echo vm.swappiness $SWAPINESS /etc/sysctl.conf \ sysctl -p VOLUME [/opt/doris/be/storage]Broker镜像相对简单主要注意HDFS客户端版本要与集群一致。建议在Dockerfile里指定ARG HADOOP_VERSION3.3.4 RUN wget https://archive.apache.org/dist/hadoop/common/hadoop-$HADOOP_VERSION/hadoop-$HADOOP_VERSION.tar.gz \ tar -zxvf hadoop-$HADOOP_VERSION.tar.gz -C /opt \ ln -s /opt/hadoop-$HADOOP_VERSION /opt/hadoop3. Docker Compose编排实战3.1 单节点开发环境配置对于本地开发我最常用这个docker-compose.yml配置version: 3.8 services: fe: image: doris-fe:2.0.3 environment: FE_ID: 1 FE_SERVERS: fe1:fe:9010 ports: - 8030:8030 - 9030:9030 volumes: - fe-meta:/opt/doris/fe/doris-meta - fe-log:/opt/doris/fe/log healthcheck: test: [CMD, curl, -f, http://localhost:8030/api/bootstrap] interval: 10s timeout: 5s retries: 3 be: image: doris-be:2.0.3 environment: FE_SERVERS: fe1:fe:9010 BE_ADDR: be:9050 depends_on: fe: condition: service_healthy volumes: - be-data:/opt/doris/be/storage sysctls: vm.swappiness: 0 volumes: fe-meta: fe-log: be-data:启动命令docker-compose up -d这个配置实现了FE自动初始化元数据BE在FE就绪后自动加入集群数据持久化到Docker卷禁止内存交换3.2 多节点测试集群部署要模拟生产环境可以用docker-compose部署3FE3BE集群。关键配置在于使用host网络模式提升性能为每个节点单独配置数据卷设置正确的启动顺序示例片段services: fe1: network_mode: host environment: FE_ID: 1 FE_SERVERS: fe1:${HOST_IP}:9010,fe2:${HOST_IP}:9011,fe3:${HOST_IP}:9012 fe2: network_mode: host environment: FE_ID: 2 FE_SERVERS: fe1:${HOST_IP}:9010,fe2:${HOST_IP}:9011,fe3:${HOST_IP}:9012 depends_on: fe1: condition: service_healthy启动时需要先初始化FE masterexport HOST_IP$(hostname -I | awk {print $1}) docker-compose up -d fe1 sleep 30 # 等待master初始化 docker-compose up -d fe2 fe3 be1 be2 be34. Kubernetes生产级部署4.1 关键K8s资源配置在K8s中部署Doris需要特别注意这些配置StatefulSet用于有状态服务保证BE节点稳定的网络标识和存储Headless Service实现BE节点间直接通信PodDisruptionBudget确保维护时至少有多少个BE可用Resource Quotas限制每个Pod的资源使用典型BE的StatefulSet配置apiVersion: apps/v1 kind: StatefulSet metadata: name: doris-be spec: serviceName: doris-be replicas: 3 selector: matchLabels: app: doris-be template: metadata: labels: app: doris-be spec: containers: - name: be image: doris-be:2.0.3 env: - name: FE_SERVERS value: fe1:doris-fe:9010 resources: limits: cpu: 8 memory: 16Gi requests: cpu: 4 memory: 8Gi volumeMounts: - name: storage mountPath: /opt/doris/be/storage volumeClaimTemplates: - metadata: name: storage spec: accessModes: [ ReadWriteOnce ] storageClassName: ssd resources: requests: storage: 1Ti4.2 扩缩容与升级策略BE节点扩容kubectl scale statefulset doris-be --replicas5滚动升级kubectl patch statefulset doris-be \ --typejson \ -p[{op: replace, path: /spec/template/spec/containers/0/image, value:doris-be:2.0.4}]安全缩容步骤标记BE节点为下线状态ALTER SYSTEM DECOMMISSION BACKEND be-2.doris-be:9050等待数据迁移完成通过SHOW BACKENDS查看执行k8s缩容kubectl scale statefulset doris-be --replicas24.3 监控与运维建议部署这些监控组件Prometheus Operator收集BE/FE指标Grafana使用官方仪表板ElasticsearchFluentd集中日志收集示例ServiceMonitor配置apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: app: doris-monitor name: doris-fe spec: endpoints: - interval: 15s port: http-metrics selector: matchLabels: app: doris-fe5. 常见问题排查指南问题1FE启动失败日志显示Failed to load image解决方案检查镜像架构是否匹配x86_64镜像不能在ARM节点运行验证基础镜像下载完整性docker pull --platform linux/amd64 openjdk:8u342-jdk问题2BE节点无法注册到FE排查步骤检查网络连通性kubectl exec -it doris-be-0 -- curl http://doris-fe:8030/api/bootstrap验证FE的元数据目录权限检查BE的heartbeat服务是否正常netstat -tulnp | grep 9050问题3查询性能突然下降可能原因BE节点发生内存交换kubectl exec doris-be-0 -- grep Swap /proc/meminfo数据倾斜通过SHOW TABLET DISTRIBUTION查看磁盘IO瓶颈监控disk_io_util指标问题4K8s集群重启后BE无法恢复根治方案确保使用持久化存储卷配置合适的Pod反亲和性affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: [doris-be] topologyKey: kubernetes.io/hostname在实施容器化部署的过程中我发现最大的挑战不是技术实现而是团队协作方式的转变。开发人员需要适应不可变基础设施的理念运维则需要掌握Kubernetes的编排逻辑。我们内部总结了一套最佳实践开发环境用Docker Compose快速验证测试环境用Kubernetes模拟生产生产环境则采用混合部署方案——FE放在K8s管理BE仍然使用物理机以获得最佳I/O性能。这种渐进式的容器化策略既享受了编排调度的便利又保证了核心组件的性能稳定。

更多文章