Docker部署单机Flink:从环境搭建到作业运行全指南

一、为什么选择Docker部署单机Flink?

Apache Flink作为一款高性能流批一体计算框架,在实时数据处理领域应用广泛。单机部署模式适合开发测试、小规模数据处理或学习场景,而Docker的轻量化、隔离性和可移植性特点,使其成为快速部署Flink的理想选择。通过Docker,用户可以:

  1. 避免环境依赖问题:无需手动安装Java、Scala等运行环境,镜像已封装所有依赖。
  2. 快速启动与销毁:容器启动时间短,适合临时测试或CI/CD流程。
  3. 资源隔离:通过CPU/内存限制防止Flink进程占用过多主机资源。
  4. 版本一致性:确保开发、测试和生产环境使用相同的Flink版本。

二、环境准备与镜像选择

1. 安装Docker

在部署前,需确保主机已安装Docker。以Ubuntu为例:

  1. # 卸载旧版本(如有)
  2. sudo apt-get remove docker docker-engine docker.io containerd runc
  3. # 安装依赖
  4. sudo apt-get update
  5. sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
  6. # 添加Docker官方GPG密钥
  7. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  8. # 添加稳定版仓库
  9. sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  10. # 安装Docker CE
  11. sudo apt-get update
  12. sudo apt-get install docker-ce docker-ce-cli containerd.io
  13. # 验证安装
  14. sudo docker run hello-world

2. 选择Flink Docker镜像

Apache Flink官方提供了预构建的Docker镜像,可通过Docker Hub获取:

  • 基础镜像flink:latest(默认包含JobManager和TaskManager)
  • 版本指定:如flink:1.17-scala_2.12-java11
  • 轻量级选项flink:1.17-jre11(仅包含JRE,体积更小)

推荐使用明确版本号的镜像以避免兼容性问题,例如:

  1. docker pull flink:1.17-scala_2.12-java11

三、单机模式部署方案

方案1:启动独立集群(JobManager + TaskManager)

  1. docker run --name flink-standalone \
  2. -p 8081:8081 \
  3. -p 6123:6123 \
  4. -t flink:1.17-scala_2.12-java11 standalone-job

参数说明

  • -p 8081:8081:暴露Flink Web UI端口
  • -p 6123:6123:RPC通信端口
  • standalone-job:以独立集群模式启动(默认包含1个JobManager和1个TaskManager)

方案2:仅启动TaskManager(连接外部JobManager)

若需将TaskManager连接到已有JobManager(如K8s部署的集群),可使用:

  1. docker run --name flink-taskmanager \
  2. -e JOB_MANAGER_RPC_ADDRESS=jobmanager-host \
  3. -t flink:1.17-scala_2.12-java11 taskmanager

方案3:自定义配置(推荐)

通过挂载配置文件和日志目录实现更灵活的管理:

  1. # 创建本地配置目录
  2. mkdir -p ./flink/conf ./flink/log
  3. # 下载默认配置模板
  4. curl -o ./flink/conf/flink-conf.yaml https://raw.githubusercontent.com/apache/flink/master/flink-conf.yaml
  5. # 启动容器(示例配置)
  6. docker run --name flink-custom \
  7. -v $(pwd)/flink/conf:/opt/flink/conf \
  8. -v $(pwd)/flink/log:/opt/flink/log \
  9. -p 8081:8081 \
  10. -e TASK_MANAGER_NUMBER_OF_TASK_SLOTS=4 \
  11. -t flink:1.17-scala_2.12-java11 standalone-job

关键配置项

  • taskmanager.numberOfTaskSlots:控制并行度(通过环境变量或flink-conf.yaml设置)
  • jobmanager.rpc.address:若需远程连接JobManager
  • web.submit.enable:是否允许通过Web UI提交作业

四、运行Flink作业示例

1. 通过Web UI提交作业

  1. 访问 http://localhost:8081
  2. 上传JAR包(如官方示例flink-examples-batch_2.12-1.17.0.jar
  3. 配置作业参数(如输入路径、并行度)
  4. 点击”Submit”运行

2. 通过CLI提交作业(容器内执行)

  1. # 进入容器
  2. docker exec -it flink-standalone bash
  3. # 运行示例作业(WordCount)
  4. /opt/flink/bin/flink run \
  5. -c org.apache.flink.examples.java.wordcount.WordCount \
  6. /opt/flink/examples/batch/WordCount.jar \
  7. --input /opt/flink/README.txt \
  8. --output /tmp/result.txt

3. 挂载本地作业目录

  1. docker run --name flink-job \
  2. -v $(pwd)/jobs:/opt/flink/jobs \
  3. -p 8081:8081 \
  4. -t flink:1.17-scala_2.12-java11 standalone-job
  5. # 容器内执行
  6. /opt/flink/bin/flink run /opt/flink/jobs/your-job.jar

五、高级配置与优化

1. 资源限制

通过--cpus--memory参数限制容器资源:

  1. docker run --name flink-restricted \
  2. --cpus=2 \
  3. --memory=4g \
  4. -p 8081:8081 \
  5. -t flink:1.17-scala_2.12-java11 standalone-job

2. 日志管理

配置日志滚动策略(修改flink-conf.yaml):

  1. # 日志目录
  2. env.log.dir: /opt/flink/log
  3. # 按时间或大小滚动
  4. log4j.logger.akka=INFO, akkaFile
  5. log4j.appender.akkaFile=org.apache.log4j.RollingFileAppender
  6. log4j.appender.akkaFile.File=${env.log.dir}/akka.log
  7. log4j.appender.akkaFile.MaxFileSize=10MB
  8. log4j.appender.akkaFile.MaxBackupIndex=10

3. 检查点配置(容错)

启用检查点以支持故障恢复:

  1. state.backend: rocksdb
  2. state.checkpoints.dir: file:///tmp/flink/checkpoints
  3. state.savepoints.dir: file:///tmp/flink/savepoints
  4. execution.checkpointing.interval: 10s

六、常见问题与解决方案

1. 端口冲突

现象8081端口被占用
解决:修改宿主端口映射或停止冲突进程

  1. # 查找占用端口的进程
  2. sudo lsof -i :8081
  3. # 修改Docker端口映射
  4. docker run -p 8082:8081 ...

2. 内存不足

现象:容器因OOM被杀死
解决:增加内存限制或调整Flink堆内存

  1. # 在flink-conf.yaml中配置
  2. taskmanager.memory.process.size: 2048m
  3. jobmanager.memory.process.size: 1024m

3. 作业提交失败

现象ClassNotFoundException或版本不匹配
解决:确保作业JAR与Flink版本兼容,或使用--classpath指定依赖

七、总结与扩展建议

通过Docker部署单机Flink可显著简化环境搭建流程,尤其适合以下场景:

  • 快速验证数据处理逻辑
  • 本地开发调试
  • 教学演示

扩展建议

  1. 多节点集群:使用docker-compose或K8s Operator部署分布式集群
  2. CI/CD集成:在流水线中自动启动Flink容器运行测试作业
  3. 监控集成:连接Prometheus+Grafana实现指标可视化

附:完整docker-compose.yml示例

  1. version: '3.8'
  2. services:
  3. jobmanager:
  4. image: flink:1.17-scala_2.12-java11
  5. ports:
  6. - "8081:8081"
  7. command: standalone-job
  8. volumes:
  9. - ./jobs:/opt/flink/jobs
  10. - ./conf:/opt/flink/conf
  11. environment:
  12. - JOB_MANAGER_RPC_ADDRESS=jobmanager
  13. taskmanager:
  14. image: flink:1.17-scala_2.12-java11
  15. depends_on:
  16. - jobmanager
  17. command: taskmanager
  18. environment:
  19. - JOB_MANAGER_RPC_ADDRESS=jobmanager
  20. volumes:
  21. - ./log:/opt/flink/log

通过以上步骤,开发者可在10分钟内完成从环境准备到作业运行的全流程,极大提升开发效率。