[Docker & Hadoop] 使用 Docker 搭建 Hadoop 集群
java8 hadoop3.2.4 centos:centos7.9.2009 jdk1.8.0_161
2024-12-18:建议照旧到云服务上操纵,使用单个docker操纵,由于在web界面操纵下载文件是hadoop会跳转下载地址,会产生很多网络方面的问题
一些根本的关于 docker 的命令不在此先容,废话没有直接开始
搭建过程中你会使用到的包
链接: https://pan.baidu.com/s/1Y371SpxO7tUe88GFYP38zA?pwd=ket9 提取码: ket9
下面是打包的 docker 镜像,使用这个镜像你可以跳过前三个步骤,这个是 AMD64架构的,不确定别的架构下是否能使用。
!如果你要使用我的 docker 镜像,要自己提前创建一个 hadoop 的 docker内网,不要使用文档中的192.168.1.101-192.168.1.103这三个 ip,而是用172.18.1.1-172.18.1.3这个 ip范围。
- docker pull kunghuang/hadoop-docker:v1
复制代码- docker network create \
- --driver bridge \
- --subnet=172.18.1.0/24 \
- --ip-range=172.18.1.0/24 \
- hadoop
复制代码 正片开始
一、创建出容器
- docker run --privileged=true --name=hadoop001 --platform=linux/amd64 -p 9870:9870 -p 8020:8020 -p 2222:22 -dit centos:centos7.9.2009 /sbin/init
- -- 9870&8020两个端口开放给 haoop
- -- 2222端口方便后面启动 ssh 用 xssh 等工具连接用
- -dit 表示交互式且后台运行,少了 -it 容器会自动停止
- --privileged=true 和 /sbin/init 表示特权启动,后面可能需要实用到 service 命令,需要由这个权限才可以
- 没有上面这个,再使用时会报 PID 1 的错误哦
-
- #对于Mac用户 m系列芯片加上 win&liunx应该用没试过
复制代码 二、为容器配备java和hadoop环境
将 jdk 和 hadoop 从主机复制到该容器中
- docker cp <jdk路径> <容器id>:<容器路径>
- docker cp <hadoop路径> <容器id>:<容器路径>
- docker cp jdk-8u161-linux-x64.tar.gz 63a:/root
- docker cp hadoop-3.2.4.tar.gz 63a:/root
- #进入容器
- docker exec -it hadoop001 bash
- #两个压缩文件
- tar -zxvf xxxxx
复制代码 在 /etc/profile.d/ 下创建文件 mydev.sh
vim mydex.sh 文件内容如下
- # Java
- export JAVA_HOME=<jdk在容器的路径>
- export PATH=$PATH:$JAVA_HOME/bin
- # Hadoop
- export HADOOP_HOME=<hadoop在容器的路径>
- export PATH=$PATH:$HADOOP_HOME/bin
- export PATH=$PATH:$HADOOP_HOME/sbin
- # Constant
- export HDFS_NAMENODE_USER=root
- export HDFS_DATANODE_USER=root
- export HDFS_SECONDARYNAMENODE_USER=root
- export YARN_RESOURCEMANAGER_USER=root
- export YARN_NODEMANAGER_USER=root
- ######################################################
- #如果你和我一样放在 root 下了直接用下面的
- # Java
- export JAVA_HOME=/root/jdk1.8.0_161
- export PATH=$PATH:$JAVA_HOME/bin
- # Hadoop
- export HADOOP_HOME=/root/hadoop-3.2.4
- export PATH=$PATH:$HADOOP_HOME/bin
- export PATH=$PATH:$HADOOP_HOME/sbin
- # Constant
- export HDFS_NAMENODE_USER=root
- export HDFS_DATANODE_USER=root
- export HDFS_SECONDARYNAMENODE_USER=root
- export YARN_RESOURCEMANAGER_USER=root
- export YARN_NODEMANAGER_USER=root
复制代码 第一第二个是两个环境,末了一个是一些常量,在启动集群的时候,还要用到这些常量,否则可能启动失败
末了实行 source /etc/profile 使配置文件见效,输入java -version 可以看到下面内容,你就成功了。
- java version "1.8.0_161"
- Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
- Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)
复制代码 三、配置ssh服务
我们必要让各个容器产生联系,才气构成集群,但默认环境下,容器并不能被其他容器直接通过 ssh 访问,以是这里必要配置
- # 1)设置密码
- passwd root
- # 2)安装 ssh
- yum install -y openssh
- yum install -y openssh-server
- yum install -y openssh-clients
-
- #出问题执行下面这些操作
- #建或编辑 /etc/yum.repos.d/CentOS-Base.repo 文件。
- #将文件内容替换为阿里云提供的 CentOS 7 源配置:下面这段
- [base]
- name=CentOS-$releasever - Base - mirrors.aliyun.com
- failovermethod=priority
- baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
- gpgcheck=1
- gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- [updates]
- name=CentOS-$releasever - Updates - mirrors.aliyun.com
- failovermethod=priority
- baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
- gpgcheck=1
- gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- [extras]
- name=CentOS-$releasever - Extras - mirrors.aliyun.com
- failovermethod=priority
- baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
- gpgcheck=1
- gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- #再运行上面三条命令即可
-
- # 3)修改配置,【vim也需要安装】
- vim /etc/ssh/sshd_config
- PermitRootLogin yes
- PasswordAuthentication yes
- #这两个配置允许外网通过 ssh 连接该服务器(容器)
- # 4) 如果发现不是这样,就修改它,同时需要重启 ssh 是指生效
- service sshd restart
- 同样该命令可能不存在,就下载它
- yum install initscripts
- #********不过这样好像不行,反正 Mac 上不行,用下面的方法********
- #1、生成密钥
- ssh-kengen -A
- #2、启动sshd
- /usr/sbin/sshd -D &
- #3、检验,输出两行说明成功
- ps aux | grep sshd
- #4、开机自启,容器环境下 systemctr 可能不可用
- echo '/usr/sbin/sshd -D &' >> /root/.bashrc
复制代码 通过上面一顿操纵,外网已经可以通过 ssh 访问该容器了,我们可以试试:
- 1) 首先在容器内,使用 ifconfig 查看 IP 地址
- ifconfig
- 没有这个命令的话,就下载他[doge]
- yum install net-tools
- 2) 在服务器本机中,通过 ssh 访问该 IP 地址尝试连接
- ssh <IP>
- 然后要求输入密码,就是上面我们已经设置了的密码
- 3)也可以在宿主机子上登录,用 2222端口
- ssh -p 2222 root@127.0.0.1
复制代码 四、由该容器克隆出多个容器
起主要克隆出多个容器,就必要将该容器打包成镜像,再由该镜像创建出多个容器,步骤如下
- 1) 创建镜像
- docker commit -a='hk' -m='Hadoop cluster example through docker by IceClean' 2dd hadoop-docker
- 2) 由该进项克隆多个容器模拟集群(这里以三台服务器的集群为例)
- !!! 后来补充:hadoop002 要用到的端口是: 8088,主机端口自定义
- docker run --privileged=true --name=hadoop002 -p 8088:8088 -dit hadoop-docker /sbin/init
-
- !!! 后来补充:hadoop003 要用到的端口是: 9868,主机端口自定义
- docker run --privileged=true --name=hadoop003 -p 9868:9868 -dit hadoop-docker /sbin/init
复制代码 在这些容器生成好后,为它们配置一个 IP 地址映射
以后就不用去记住每一个容器的 IP 地址了
但同时由于 docker 网桥模式的特性,当容器重启时,会按次序为该容器分配一个 IP,使得该 IP 地址不是固定的会变化,这对我们已经做的映射非常不友好,以是接下来的第一步,是为每个容器固定一个 IP 地址(借助 docker network)
- #步骤 1:创建自定义网络(如果需要)
- #如果您还没有一个合适的 Docker 网络,可以创建一个新的桥接网络,并指定子网和网关等参数。
- docker network create --subnet=192.168.1.0/24 --gateway=192.168.1.1 hadoop
-
- docker network ls
-
- #步骤 2:将运行中的容器连接到新网络并指定 IP 地址
- docker network connect --ip 192.168.1.101 hadoop hadoop001
- docker network connect --ip 192.168.1.102 hadoop hadoop002
- docker network connect --ip 192.168.1.103 hadoop hadoop003
-
- #步骤 3:验证网络连接
- docker exec hadoop001 ip addr show
-
- docker inspect hadoop001
复制代码 这样就成功地为每一个容器固定好 IP 地址了,接下来就可以在容器内配置映射了
- 1) 在每一台容器中,修改 hosts 文件
- vim /etc/hosts
- 比如说我的,就在文件中增加:
- 192.168.1.101 hadoop001
- 192.168.1.102 hadoop002
- 192.168.1.103 hadoop003
- 3) 配置完毕后,我们就可以直接通过名字轻松连接各个容器了,如:
- ssh hadoop003
复制代码 五、为每个容器配置免密登录
容器之间虽然能正常互相毗连了,但如果每次都必要输入密码,那是及其不方便的
再而,到背面启动集群的时候,如果没有免密登录,既有可能会失败噢
以是我们可以为各个集群中的容器配置免密登录,实现各个容器之间的顺畅毗连
起首我们来了解一下免密登录的原理(以 hadoop001 和 hadoop002 为例)
在 hadoop001 中,可以使用 ssh-key-gen 生成密钥
—— 分为公钥和私钥,私钥保密,公钥可以给别人
然后如果将 hadoop001 的公钥拷贝给 hadoop002
—— 通过命令拷贝,该公钥会保存在 hadoop002 中的 Authorized_keys 中
以后 hadoop001 想要毗连 hadoop002,就可以直接通过公钥毗连,无需密码
以是我们可以知道,免密登录的实现,就是将目的服务器的公钥拷贝到对方的服务器上,这样对方即可免密登录该目的服务器,而如果两台服务器要互相免密登录,当然就要互相拷贝到对方的公钥啦~ 开始行动
- 1) 首先在 hadoop001 中,生成公钥和私钥(一路回车到底就行了,不需要输入内容)
- ssh-keygen -t rsa
- 其中 id_rsa 为私钥,id_rsa.pub 为公钥
- 2) 将 hadoop001 的公钥拷贝到 hadoop002
- ssh-copy-id hadoop002
复制代码 出现提示说明添加成功了,以后我们可以直接通过 ssh hadoop002 毗连 hadoop002
注意啦:公钥也必要拷贝到本服务器(如 hadoop001 将自己的公钥拷贝到 hadoop001)不然自己五大免密登录自己哦
然后对于其他的容器也是这样做,把每个容器的公钥都拷贝到自己以及别的两台服务器上,就实现了三台服务器互相的免密登录,完毕~
六、编写集群配置
前面做足了准备工作,把每一个容器都配置好了
如今要正式开始集群的搭建啦,起首是集群的配置:
安排一下集群的部署:
hadoop001hadoop002hadoop003HDFSNameNode
DataNodeDataNodeSecondaryNameNode
DataNodeYARNNodeManagerResourceManager
NodeManagerNodeManager hadoop001 兼任主节点,配置 NameNode
hadoop002 兼任资源管理,配置 ResourceManager
hadoop003 兼任备份结点,配置 SecondaryNameNode
接着按照这个规划,修改 hadoop 配置文件
先说明一下各个配置文件及其位置(~ 表现 hadoop 所在目录)
系统配置文件:~/share/doc/hadoop
用户自定义配置文件:~/etc/hadoop
必要我们自定义配置的文件在 etc 目录下,总共有四个,分别是:
core-site.xml,
① 配置 hadoop001
起首到主节点 hadoop001 里边,配置 core-site.xml
下面是我自己的配置,必要配置两个东西
① 将 hadoop001 设置为主节点,端口推荐为 8020
② 将数据的默认存储位置改为 hadoop 目录下的 data 文件夹(如果不存在的话,会自动创建)
- <configuration>
- <!-- 指定 NameNode 地址 -->
- <property>
- <name>fs.defaultFS</name>
- <value>hdfs://hadoop001:8020</value>
- </property>
- <!-- 使用 root用户操作文件 -->
- <property>
- <name>hadoop.http.staticuser.user</name>
- <value>root</value>
- </property>
- <!-- 校验 -->
- <property>
- <name>dfs.permissions.enabled</name>
- <value>false</value>
- </property>
- <!-- 指定 hadoop 数据存放的目录 -->
- <property>
- <name>hadoop.tmp.dir</name>
- <value>/root/hadoop-3.2.4/data</value>
- </property>
- </configuration>
复制代码 然后配置 hdfs-site.xml
- <configuration>
- <!-- nn web 端访问地址 -->
- <property>
- <name>dfs.namenode.http-address</name>
- <value>hadoop001:9870</value>
- </property>
- <!-- 2nn web 端访问地址-->
- <property>
- <name>dfs.namenode.secondary.http-address</name>
- <value>hadoop003:9868</value>
- </property>
- <!-- 添加 web 端访问文件的权限 -->
- <property>
- <name>dfs.webhdfs.enabled</name>
- <value>true</value>
- </property>
- </configuration>
复制代码 然后是 yarn-site.xml
- <configuration>
- <!-- 指定 MR 走 shuffle -->
- <property>
- <name>yarn.nodemanager.aux-services</name>
- <value>mapreduce_shuffle</value>
- </property>
- <!-- 指定 ResourceManager 的地址 -->
- <property>
- <name>yarn.resourcemanager.hostname</name>
- <value>hadoop002</value>
- </property>
- <!-- 环境变量的继承 -->
- <property>
- <name>yarn.nodemanager.env-whitelist</name>
- <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
- </property>
- </configuration>
复制代码 末了配置 mapred-site.xml
- <configuration>
- <!-- 指定 MapReduce 程序运行在 Yarn 上 -->
- <property>
- <name>mapreduce.framework.name</name>
- <value>yarn</value>
- </property>
- </configuration>
复制代码 ② 将编写好的四个配置文件,同步到其他两台服务器上(hadoop002,hadoop003)
只需实行下面这一句,就能将四个配置文件远程复制到别的一个容器中
由于之前设置了免密登录,以是它可以直接远程复制,而不必要输入密码,可以很方便地在哥哥容器之间拷贝文件(hadoop003 也同理)
- scp core-site.xml hdfs-site.xml yarn-site.xml mapred-site.xml root@hadoop002:/root/hadoop-3.2.4/etc/hadoop
复制代码 ③ 配置 workers
同样是在 hadoop001 中,修改文件 /etc/hadoop/workers
将里边的内容去掉(把 localhost 删掉)然后换成我们的三个容器:
注意:行末不能有空格,以及不能有空行的出现
- hadoop001
- hadoop002
- hadoop003
复制代码 然后将该文件同步到其他两个容器
- scp workers root@hadoop002:/root/hadoop-3.1.3/etc/hadoop/
- scp workers root@hadoop003:/root/hadoop-3.1.3/etc/hadoop/
复制代码 七、启动集群
第一次启动时,必要举行初始化(以后就不用了,再初始化会清空数据哦)
初始化完毕后,在配置文件指定的目录下,就会生成 data 和 logs 两个文件
———— 接下来正式启动
① 起首启动 DFS:
在 Hadoop001 中操纵(配置了 NameNode 的)
进入 sbin,实行 ./start-dfs.sh 命令
然后实行 jps 看是否启动成功,和下图一样说明成功了
如果上面的配置都没有堕落的话,这里应该是很顺遂就启动的了
可能出现的错误有:
1、没有配置免密登录,权限不足导致启动失败
2、只把公钥给了其他容器,没有给自己,也会导致权限不足的失败
以是说,免密登录在这里,照旧非常非常紧张的!!!
② 然后启动 YARN:
在 Hadoop002 中操纵(配置了 ResourceManager的)
依旧在 sbin 中实行 ./start-yarn.sh
如果启动完毕的话,就实行 jps 检查下各个容器是否如我们规划的那样配置完毕
像我下面这种环境就是 OK 的:
③ 测试集群
访问 9870,9868 以及 8088 端口打
分别对应 NameNode SecondaryNameNode ResourceManager,就可以了。
!!!
如果你没有成功,可能是网络问题,可以尝试用 ng 加一层映射(我就是,原因没弄明白)
步骤 1:创建或毗连到现有的 Docker 网络【用前面的 hadoop 就可以】
步骤 2:准备 Nginx 配置文件
创建一个自定义的 Nginx 配置文件 nginx.conf,其中包含所需的反向代理规则。
nginx.conf 示例【映射的端口都在原有的端口上+1,其实一开始直接拉 hadoop 容器不指定端口,就可以直接用默认的端口】
- events {
- worker_connections 1024;
- }
- http {
- upstream hadoop_9870 {
- server 172.18.1.1:9870;
- }
- upstream hadoop_9868 {
- server 172.18.1.3:9868;
- }
- upstream hadoop_8088 {
- server 172.18.1.2:8088;
- }
- upstream hadoop_9864 {
- server 172.18.1.1:9864;
- }
- server {
- listen 9871;
- location / {
- proxy_pass http://hadoop_9870;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
- }
- server {
- listen 9869;
- location / {
- proxy_pass http://hadoop_9868;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
- }
- server {
- listen 8089;
- location / {
- proxy_pass http://hadoop_8088;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
- }
- server {
- listen 9865;
- location / {
- proxy_pass http://hadoop_9864;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
- }
- }
复制代码 步骤 3:构建和启动 Nginx 容器
创建一个简单的 Dockerfile 来将自定义的 Nginx 配置文件复制到容器中,并使用官方的 Nginx 镜像。
Dockerfile 示例
- FROM nginx:latest
- # 复制自定义的 Nginx 配置文件 nginx.config 和 Dockerfile在一个目录
- COPY nginx.conf /etc/nginx/nginx.conf
- # 暴露端口
- EXPOSE 9871 9869 8089 9865
复制代码 然后构建并运行 Nginx 容器:
- # 构建镜像
- docker build -t my_nginx_proxy .
- # 启动容器并连接到 hadoop_network 网络
- docker run -d --name my_nginx_proxy --network hadoop_network -p 9871:9871 -p 9869:9869 -p 8089:8089 -p 9865:9865 my_nginx_proxy
复制代码 确保所有 Hadoop 容器和 Nginx 容器都在同一个 Docker 网络中,并且 IP 地址精确。您可以使用 docker inspect <container_name> 来检查容器的网络配置。
尝试访问 Nginx 的监听端口,以确认代理是否正常工作:
- http://localhost:9871
- http://localhost:9869
- http://localhost:8089
- http://localhost:9865
复制代码 然后可以看到下面页面,就大功告成
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |