Docker 容器化与部署实战
基于 olad_data_ap 项目 infra/docker-compose.yml
来源:olad_data_ap/DEVELOPMENT.md
面试定位:证明你有现代化数据平台的完整部署和运维能力
〇、学习目标与面试关联
0.1 为什么要学习 Docker 部署?
| 维度 |
说明 |
| 面试价值 |
交易所 BI 岗位需要快速搭建数据环境,Docker 是基础能力 |
| 项目价值 |
olad_data_ap 用 Docker 编排 8 个组件,一键启动,降低环境配置成本 |
| 生产价值 |
证明你不仅会写 SQL/代码,还能搭建完整的数据平台基础设施 |
0.2 与交易所面试的直接关系
交易所场景:
- 需要快速搭建测试环境(交易数据回放、风控测试)
- 需要本地开发环境(ClickHouse/Spark/Airflow 调试)
- 需要演示 Demo(Risk Dashboard、指标字典)
- 需要隔离环境(不同项目/不同版本不冲突)
你的回答:
"我用 Docker Compose 编排了 ClickHouse、PostgreSQL、Redis、
Airflow、Prometheus/Grafana 等 8 个组件,通过 Makefile 封装
了启动、停止、健康检查等命令。这让我能快速搭建完整的数据平台
环境,也保证了开发、测试、演示环境的一致性。"
0.3 生产环境会用 Docker 吗?
会,而且很普遍,但有分层:
| 场景 |
方案 |
为什么 |
| 开发环境 |
Docker Compose |
快速启动、环境一致、方便调试 |
| 测试环境 |
Kubernetes(K8s)或 Docker Swarm |
需要多实例、高可用 |
| 生产环境 |
Kubernetes(主流)或裸机 |
需要自动扩缩容、服务治理、灰度发布 |
| 数据平台 |
K8s + 专有组件(ClickHouse Operator) |
数据组件有状态,需要特殊处理 |
0.4 Docker 的优劣势与生产痛点
✅ 优势
| 优势 |
说明 |
面试加分点 |
| 环境一致性 |
开发/测试/生产用同一镜像 |
"在我的笔记本上和在线上行为一致" |
| 快速启动 |
秒级启动 vs VM 分钟级 |
"调试 Airflow DAG 可以秒级重启" |
| 资源隔离 |
Namespace + Cgroup |
"ClickHouse 和 Airflow 互不影响" |
| 版本管理 |
镜像 tag 管理版本 |
"可以随时回退到 v1.0 的 ClickHouse" |
| 生态丰富 |
Docker Hub、Compose、Swarm |
"社区有大量现成镜像" |
❌ 生产痛点与规避方案
| 痛点 |
场景 |
规避方案 |
面试回答示例 |
| 有状态组件管理难 |
ClickHouse/PG/Redis 数据持久化 |
用 Volume 或 Bind Mount;生产用 Operator |
"我用 ./data/clickhouse 绑定数据目录,但生产会改用 ClickHouse Operator 管理 StatefulSet" |
| 网络性能损耗 |
高吞吐场景(如实时 Flink) |
用 host 网络模式或 CNI 优化 |
"生产环境 Flink 会用 host 网络减少 NAT 开销" |
| 日志收集复杂 |
容器日志分散、易丢失 |
用 Loki/ELK 集中采集 |
"我项目中用 Loki 采集所有容器日志,Grafana 统一查看" |
| 监控指标缺失 |
容器内部指标看不到 |
用 Prometheus + exporters |
"每个服务都暴露 /metrics,Prometheus 定期抓取" |
| 镜像体积大 |
Airflow 镜像 1GB+ |
多阶段构建、Alpine 基础镜像 |
"我用 alpine 基础镜像,从 1.2GB 降到 350MB" |
| 编排能力有限 |
Compose 不支持自动扩缩容 |
生产迁移到 K8s + Helm |
"开发用 Compose 快速验证,生产用 K8s 管理高可用" |
| 安全隔离不足 |
容器共享内核 |
用 rootless 模式、安全策略 |
"生产会用非 root 用户运行容器,限制权限" |
🎯 面试高频回答模板
"我们项目用 Docker Compose 做开发环境编排,
优点是快速启动、环境一致、方便调试。
但生产环境会迁移到 Kubernetes,因为:
1. 有状态组件(ClickHouse/PG)需要 Operator 管理
2. 需要自动扩缩容、健康检查、滚动更新
3. 需要更好的服务治理、灰度发布能力
Docker Compose 是开发阶段的利器,K8s 是生产阶段的标配。"
我的感悟
印象中生产使用场景:1. 调度期生成的实例使用容器来快速构建; 2. flink集群使用k8s快速部署
对于业务方来说是透明无感的
一、项目中的组件
1.1 基础设施组件
| 组件 |
作用 |
面试关联 |
| ClickHouse |
OLAP 引擎,存储 ODS/DWD/DWS/ADS |
核心,OLAP 选型 |
| PostgreSQL |
元数据存储(metric-svc / admin-svc) |
字典/租户 |
| Redis |
缓存(看板/BFF/AI) |
缓存策略 |
| MinIO |
S3 兼容对象存储 |
备份/冷数据 |
| Airflow |
任务调度 |
DAG 编排 |
| Prometheus |
指标采集 |
可观测性 |
| Grafana |
监控面板 |
可视化 |
| Loki |
日志采集 |
日志聚合 |
1.2 编排架构
# infra/docker-compose.yml 核心配置
services:
# ========== 数据层 ==========
clickhouse:
image: clickhouse/clickhouse-server:24.5
ports:
- "8123:8123" # HTTP
- "9000:9000" # TCP(内部)
volumes:
- ./data/clickhouse:/var/lib/clickhouse
environment:
CLICKHOUSE_DB: ads
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: ads_meta
POSTGRES_USER: ads
POSTGRES_PASSWORD: ads
volumes:
- ./data/postgres:/var/lib/postgresql/data
redis:
image: redis:7-alpine
command: redis-server --maxmemory 512mb --maxmemory-policy allkeys-lru
# ========== 对象存储 ==========
minio:
image: minio/minio:latest
ports:
- "9000:9000" # API
- "9001:9001" # Console
environment:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: minio123
command: server /data --console-address ":9001"
# ========== 调度 ==========
airflow-webserver:
image: apache/airflow:2.8
environment:
AIRFLOW__CORE__EXECUTOR: LocalExecutor
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://ads:ads@postgres/ads_meta
volumes:
- ./dags:/opt/airflow/dags
depends_on:
- postgres
# ========== 可观测性 ==========
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./infra/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana:latest
ports:
- "3001:3000"
volumes:
- ./infra/grafana/provisioning:/etc/grafana/provisioning
loki:
image: grafana/loki:latest
二、核心概念
2.1 Docker vs Docker Compose
Docker:单容器管理
- docker run -d redis:7 # 运行一个容器
- docker ps # 查看运行中的容器
- docker logs <container_id> # 查看日志
- docker exec -it <id> sh # 进入容器
Docker Compose:多容器编排
- docker-compose up -d # 启动所有服务
- docker-compose ps # 查看所有服务状态
- docker-compose logs -f # 实时日志
- docker-compose down # 停止所有服务
- docker-compose up --build # 重新构建镜像
2.2 常用命令
# 项目中 Makefile 封装的命令
make up # docker-compose up -d
make ps # docker-compose ps
make logs # docker-compose logs -f
make down # docker-compose down
make clean # docker-compose down -v(删除数据卷)
# 常见问题排查
docker logs <service_name> # 查看服务日志
docker exec -it <service_name> clickhouse-client # 进 CH 调试
docker stats # 查看资源占用
docker network inspect olad_data_ap_default # 查看网络
三、面试高频问题
Q1: Docker 容器和虚拟机的区别?
答:
| 维度 | VM | Docker 容器 |
|------|-----|------------|
| 启动时间 | 分钟级 | 秒级 |
| 资源占用 | 完整 OS,GB 级 | 共享内核,MB 级 |
| 隔离性 | 完全隔离 | 共享内核,进程级隔离 |
| 可移植性 | 依赖 Hypervisor | 镜像,到处运行 |
| 性能 | 有损耗 | 接近原生 |
面试加分点:
- 容器使用 Linux Namespace + Cgroup 实现隔离
- 镜像是分层叠加(UnionFS / OverlayFS)
- Docker Hub 生态丰富
Q2: Docker 网络模式?
答:四种模式
1. bridge(默认):容器间通信,与宿主机隔离
2. host:容器共享宿主机网络栈
3. overlay:跨主机容器通信(Swarm)
4. none:禁用网络
项目中用:
- 默认 bridge 模式
- 通过 networks 指定自定义网络
- 外部访问通过 ports 映射
Q3: Docker 数据持久化?
答:两种方式
1. Volume:Docker 管理的数据卷
- docker volume create mydata
- 适合数据迁移和备份
2. Bind Mount:绑定宿主机目录
- -v /host/path:/container/path
- 适合开发环境,文件实时同步
项目中用:
- ./data/clickhouse 绑定到 /var/lib/clickhouse
- ./dags 绑定到 /opt/airflow/dags
Q4: 如何排查容器启动失败?
步骤:
1. docker-compose ps 查看状态
2. docker-compose logs <service> 查看错误日志
3. docker inspect <container_id> 查看详细信息
常见问题:
- 端口冲突:Bind for :::9000 failed
→ 修改 CH_TCP_PORT 或停掉 MinIO
- 权限问题:Permission denied
→ chown -R 101:101 /data
- 依赖未就绪:Airflow init 失败
→ 等 PG 就绪后重起,或加 depends_on
四、项目实践 Checklist
相关文档:
- ClickHouse 深度解析
- Redis 缓存策略(待补充)
- olad_data_ap DEVELOPMENT.md