Docker部署Hadoop+Flink集群

最近在学习Flink,想自己学课程,做项目实践下,于是搭建Flink集群,之前使用虚拟机搭建过Hadoop集群,现在我想使用Docker来部署Hadoop和Flink,正好可以回顾下Docker、Hadoop,学习Flink。

从网上搜有不少Docker搭建Hadoop集群的博客,但是Docker搭建Flink集群的比较少,Docker部署Hadoop+Flink的更少了,于是看着别人的教程,不会的问AI,终于搭起来了,于是写一下部署过程,目的一个是梳理一下,一个是希望能避免小伙伴们踩坑。

核心思路:环境标准化(镜像)网络隔离与互通(自定义网络)节点角色分工(多容器)配置统一化(环境变量/核心配置文件)集群启动与验证

前置条件

  • 宿主机环境准备

    这里我是用Linux系统

    • 安装 Docker,确保 Docker 服务正常运行

      bash 复制代码
      yum 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.gzjdk-8u212-linux-x64.tar.gz),统一存放至宿主机目录,我自己建了一个 D:\bigdata → WSL 路径 /mnt/d/bigdata

      hadoop-3.3.4.tar.gz

      jdk-8u212-linux-x64.tar.gz
      | 🚧
      |
      | 这里我踩坑,是版本一定要兼容,后边Flink的包下载也是如此,版本一定要兼容

  • 创建 Docker 自定义网络

    bash 复制代码
    docker 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" 的标准化环境,避免每个容器重复配置

  1. 拉取Centos镜像

    bash 复制代码
    docker pull centos
  2. 创建一个dockerfile,取名dockerfile-centos

    bash 复制代码
    FROM 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服务并启动

  3. 构建centos镜像

    bash 复制代码
    docker build -t="centos7-ssh" .
  4. 构建hadoop和jdk环境的镜像

    1. 将下载的hadoop和jdk压缩包,放到/mnt/d/bigdata

    2. 构建Dockerfile, vi Dockerfile

      bash 复制代码
      FROM 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
    3. 创建镜像, 生成hadoop镜像

      bash 复制代码
      docker build -t="hadoop" .

3.网络配置

  1. 前面我们自定义了名为bigdata-net 的网络,我们在启用docker时指定使用它, 启动3台hadoop镜像相同的容器,分别名为hadoop1、hadoop2、hadoop3

    bash 复制代码
    docker 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
  2. 启动三台容器

    在这里我为了方边,命令窗口我开启了3个,分别启动这3个容器,一定要记住哪一个是hadoop1,因为使用它来作为master

    bash 复制代码
    docker exec -it hadoop1 bash
    docker exec -it hadoop2 bash
    docker exec -it hadoop3 bash
  3. 查看网络情况,docker network inspect bigdata-net ,可以看到各自的IP地址,记录下来。

    bash 复制代码
    172.18.0.2 hadoop1 
    172.18.0.3 hadoop2 
    172.18.0.4 hadoop3 

4.文件配置

hosts文件配置

  1. 将3个IP分别写入到3台容器中的hosts文件中

    vi /etc/hosts

    将以下内容写入到hosts文件中

    172.18.0.2 hadoop1 172.18.0.3 hadoop2 172.18.0.4 hadoop3

  2. 检查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中。

  1. 进入到hadoop1

    bash 复制代码
    docker exec -it hadoop1 bash
  2. 创建文件夹

    这里我不知道为啥,就跟着做了,配置中要用到

    bash 复制代码
    mkdir /home/hadoop
    mkdir /home/hadoop/tmp /home/hadoop/hdfs_name /home/hadoop/hdfs_data
  3. 进入hadoop配置目录

    bash 复制代码
    cd $HADOOP_HOME/etc/hadoop/
  4. 编辑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>
  5. 编辑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>
  6. 编辑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>
  7. 编辑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>
  8. 编辑slaves

    把hadoop1当作主节点,hadoop2、hadoop3作为从节点

    bash 复制代码
    hadoop2
    hadoop3
  9. 把文件拷贝到hadoop2和hadoop3上

    一次执行以下命令

    bash 复制代码
    scp -r $HADOOP_HOME/ hadoop2:/usr/local/
    scp -r $HADOOP_HOME/ hadoop3:/usr/local/
    
    scp -r /home/hadoop hadoop2:/
    scp -r /home/hadoop hadoop3:/

6.启动集群测试

  1. 启动每个容器

    bash 复制代码
    docker exec -it hadoop1 bash
    docker exec -it hadoop2 bash
    docker exec -it hadoop3 bash
  2. 配置hadoop sbin目录的环境变量

    因为hadoop bin目录在之前创建镜像时就配好了,但是sbin目录没有配,所以要单独配置。分配为每台机器配置:

    vi ~/.bashrc

    追加如下内容:

    export PATH=$PATH:$HADOOP_HOME/sbin

    执行:

    source ~/.bashrc

  3. 启动hadoop

    在hadoop1上执行以下命令:

    1. 格式化hdfs

      lua 复制代码
      hdfs namenode -format
    2. 一键启动

      css 复制代码
      start-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 文件),但在企业级部署中,这种方式(依赖隔离)是非常标准的做法:

  1. 绝对兼容:Hadoop 3.3.4 的包去连 Hadoop 3.3.4 的集群,就像原配钥匙开原配锁,绝不会有版本不兼容的问题。
  2. 环境纯净: Flink 容器只依赖它自己内部的文件,不依赖宿主机的配置,迁移到任何机器上都能跑。

0.提前准备

确保 /mnt/d/bigdata 目录下有这些文件(你之前的截图里都有):

  1. jdk-8u212-linux-x64.tar.gz

  2. flink-1.17.2-bin-scala_2.12.tgz

  3. hadoop-3.3.4.tar.gz (关键,现在要用到它)

  4. 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

进入flink容器,执行以下步骤

  1. 进入 Hadoop Master 容器启动 YARN:

    docker exec -it hadoop1 bash

    start-yarn.sh

  2. 验证 YARN 是否成功

    执行jps

    你应该能看到 ResourceManagerNodeManager 进程。

  3. 切换到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部署完成了

参考文章

相关推荐
小锋学长生活大爆炸11 小时前
【教程】免Root在Termux上安装Docker
运维·docker·容器
进击切图仔11 小时前
常用 Docker 命令备份
运维·docker·容器
岁岁种桃花儿14 小时前
Flink从入门到上天系列第三篇:Flink集群化部署
大数据·flink
德育处主任15 小时前
『NAS』将魂斗罗马里奥塞进NAS里
前端·javascript·docker
Mr.小海16 小时前
Docker 底层解析与生产环境实战指南
java·docker·eureka
流氓也是种气质 _Cookie18 小时前
Linux上安装Docker
linux·redis·docker
小锋学长生活大爆炸19 小时前
【教程】查看docker容器的TCP连接和带宽使用情况
tcp/ip·docker·容器
ccino .20 小时前
【Drupal文件上传导致跨站脚本执行(CVE-2019-6341)】
运维·网络安全·docker·容器
Francek Chen20 小时前
【大数据存储与管理】分布式文件系统HDFS:01 分布式文件系统
大数据·hadoop·分布式·hdfs·架构