# 安装 yum-utils
[root@do-hadoop ~]# yum install -y yum-utils
# 添加Docker CE的yum源
[root@do-hadoop ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
[root@do-hadoop ~]# yum makecache fast
# 看一下仓库里的最新版本
[root@do-hadoop ~]# yum list docker-ce
[root@do-hadoop ~]# yum -y install docker-ce
[root@do-hadoop ~]# systemctl start docker
[root@do-hadoop ~]# systemctl enable docker
hadoop 及其组件,放在 docker 中运行,所以先要创建一个基于 centos 镜像的 hadoop 容器。
这个hadoop 容器,最后会生成镜像,最终成为所有 hadoop 节点的模板。
# 搜索镜像
[root@do-hadoop ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 6300 [OK]
## 在搜索结果列表中OFFICIAL列中有[OK]的表示是官方的镜像。我们看到第一个就是官方的。
# 拉取
[root@do-hadoop ~]# docker pull centos
# 查看镜像
[root@do-hadoop ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 0d120b6ccaa8 3 months ago 215MB
docker network create --driver bridge --subnet 192.168.1.0/16 --gateway 192.168.1.0 mynet
解析:
--driver bridge 表示使用桥接模式
--subnet 192.168.1.0/16 表示子网ip 可以分配 192.168.1.2 到 192.168.255.255
--gateway 192.168.1.0 表示网关
mynet 表示网络名
# 创建 docker 网络
[root@do-hadoop ~]# docker network create --driver bridge --subnet=172.18.0.0/16 --gateway 172.18.0.1 hadoop_nw
# --driver bridge 表示使用桥接模式
# --subnet 172.18.0.0/16 表示子网ip 可以分配 172.18.0.2 到 172.18.255.255
# --gateway 172.18.0.1 表示网关
[root@do-hadoop ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
a30056cd8ca2 bridge bridge local
c77cddcd1cd9 hadoop_nw bridge local
32aadb56edcd host host local
72550a0f5547 none null local
[root@do-hadoop ~]# docker network inspect hadoop_nw
...
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
...
## 记住上面的网络掩码,本例是 172.18.0.0/16, 这表明了网络的ip 地址范围
# 创建并运行容器
[root@do-hadoop ~]# docker run -it -h hadoop --name hadoop centos
## 说明:
## run 表示创建一个容器并运行。
## -it 表示容器运行后直接进入容器内部的命令行。此时就可以像操作虚拟机一样操作这个容器了。
## -h 表示容器的主机名hostname,和虚拟机的hostname一样。如果不指定,Docker 会用 CONTAINER ID 来作为 hostname。
## --name 表示容器的名称。这个前面已经提到了,如果自己不指定,Docker 会自动分配一个名称。不过还是自己指定的更有意义。
## 其中主机名和容器名一不一样都行,我这里是给了一样的,都是 hadoop。
## 最后一个参数centos是镜像名称,表示该容器用哪个镜像创建。
## 这个过程类似于用ISO文件装系统。
# 退出并停止当前容器运行
[root@do-hadoop ~]# exit
# 查看本机的所有容器(正在进行或停止运行)
[root@do-hadoop ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5e1930be0f53 centos "/bin/bash" 5 minutes ago Exited (0) 3 seconds ago hadoop
# 启动并进入刚才创建的容器
[root@do-hadoop ~]# docker start -i hadoop
注意,以下内容在 hadoop 容器内执行
# 修改时区
[root@hadoop /]# rm -f /etc/localtime
[root@hadoop /]# ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
[root@hadoop /]# echo Asia/Shanghai > /etc/timezone
# 安装语言包
[root@hadoop /]# yum -y install glibc-langpack-en
[root@hadoop /]# echo "export LC_ALL=en_US.UTF-8" >> /etc/profile
[root@hadoop /]# echo "export LC_CTYPE=en_US.UTF-8" >> /etc/profile
[root@hadoop /]# source /etc/profile
## 这个操作完,可能要退出 hadoop 窗口,再进入才生效
# 安装 SSH
[root@hadoop /]# yum -y install openssh-server.x86_64 openssh-clients.x86_64
# 生成三个主机的 key 文件
## 均不需做键盘输入内容,一路回车即可
[root@hadoop /]# ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
[root@hadoop /]# ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
[root@hadoop /]# ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
# 运行 SSH
[root@hadoop /]# /usr/sbin/sshd
# 设置 root 密码
[root@hadoop /]# yum -y install passwd cracklib-dicts
[root@hadoop /]# passwd
Changing password for user root.
New password: 1qt5!QT%
# 生成用户的 key 文件
[root@hadoop /]# ssh-keygen
# 设置ssh免密登录到本机
[root@hadoop /]# vi /etc/pam.d/sshd
## 注释下一行
#account required pam_nologin.so
[root@hadoop /]# ssh-copy-id localhost
[root@hadoop /]# ssh localhost
[root@hadoop /]# exit
# 运行hadoop需要which命令,同样容器没有自带,需要我们安装。
[root@hadoop /]# yum -y install which
# 退出当前容器并保持其继续运行
# 快捷键 Ctrl+p+q
注意,以下内容在宿主机执行
[root@do-hadoop ~]# docker cp /root/jdk-8u251-linux-x64.tar.gz hadoop:/root/
[root@do-hadoop ~]# docker cp /root/apache-hive-2.3.7-bin.tar.gz hadoop:/root/
[root@do-hadoop ~]# docker cp /root/hadoop-2.9.2.tar.gz hadoop:/root/
[root@do-hadoop ~]# docker cp /root/scala-2.11.8.tgz hadoop:/root/
[root@do-hadoop ~]# docker cp /root/spark-2.2.0-bin-hadoop2.7.tgz hadoop:/root/
[root@do-hadoop ~]# docker cp /root/mysql-connector-java-5.1.49.tar.gz hadoop:/root/
# 进入容器
[root@do-hadoop ~]# docker attach hadoop
注意,以下内容在 hadoop 容器内执行
[root@hadoop /]# cd /root
[root@hadoop ~]# tar xzf jdk-8u251-linux-x64.tar.gz
[root@hadoop ~]# tar xzf hadoop-2.9.2.tar.gz
[root@hadoop ~]# tar xzf apache-hive-2.3.7-bin.tar.gz
[root@hadoop ~]# tar xzf scala-2.11.8.tgz
[root@hadoop ~]# tar xzf spark-2.2.0-bin-hadoop2.7.tgz
[root@hadoop ~]# tar xzf mysql-connector-java-5.1.49.tar.gz
[root@hadoop ~]# mkdir /root/hadoop-2.9.2/data
[root@hadoop ~]# mv apache-hive-2.3.7-bin hive-2.3.7
[root@hadoop ~]# cp mysql-connector-java-5.1.49/mysql-connector-java-5.1.49.jar ./hive-2.3.7/lib/
[root@hadoop ~]# mv spark-2.2.0-bin-hadoop2.7 spark-2.2.0
[root@hadoop ~]# vi /etc/profile.d/run.sh
export JAVA_HOME=/root/jdk1.8.0_251
export PATH=$PATH:$JAVA_HOME/bin
export HADOOP_HOME=/root/hadoop-2.9.2
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HIVE_HOME=/root/hive-2.3.7
export PATH=$PATH:$HIVE_HOME/bin
/usr/sbin/sshd
[root@hadoop ~]# source /etc/profile
hadoop-2.9.2
apache-hive-2.3.7-bin
scala-2.11.8
spark-2.2.0-bin-hadoop2.7
mysql-connector-java-5.1.49
注意,以下内容在 hadoop 容器内执行
[root@hadoop ~]# cd /root/hadoop-2.9.2/etc/hadoop
[root@hadoop hadoop]# vi hadoop-env.sh
## 修改如下键值
export JAVA_HOME=/root/jdk1.8.0_251
[root@hadoop hadoop]# vi core-site.xml
# 增加如下内容
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop11:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/root/hadoop-2.9.2/data</value>
</property>
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
[root@hadoop hadoop]# vi hdfs-site.xml
# 增加如下内容
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop11:50090</value>
</property>
[root@hadoop hadoop]# vi mapred-site.xml
# 增加如下内容
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop11:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop11:19888</value>
</property>
</configuration>
[root@hadoop hadoop]# vi yarn-site.xml
# 增加如下内容
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop11</value>
</property>
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>1</value>
</property>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>1536</value>
</property>
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
</configuration>
[root@hadoop hadoop]# vi slaves
hadoop11
hadoop12
hadoop13
注意,以下内容在 hadoop 容器内执行
[root@hadoop hadoop]# cd /root/hive-2.3.7/conf/
[root@hadoop hadoop]# cp hive-default.xml.template hive-site.xml
[root@hadoop hadoop]# vi hive-site.xml
# 最前面添加
<property>
<name>system:java.io.tmpdir</name>
<value>/tmp/hive/java</value>
</property>
<property>
<name>system:user.name</name>
<value>${user.name}</value>
</property>
# 逐项修改如下键值
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>1qt5!QT%</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>mysql
<value>jdbc:mysql://172.18.0.1:3306/hive?useSSL=false&allowPublicKeyRetrieval=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
[root@hadoop conf]# cp hive-env.sh.template hive-env.sh
[root@hadoop conf]# vi hive-env.sh
export HADOOP_HOME=/root/hadoop-2.9.2
export HIVE_CONF_DIR=/root/hive-2.3.7/conf
export HIVE_AUX_JARS_PATH=/root/hive-2.3.7/lib
注意,以下内容在 hadoop 容器内执行
[root@hadoop ~]# cd /root/spark-2.2.0/conf
[root@hadoop ~]# cp spark-env.sh.template spark-env.sh
[root@hadoop ~]# vi spark-env.sh
# 添加如下内容
# 配置各种软件的HOME,一般来说不配置也可以,但是可能会出现问题,还是配上
export JAVA_HOME=/root/jdk1.8.0_251
export HADOOP_HOME=/root/hadoop-2.9.2
export HADOOP_CONF_DIR=/root/hadoop-2.9.2/etc/hadoop
export SCALA_HOME=/root/scala-2.11.8
export SPARK_HOME=/root/spark-2.2.0
# 设置Master的IP
export SPARK_MASTER_IP=172.18.0.11
# 设置Master的主机名
export SPARK_MASTER_HOST=hadoop11
# 设置本节点的IP
export SPARK_LOCAL_IP=172.18.0.11
# 每一个Worker最多可以使用的内存
export SPARK_WORKER_MEMORY=1g
# 每一个Worker最多可以使用的cpu core的个数
export SPARK_WORKER_CORES=1
# 提交Application的端口,默认就是这个,万一要改呢,改这里
export SPARK_MASTER_WEBUI_PORT=8080
export SPARK_DIST_CLASSPATH=$(/root/hadoop-2.9.2/bin/hadoop classpath)
## 注意,上面 SPARK_LOCAL_IP 这个配置项的值,等会生成各节点容器后要改成各自节点的ip地址
[root@hadoop ~]# cp slaves.template slaves
[root@hadoop ~]# vi slaves
hadoop11
hadoop12
hadoop13
注意,以下内容在宿主机执行
将上面的 hadoop 容器打包成镜像
[root@do-hadoop ~]# docker commit -a "luchunyu" -m "Hadoop在centos上搭建的分布模式" hadoop hadoop-centos:v1
sha256:8e9f85b18c9392ec4e2561b72e0ba225f5a91ab9a8d0cb2b45278e6ec258536d
[root@do-hadoop ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hadoop-centos v1 8e9f85b18c93 53 seconds ago 3.11GB
centos latest 0d120b6ccaa8 3 months ago 215MB
-a 表示作者。
-m 表示对该镜像的说明。
pseudo-distributed 被打包容器的名称
hadoop-centos:v1 生成镜像的名称及版本
需要知道的是,因为这个被打包的容器是通过centos镜像创建的,所以由该容器打包成的新镜像也包含了centos镜像。
用新生成的镜像创建 4 个容器
[root@do-hadoop ~]# docker run -itd -h hadoop11 --name hadoop11 --network=hadoop_nw --ip 172.18.0.11 -p 50070:50070 -p 8088:8088 -p 19888:19888 -p 10000:10000 hadoop-centos:v1
[root@do-hadoop ~]# docker run -itd -h hadoop12 --name hadoop12 --network=hadoop_nw --ip 172.18.0.12 hadoop-centos:v1
[root@do-hadoop ~]# docker run -itd -h hadoop13 --name hadoop13 --network=hadoop_nw --ip 172.18.0.13 hadoop-centos:v1
[root@do-hadoop ~]# docker run -itd -h client --name client --network=hadoop_nw --ip 172.18.0.10 hadoop-centos:v1
[root@do-hadoop ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3a4357b7b4a hadoop-centos:v1 "/bin/bash" 4 seconds ago Up 3 seconds client
8bea9c87b37d hadoop-centos:v1 "/bin/bash" 17 seconds ago Up 16 seconds hadoop13
e0b2121b5ccc hadoop-centos:v1 "/bin/bash" 22 seconds ago Up 21 seconds hadoop12
5f5ffa81a6fd hadoop-centos:v1 "/bin/bash" 32 seconds ago Up 30 seconds 0.0.0.0:8088->8088/tcp, 0.0.0.0:10000->10000/tcp, 0.0.0.0:19888->19888/tcp, 0.0.0.0:50070->50070/tcp hadoop11
5e1930be0f53 centos "/bin/bash" 5 days ago Exited (130) 2 days ago hadoop
[root@do-hadoop ~]#
在 client 节点执行
配置节点间SSH免密登录
[root@do-hadoop ~]# docker attach client
# 这一步貌似可以不执行,因为在制作 hadoop 容器时,已经生成了 key 文件,并实现了免密登录,
# 所以现在复制的三台,key都是一样的,就可以自动登录了。
[root@client /]# ssh-copy-id hadoop11
[root@client /]# ssh-copy-id hadoop12
[root@client /]# ssh-copy-id hadoop13
# 从 client ssh 登录到 hadoop11,然后再分别执行一下到 hadoop11,hadoop12,hadoop13服务器的 ssh 登录命令
# 以便在 hadoop11 上生成 known_hosts 清单
启动
[root@client /]# ssh hadoop11 "hdfs namenode -format"
[root@client /]# ssh hadoop11 "start-dfs.sh"
[root@client /]# ssh hadoop11 "start-yarn.sh"
[root@client /]# ssh hadoop11 "mr-jobhistory-daemon.sh --config $HADOOP_CONF_DIR start historyserver"
在浏览器中查看集群信息
HDFS http://192.168.109.128:50070/
YARN http://192.168.109.128:8088/
jobhistory http://192.168.109.128:19888/
运行wordcount示例程序
# 准备数据
[root@client /]# mkdir /root/input
[root@client /]# ls --help > /root/input/ls.txt
[root@client /]# df --help > /root/input/df.txt
[root@client /]# fdisk --help > /root/input/fdisk.txt
[root@client /]# hadoop fs -put /root/input /
# 运行
[root@client /]# hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.2.jar wordcount /input /output
[root@client /]# hadoop fs -cat /output/*
在 client 节点执行
[root@client /]# rm -f /root/hive-2.3.7/conf/hive-site.xml
[root@client /]# vi /root/hive-2.3.7/conf/hive-site.xml
# 添加如下内容
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://hadoop11:9083</value>
</property>
</configuration>
# 初始化
[root@client /]# ssh hadoop11 "schematool -dbType mysql -initSchema --verbose"
# 启动 hive server 端
[root@client /]# ssh hadoop11 "nohup hive --service metastore 1>/dev/null 2>&1 &"
# 启动 hiveserver2
[root@client /]# ssh hadoop11 "nohup hiveserver2 1>/dev/null 2>&1 &"
# 测试一下
[root@client /]# beeline -u 'jdbc:hive2://hadoop11:10000' -n root
在 client 节点执行
# 修改所有节点 spark-env.sh 中的 SPARK_LOCAL_IP 为对应的 IP
[root@client /]# vi /root/spark-2.2.0/conf/spark-env.sh
[root@client /]# ssh hadoop11
[root@client /]# ssh hadoop12
[root@client /]# ssh hadoop13
[root@client /]# ssh client
# 启动 spark 集群
[root@client /]# ssh hadoop11 "/root/spark-2.2.0/sbin/start-all.sh"
# 停止 spark 集群
[root@client /]# ssh hadoop11 "/root/spark-2.2.0/sbin/stop-all.sh"
# 测试一下
[root@client /]# /root/spark-2.2.0/bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode client --driver-memory 1G --executor-memory 1G --executor-cores 1 /root/spark-2.2.0/examples/jars/spark-examples_2.11-2.2.0.jar 40