hadoop3 docker 集群部署
网络可以使用 macvlan 网络 或 bridge 网络,可以自行选择。本教程使用 bridge 网络。
本教程使用docker原生方式搭建环境,没有使用docker compose,主要是为了可以减少学习成本,另外,整个docker容器的环境的不仅可以用于hadoop,其它需要分布式环境的也可以使用这套环境,比如kafka,flink。
机器信息
域名 | ip | 备注 |
---|---|---|
m0 | 172.18.0.100 | master |
m1 | 172.18.0.101 | slave |
m2 | 172.18.0.102 | slave |
m3 | 172.18.0.103 | slave |
使用 macvlan 网络
使用 bridge 网络的可以忽略这一步,直接看下面的使用 bridge 网络
docker network create -d macvlan --subnet=192.168.8.0/24 --gateway=192.168.8.1 -o parent=wlp40s0f3u3 mynet
-d
指定 Docker 网络 driver--subnet
指定 macvlan 网络所在的网络--gateway
指定网关-o parent
指定用来分配 macvlan 网络的物理网卡
查看网络
docker network ls
开启网卡混杂模式
网卡的混杂模式,在该模式下网卡会将网络上的数据一并抓获。
ifconfig wlp40s0f3u3 promisc #设置混杂模式
ifconfig wlp40s0f3u3 -promisc #取消混杂模式
创建容器
#m0
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name m0 -h m0 --net mynet --ip 192.168.8.200 centos:centos7 /usr/sbin/init
#cluster-slaves
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name m1 -h m1 --net mynet --ip 192.168.8.201 centos:centos7 /usr/sbin/init
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name m2 -h m2 --net mynet --ip 192.168.8.202 centos:centos7 /usr/sbin/init
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name m3 -h m3 --net mynet --ip 192.168.8.203 centos:centos7 /usr/sbin/init
使用 bridge 网络
创建固定IP的子网
docker network create --subnet=172.18.0.0/16 netgroup
创建容器
#m0
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name m0 -h m0 --net netgroup --ip 172.18.0.100 centos:centos7 /usr/sbin/init
#cluster-slaves
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name m1 -h m1 --net netgroup --ip 172.18.0.101 centos:centos7 /usr/sbin/init
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name m2 -h m2 --net netgroup --ip 172.18.0.102 centos:centos7 /usr/sbin/init
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name m3 -h m3 --net netgroup --ip 172.18.0.103 centos:centos7 /usr/sbin/init
#mysql
docker run -d --privileged --restart always -ti -v /sys/fs/cgroup:/sys/fs/cgroup --name mysql -h mysql --net netgroup --ip 172.18.0.200 -e MYSQL_ROOT_PASSWORD=abc@123456 -d --restart always mysql:5.7.24
解决 CentOS 8 上Docker容器内无法联网
只需要将 Docker 添加到 firewalld 的 trusted 组即可。执行:
firewall-cmd --permanent --zone=trusted --change-interface=docker0
firewall-cmd --reload
docker0 需改成相应的网卡名
m0 配置
换源
yum -y install wget
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
yum makecache
安装openssh
yum -y install openssh openssh-server openssh-clients
systemctl start sshd
systemctl enable sshd
ssh自动接受新的公钥,master设置ssh登录自动添加kown_hosts
修改 /etc/ssh/ssh_config,将原来的StrictHostKeyChecking ask,设置StrictHostKeyChecking为no
systemctl restart sshd
m1-m3 配置
换源
yum -y install wget
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
yum makecache
安装openssh
yum -y install openssh openssh-server openssh-clients
systemctl enable sshd
systemctl start sshd
m0公钥分发
在master机上执行ssh-keygen -t rsa
并一路回车,完成之后会生成~/.ssh目录,目录下有id_rsa(私钥文件)和id_rsa.pub(公钥文件)
ssh-copy-id root@172.18.0.101
ssh-copy-id root@172.18.0.102
ssh-copy-id root@172.18.0.103
至此,m0可以免密登录个slave。
Ansible安装
官方自带安装:
yum -y install epel-release
yum -y install ansible
编辑ansible的hosts文件 /etc/ansible/hosts 添加配置
[cluster]
m0
m1
m2
m3
[master]
m0
[slaves]
m1
m2
m3
配置docker容器hosts
由于/etc/hosts文件在容器启动时被重写,直接修改内容在容器重启后不能保留,为了让容器在重启之后获取集群hosts,使用了一种启动容器后重写hosts的方法。 需要在~/.bashrc中追加以下指令
:>/etc/hosts
cat >>/etc/hosts<<EOF
127.0.0.1 localhost
172.18.0.100 m0
172.18.0.101 m1
172.18.0.102 m2
172.18.0.103 m3
EOF
用ansible分发.bashrc至集群slave下
ansible slaves -m copy -a "src=~/.bashrc dest=~/"
修改时区为亚洲上海
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
支持中文
localedef -i zh_CN -f UTF-8 zh_CN.UTF-8
yum -y install kde-l10n-Chinese && yum -y reinstall glibc-common
# 以下内容加入~/.bashrc,加入后source ~/.bashrc
localedef -c -f UTF-8 -i zh_CN zh_CN.utf8
export LC_ALL=zh_CN.utf8
另一种方式是在Dockerfile中添加一行,如下所示:
ENV LANG C.UTF-8
重新打包制作docker镜像。
时间同步
NTP服务器【Network Time Protocol(NTP)】是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒),且可介由加密确认的方式来防止恶毒的协议攻击。
m0 配置ntp
安装ntp
yum install ntp -y
systemctl enable ntpd
systemctl start ntpd
同步网上时间
ntpdate 0.centos.pool.ntp.org #该网址为centos网络上的时间同步服务器
关于ntpd与ntpdate区别
ntpd不仅仅是时间同步服务器,它还可以做客户端与标准时间服务器进行同步时间,而且是平滑同步,并非ntpdate立即同步,在生产环境中慎用ntpdate,也正如此两者不可同时运行。
NTPD 在和时间服务器的同步过程中,会把 BIOS 计时器的振荡频率偏差——或者说 Local Clock 的自然漂移(drift)——记录下来。这样即使网络有问题,本机仍然能维持一个相当精确的走时。
m1-m3 配置ntp
安装ntp
yum install ntp -y
修改ntp配置
修改 /etc/ntp.conf,将内容删除,添加一下内容:
server m0
启动ntp
systemctl enable ntpd
systemctl start ntpd
查看与时间同步服务器的时间偏差
ntpdc -c loopinfo
查看ntp状态
ntpstat
输出信息:
time correct to within 594 ms
polling server every 128 s
这个指令可以列出我们的 NTP 服务器有跟上层联机否。由上述的输出结果可以知道,时间有校正约 594 * 10^(-3) 秒,且每隔 128 秒会主动去更新时间喔!
查看当前同步的时间服务器
ntpq -p
输出信息:
remote | refid | st | t | when | poll | reach | delay | offset | jitter |
---|---|---|---|---|---|---|---|---|---|
*m0 | 193.182.111.141 | 3 | u | 61 | 64 | 377 | 0.104 | 0.031 | 0.011 |
下面的表格解释了输出列。
字段 | 备注 |
---|---|
remote | 源在 ntp.conf 中定义。‘*’ 表示当前使用的,也是最好的源;‘+’ 表示这些源可作为 NTP 源;‘-’ 标记的源是不可用的。 |
refid | 用于和本地时钟同步的远程服务器的 IP 地址。 |
st | Stratum(阶层) |
t | 类型。 ‘u’ 表示单播(unicast)。其它值包括本地(local)、多播(multicast)、广播(broadcast)。 |
when | 自从上次和服务器交互后经过的时间(以秒数计)。 |
poll | 和服务器的轮询间隔,以秒数计。 |
reach | 表示和服务器交互是否有任何错误的八进制数。值 337 表示 100% 成功(即十进制的255)。 |
delay | 服务器和远程服务器来回的时间。 |
offset | 我们服务器和远程服务器的时间差异,以毫秒数计。 |
jitter | 两次取样之间平均时差,以毫秒数计。 |
/sbin/hwclock: 用于 BIOS 时钟 (硬件时钟) 的修改与显示的指令。 这是一个 root 才能执行的指令,因为 Linux 系统上面 BIOS 时间与 Linux 系统时间是分开的,所以使用 date 这个指令调整了时间之后,还需要使用 hwclock 才能将修改过后的时间写入 BIOS 当中!
使用ansible在在集群中安装openjdk
ansible cluster -m yum -a "name=java-1.8.0-openjdk,java-1.8.0-openjdk-devel state=latest"
hadoop 搭建
下载最新hadoop
https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/stable/hadoop-3.3.0.tar.gz
下载完成之后解压安装包,并创建链接文件:
tar -xzvf hadoop-3.3.0.tar.gz
ln -s hadoop-3.3.0 hadoop
设置java和hadoop环境变量(~/.bashrc)
#java
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.272.b10-1.el7_9.x86_64/
export PATH=$HADOOP_HOME/bin:$PATH
# hadoop
export HADOOP_HOME=/opt/hadoop
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
修改配置
修改$HADOOP_HOME/etc/hadoop/core-site.xml
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/tmp</value>
<description>A base for other temporary directories.</description>
</property>
<!-- file system properties -->
<property>
<name>fs.default.name</name>
<value>hdfs://m0:9000</value>
</property>
<property>
<name>fs.trash.interval</name>
<value>4320</value>
</property>
</configuration>
修改$HADOOP_HOME/etc/hadoop/hdfs-site.xml
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/tmp/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.permissions.superusergroup</name>
<value>staff</value>
</property>
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
修改$HADOOP_HOME/etc/hadoop/mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapred.job.tracker</name>
<value>m0:9001</value>
</property>
<property>
<name>mapreduce.jobtracker.http.address</name>
<value>m0:50030</value>
</property>
<property>
<name>mapreduce.jobhisotry.address</name>
<value>m0:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>m0:19888</value>
</property>
<property>
<name>mapreduce.jobhistory.done-dir</name>
<value>/jobhistory/done</value>
</property>
<property>
<name>mapreduce.intermediate-done-dir</name>
<value>/jobhisotry/done_intermediate</value>
</property>
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
</configuration>
修改$HADOOP_HOME/etc/hadoop/yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>m0</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>m0:18040</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>m0:18030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>m0:18025</value>
</property> <property>
<name>yarn.resourcemanager.admin.address</name>
<value>m0:18141</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>m0:18088</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<property>
<name>yarn.log-aggregation.retain-check-interval-seconds</name>
<value>86400</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/tmp/logs</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir-suffix</name>
<value>logs</value>
</property>
</configuration>
root 用户特殊配置
在$HADOOP_HOME/sbin/start-dfs.sh、stop-dfs.sh添加:
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
在$HADOOP_HOME/sbin/start-yarn.sh、stop-yarn.sh添加:
YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
$HADOOP_HOME/etc/hadoop下的workers文件
新增:
m1
m2
m3
3.0.0以后的版本都不让用slaves了,现在是workers
打包hadoop文件
tar -cvf hadoop-dis.tar hadoop hadoop-3.3.0
使用ansible-playbook分发.bashrc和hadoop-dis.tar至slave主机
---
- hosts: cluster
tasks:
- name: copy .bashrc to slaves
copy: src=~/.bashrc dest=~/
notify:
- exec source
- name: copy hadoop-dis.tar to slaves
unarchive: src=/opt/hadoop-dis.tar dest=/opt
handlers:
- name: exec source
shell: source ~/.bashrc
将以上yaml保存为hadoop-dis.yaml,并执行
ansible-playbook hadoop-dis.yaml
在 m0 格式化namenode
hadoop namenode -format
启动hadoop集群
$HADOOP_HOME/sbin
./start-all.sh
访问hadoop web
3.x 版本 NameNode 50070端口 -> 9870端口了 访问:m0:9870 可以看到集群信息。
用命令查看集群信息
hdfs dfsadmin -report
### 查看YARN各节点状态
yarn node -list
存放文件
hdfs dfs -put start-all.sh /
获取文件
hdfs dfs -get /start-all.sh /root/
获取文件列表
hdfs dfs -ls /
hadoop3.x 端口变更
Namenode ports: 50470 –> 9871, 50070–> 9870, 8020 –> 9820
Secondary NN ports: 50091 –> 9869,50090 –> 9868
Datanode ports: 50020 –> 9867, 50010–> 9866, 50475 –> 9865, 50075 –> 9864
Kms server ports: 16000 –> 9600 (原先的16000与HMaster端口冲突)
Hadoop的启动和停止说明
sbin/start-all.sh 启动所有的Hadoop守护进程。包括NameNode、 Secondary NameNode、DataNode、ResourceManager、NodeManager
sbin/stop-all.sh 停止所有的Hadoop守护进程。包括NameNode、 Secondary NameNode、DataNode、ResourceManager、NodeManager
sbin/start-dfs.sh 启动Hadoop HDFS守护进程NameNode、SecondaryNameNode、DataNode
sbin/stop-dfs.sh 停止Hadoop HDFS守护进程NameNode、SecondaryNameNode和DataNode
sbin/hadoop-daemons.sh start namenode 单独启动NameNode守护进程
sbin/hadoop-daemons.sh stop namenode 单独停止NameNode守护进程
sbin/hadoop-daemons.sh start datanode 单独启动DataNode守护进程
sbin/hadoop-daemons.sh stop datanode 单独停止DataNode守护进程
sbin/hadoop-daemons.sh start secondarynamenode 单独启动SecondaryNameNode守护进程
sbin/hadoop-daemons.sh stop secondarynamenode 单独停止SecondaryNameNode守护进程
sbin/start-yarn.sh 启动ResourceManager、NodeManager
sbin/stop-yarn.sh 停止ResourceManager、NodeManager
sbin/yarn-daemon.sh start resourcemanager 单独启动ResourceManager
sbin/yarn-daemons.sh start nodemanager 单独启动NodeManager
sbin/yarn-daemon.sh stop resourcemanager 单独停止ResourceManager
sbin/yarn-daemons.sh stopnodemanager 单独停止NodeManager
sbin/mr-jobhistory-daemon.sh start historyserver 手动启动jobhistory
sbin/mr-jobhistory-daemon.sh stop historyserver 手动停止jobhistory
参考资料
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦