
最近在学习Flink,想自己学课程,做项目实践下,于是搭建Flink集群,之前使用虚拟机搭建过Hadoop集群,现在我想使用Docker来部署Hadoop和Flink,正好可以回顾下Docker、Hadoop,学习Flink。
从网上搜有不少Docker搭建Hadoop集群的博客,但是Docker搭建Flink集群的比较少,Docker部署Hadoop+Flink的更少了,于是看着别人的教程,不会的问AI,终于搭起来了,于是写一下部署过程,目的一个是梳理一下,一个是希望能避免小伙伴们踩坑。
核心思路:环境标准化(镜像) → 网络隔离与互通(自定义网络) → 节点角色分工(多容器) → 配置统一化(环境变量/核心配置文件) → 集群启动与验证。
前置条件
-
宿主机环境准备
这里我是用Linux系统
-
安装 Docker,确保 Docker 服务正常运行
bashyum update yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce systemctl start docker docker -v -
准备 Hadoop、JDK 压缩包(如
hadoop-3.3.4.tar.gz、jdk-8u212-linux-x64.tar.gz),统一存放至宿主机目录,我自己建了一个D:\bigdata→ WSL 路径/mnt/d/bigdata。jdk-8u212-linux-x64.tar.gz
| 🚧
|
| 这里我踩坑,是版本一定要兼容,后边Flink的包下载也是如此,版本一定要兼容
-
-
创建 Docker 自定义网络
bashdocker network create bigdata-net # 所有 Hadoop 容器加入此网络,实现容器名互通Docker 自定义网络,后边在构建hadoop和flink时都使用此网络
-
cd 到
/mnt/d/bigdata目录下进行所有操作cd /mnt/d/bigdata
Hadoop集群配置
1.构建镜像
1.1 构建Centos镜像
通过 Dockerfile 封装 "CentOS + SSH + JDK + Hadoop" 的标准化环境,避免每个容器重复配置
-
拉取Centos镜像
bashdocker pull centos -
创建一个dockerfile,取名dockerfile-centos
bashFROM centos MAINTAINER mwf RUN yum install -y openssh-server sudo RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config RUN yum install -y openssh-clients RUN echo "root:123456" | chpasswd RUN echo "root ALL=(ALL) ALL" >> /etc/sudoers RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key RUN mkdir /var/run/sshd EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]创建centos镜像,设置密码,安装ssh服务并启动
-
构建centos镜像
bashdocker build -t="centos7-ssh" . -
构建hadoop和jdk环境的镜像
-
将下载的hadoop和jdk压缩包,放到
/mnt/d/bigdata -
构建Dockerfile,
vi DockerfilebashFROM centos7-ssh ADD jdk-8u212-linux-x64.tar.gz /usr/local/ RUN mv /usr/local/jdk1.8.0_212 /usr/local/jdk1.8 ENV JAVA_HOME /usr/local/jdk1.8 ENV PATH $JAVA_HOME/bin:$PATH ADD hadoop-3.3.4.tar.gz /usr/local RUN mv /usr/local/hadoop-3.3.4 /usr/local/hadoop ENV HADOOP_HOME /usr/local/hadoop ENV PATH $HADOOP_HOME/bin:$PATH RUN yum install -y which sudo -
创建镜像, 生成hadoop镜像
bashdocker build -t="hadoop" .
-
3.网络配置
-
前面我们自定义了名为
bigdata-net的网络,我们在启用docker时指定使用它, 启动3台hadoop镜像相同的容器,分别名为hadoop1、hadoop2、hadoop3bashdocker run -itd --network bigdata-net --name hadoop1 -p 50070:50070 -p 8088:8088 hadoop docker run -itd --network bigdata-net --name hadoop2 hadoop docker run -itd --network bigdata-net --name hadoop3 hadoop -
启动三台容器
在这里我为了方边,命令窗口我开启了3个,分别启动这3个容器,一定要记住哪一个是hadoop1,因为使用它来作为master
bashdocker exec -it hadoop1 bash docker exec -it hadoop2 bash docker exec -it hadoop3 bash -
查看网络情况,
docker network inspect bigdata-net,可以看到各自的IP地址,记录下来。bash172.18.0.2 hadoop1 172.18.0.3 hadoop2 172.18.0.4 hadoop3
4.文件配置
hosts文件配置
-
将3个IP分别写入到3台容器中的hosts文件中
vi /etc/hosts将以下内容写入到hosts文件中
172.18.0.2 hadoop1 172.18.0.3 hadoop2 172.18.0.4 hadoop3 -
检查docker容器之间是否可以ping通, ping一下就行,如果不通,检查一下是否将三个ip分别都填写到了hosts文件中
ssh免密登陆
参照参考文章,将生成的密钥分发一下即可,因为在构建hadoop镜像时已经安装了ssh服务,所以在3台hadoop容器上分别执行一下命令
bash
ssh-keygen
一路回车
ssh-copy-id -i /root/.ssh/id_rsa -p 22 root@hadoop1
输入密码,如果按我的来得话就是qwe123
ssh-copy-id -i /root/.ssh/id_rsa -p 22 root@hadoop2
输入密码,如果按我的来得话就是qwe123
ssh-copy-id -i /root/.ssh/id_rsa -p 22 root@hadoop3
输入密码,如果按我的来得话就是qwe123
| 💡 提醒:文件配置要在3台hadoop容器上分别进行配置,或者在一台上配置完成后,进行文件分发也行
检查
bash
ping hadoop1
ping hadoop2
ping hadoop3
ssh hadoop1
ssh hadoop2
ssh hadoop3
5.构建容器:hadoop集群
hadoop集群配置,主要配置的是core、hdfs、yarn、mapreduce的相关配置,这里也是需要分别在3台容器中配置,为了方便,在hadoop1上配置,然后分发到hadoop2、hadoop3中。
-
进入到hadoop1
bashdocker exec -it hadoop1 bash -
创建文件夹
这里我不知道为啥,就跟着做了,配置中要用到
bashmkdir /home/hadoop mkdir /home/hadoop/tmp /home/hadoop/hdfs_name /home/hadoop/hdfs_data -
进入hadoop配置目录
bashcd $HADOOP_HOME/etc/hadoop/ -
编辑core-site.xml
在此文件内容最后粘贴上以下内容
bash<property> <name>fs.defaultFS</name> <value>hdfs://hadoop1:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>file:/home/hadoop/tmp</value> </property> <property> <name>io.file.buffer.size</name> <value>131702</value> </property> -
编辑hdfs-site.xml
bash<property> <name>dfs.namenode.name.dir</name> <value>file:/home/hadoop/hdfs_name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:/home/hadoop/hdfs_data</value> </property> <property> <name>dfs.replication</name> <value>2</value> </property> <property> <name>dfs.namenode.secondary.http-address</name> <value>hadoop1:9001</value> </property> <property> <name>dfs.webhdfs.enabled</name> <value>true</value> </property> -
编辑mapred-site.xml
hadoop版本不一样,可能会存在此文件不存在的情况,如果不存在创建一个即可,
cp mapred-site.xml.template mapred-site.xml,在3.3.4中是存在,直接编辑即可bash<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>hadoop1:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>hadoop1:19888</value> </property> -
编辑yarn-site.xml
bash<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.auxservices.mapreduce.shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> <property> <name>yarn.resourcemanager.address</name> <value>hadoop1:8032</value> </property> <property> <name>yarn.resourcemanager.scheduler.address</name> <value>hadoop1:8030</value> </property> <property> <name>yarn.resourcemanager.resource-tracker.address</name> <value>hadoop1:8031</value> </property> <property> <name>yarn.resourcemanager.admin.address</name> <value>hadoop1:8033</value> </property> <property> <name>yarn.resourcemanager.webapp.address</name> <value>hadoop1:8088</value> </property> -
编辑slaves
把hadoop1当作主节点,hadoop2、hadoop3作为从节点
bashhadoop2 hadoop3 -
把文件拷贝到hadoop2和hadoop3上
一次执行以下命令
bashscp -r $HADOOP_HOME/ hadoop2:/usr/local/ scp -r $HADOOP_HOME/ hadoop3:/usr/local/ scp -r /home/hadoop hadoop2:/ scp -r /home/hadoop hadoop3:/
6.启动集群测试
-
启动每个容器
bashdocker exec -it hadoop1 bash docker exec -it hadoop2 bash docker exec -it hadoop3 bash -
配置hadoop sbin目录的环境变量
因为hadoop bin目录在之前创建镜像时就配好了,但是sbin目录没有配,所以要单独配置。分配为每台机器配置:
vi ~/.bashrc追加如下内容:
export PATH=$PATH:$HADOOP_HOME/sbin执行:
source ~/.bashrc -
启动hadoop
在hadoop1上执行以下命令:
-
格式化hdfs
luahdfs namenode -format -
一键启动
cssstart-all.sh
-
如果不出错,基本就配置成功,如果报错,那就将错误复制给AI,再调试下,我也是经过几次修改才配置成功的。
Flink集群配置
我这里使用的是flink-1.17.2-bin-scala_2.12.taz,直接从官网下载或者阿里云镜像网站下载即可。方法和思路与部署hadoop集群一样。
在部署时要注意一下版本兼容性(可以下载flink-shaded-hadoop-3-uber-3.2.0-10.0.jar )、网络互通、时间同步的问题。
在准备过程中,由于我没有找到flink-shaded-hadoop-3-uber-3.2.0-10.0.jar 的下载地址,以及尝试使用meven中央仓库也没有下载下来,所以找了一个另一种方法,既然本地有 hadoop-3.3.4.tar.gz,就不去单独下载那个 shaded jar 了,直接把整个 Hadoop 放进去,让 Flink 直接使用。
| 💡 问题:为什么 Flink 容器里也需要一套 Hadoop?
因为 Flink 需要"驱动"来和 Hadoop 通话。
这就好比:你要去开一辆车(Hadoop 服务),虽然车停在车库(Hadoop容器)里,但如果你想远程控制它,你手里必须有一个"车钥匙"(Hadoop 客户端库/Jar 包)。
- Flink 本身是不懂 HDFS 和 YARN 语言的。
- Flink 只是一个计算引擎。
- 当 Flink 想要把数据存到 HDFS,或者想向 YARN 申请资源运行任务时,它必须调用 Hadoop 的客户端代码 (就是那些
.jar文件)来发送请求。
如果你不把 Hadoop 放进 Flink 容器里:
Flink 就像一个没有钥匙的人站在车门外,它不知道怎么跟 YARN 说话,提交任务时就会报 ClassNotFoundException 或者 UnknownHostException。
- Hadoop 集群容器 = 服务器(负责干重活,存数据)。
- Flink 容器 = 客户端(负责写代码,发指令)。
- Flink 容器里的 Hadoop 文件 = 驱动程序/SDK(负责翻译指令,让 Flink 能跟 Hadoop 说话)。
虽然看起来有点"浪费空间"(存了两份 Hadoop 文件),但在企业级部署中,这种方式(依赖隔离)是非常标准的做法:
- 绝对兼容:Hadoop 3.3.4 的包去连 Hadoop 3.3.4 的集群,就像原配钥匙开原配锁,绝不会有版本不兼容的问题。
- 环境纯净: Flink 容器只依赖它自己内部的文件,不依赖宿主机的配置,迁移到任何机器上都能跑。
0.提前准备
确保 /mnt/d/bigdata 目录下有这些文件(你之前的截图里都有):
-
jdk-8u212-linux-x64.tar.gz -
flink-1.17.2-bin-scala_2.12.tgz -
hadoop-3.3.4.tar.gz(关键,现在要用到它) -
Hadoop 配置文件(
core-site.xml,hdfs-site.xml,yarn-site.xml)。如果没有这三个文件,就进入到hadoop1容器中,将三个文件复制发送到宿主机上的**/mnt/d/bigdata** 目录bash# 将 Master 容器里的配置文件复制到当前目录 docker cp hadoop1:/usr/local/hadoop/etc/hadoop/core-site.xml ./core-site.xml docker cp hadoop1:/usr/local/hadoop/etc/hadoop/hdfs-site.xml ./hdfs-site.xml docker cp hadoop1:/usr/local/hadoop/etc/hadoop/yarn-site.xml ./yarn-site.xml执行完后,检查你的
/mnt/d/bigdata目录下,应该能直接看到这三个文件
1.构建镜像
构建dockerfile, 名字为dockerfile-flink, 都是要在**mnt/d/bigdata 下**
bash
# 基于 centos7-ssh 镜像
FROM centos7-ssh
# 1. 安装基础依赖
RUN yum install -y which sudo vim net-tools wget
# 2. 配置 JDK
ADD jdk-8u212-linux-x64.tar.gz /usr/local/
RUN mv /usr/local/jdk1.8.0_212 /usr/local/jdk1.8
ENV JAVA_HOME=/usr/local/jdk1.8
ENV PATH=$JAVA_HOME/bin:$PATH
# 3. 【新增】配置 Hadoop (使用你本地的 hadoop-3.3.4.tar.gz)
# 这样 Flink 就能直接调用你的 Hadoop 库,版本 100% 匹配
ADD hadoop-3.3.4.tar.gz /usr/local/
RUN mv /usr/local/hadoop-3.3.4 /usr/local/hadoop
ENV HADOOP_HOME=/usr/local/hadoop
ENV HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
ENV PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
# 4. 配置 Flink
ADD flink-1.17.2-bin-scala_2.12.tgz /usr/local/
RUN mv /usr/local/flink-1.17.2 /usr/local/flink
ENV FLINK_HOME=/usr/local/flink
ENV PATH=$FLINK_HOME/bin:$PATH
# 5. 【重要】注入 Hadoop 配置文件
# 即使安装了 Hadoop,也要把集群的配置文件覆盖进去,确保连接正确
# 如果目录不存在会自动创建
RUN mkdir -p $HADOOP_HOME/etc/hadoop
# 请确保你本地目录下有这三个文件
ADD core-site.xml $HADOOP_HOME/etc/hadoop/
ADD hdfs-site.xml $HADOOP_HOME/etc/hadoop/
ADD yarn-site.xml $HADOOP_HOME/etc/hadoop/
# 6. 告诉 Flink 去哪里找 Hadoop 的库
# 这一步会自动把 Hadoop 的 jar 包加入到 Flink 的 classpath 中
ENV FLINK_CLASSPATH=$HADOOP_HOME/etc/hadoop:$HADOOP_HOME/share/hadoop/common/lib/*:$HADOOP_HOME/share/hadoop/common/*:$HADOOP_HOME/share/hadoop/hdfs/*:$HADOOP_HOME/share/hadoop/mapreduce/*:$HADOOP_HOME/share/hadoop/yarn/*
# 7. 容器启动命令
CMD ["/bin/bash", "-c", "source /etc/profile && /usr/sbin/init"]
执行
bash
docker build -f dockerfile-flink -t flink:1.17.2-hadoop333 .
2.启动flink容器
bash
docker run -it --name flink-client \
--network hadoop-br \
--add-host hadoop1:172.19.0.2 \
--privileged \
flink:1.17.2-hadoop333 /bin/bash
进入后直接运行:hdfs dfs -ls / ,如果打印是以下情况,则部署成功了
bash
jry@LAPTOP-TV74JD9D:/mnt/d/bigdata$ docker build -f dockerfile-flink -t flink:1.17.2-hadoop333 .
[+] Building 0.8s (17/17) FINISHED docker:default
=> [internal] load build definition from dockerfile-flink 0.0s
=> => transferring dockerfile: 1.69kB 0.0s
=> [internal] load metadata for docker.io/library/centos7-ssh:latest 0.1s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [ 1/12] FROM docker.io/library/centos7-ssh:latest@sha256:5d7d2768be88d5015779b81da0b8f7b8a36946b3a0759a8b545b482abcffe8e1 0.1s
=> => resolve docker.io/library/centos7-ssh:latest@sha256:5d7d2768be88d5015779b81da0b8f7b8a36946b3a0759a8b545b482abcffe8e1 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 245B 0.0s
=> CACHED [ 2/12] RUN yum install -y which sudo vim net-tools wget 0.0s
=> CACHED [ 3/12] ADD jdk-8u212-linux-x64.tar.gz /usr/local/ 0.0s
=> CACHED [ 4/12] RUN mv /usr/local/jdk1.8.0_212 /usr/local/jdk1.8 0.0s
=> CACHED [ 5/12] ADD hadoop-3.3.4.tar.gz /usr/local/ 0.0s
=> CACHED [ 6/12] RUN mv /usr/local/hadoop-3.3.4 /usr/local/hadoop 0.0s
=> CACHED [ 7/12] ADD flink-1.17.2-bin-scala_2.12.tgz /usr/local/ 0.0s
=> CACHED [ 8/12] RUN mv /usr/local/flink-1.17.2 /usr/local/flink 0.0s
=> CACHED [ 9/12] RUN mkdir -p /usr/local/hadoop/etc/hadoop 0.0s
=> CACHED [10/12] ADD core-site.xml /usr/local/hadoop/etc/hadoop/ 0.0s
=> CACHED [11/12] ADD hdfs-site.xml /usr/local/had
3.验证flink on yarn
进入flink容器,执行以下步骤
-
进入 Hadoop Master 容器启动 YARN:
docker exec -it hadoop1 bashstart-yarn.sh -
验证 YARN 是否成功
执行
jps你应该能看到
ResourceManager和NodeManager进程。 -
切换到flink容器中,提交任务到yarn
bash/usr/local/flink/bin/flink run \ -m yarn-cluster \ -yjm 1024 \ -ytm 1024 \ /usr/local/flink/examples/batch/WordCount.jar
如果运行成功,那么恭喜您,hadoop+flink部署完成了