2020.12
host: sea132, ubuntu16, docker19.03.12
reference: XMU
http://dblab.xmu.edu.cn/blog/1233/#more-1233
Docker命令
# 启动master
docker run -it -h master --name master -p 50070:50070 -p 8088:8088 -p 8084:8084 -p 4040:4040 -p 18018:18018 ubuntu/master
容器
正常退出不关闭容器,请按Ctrl+P+Q进行退出容器
# 在运行的容器
docker ps
# 进入运行中的容器,退出不停止
docker exec -it d70015007d89 /bin/bash
# 删除指定镜像生成的容器
docker rm $(docker ps -a | grep 45c548e0e0aa | awk '{print $1}')
# 文件拷贝/传输
docker cp <container_name/id>:/usr/local/... /home/...
# 删除已停止的容器
sudo docker rm `docker ps -a|grep Exited|awk '{print $1}'`
sudo docker rm $(sudo docker ps -qf status=exited)
# 删除孤立容器
sudo docker container prune
镜像
# 显示指定镜像
docker images ubuntu/*
docker image ls
# 删除
docker image rm <id1> <id2>
1. 搭建ubuntu镜像
添加docker用户权限
docker默认只有root才能执行docker命令,因此需要添加用户权限
# 创建docker组
sudo groupadd docker
# 添加当前用户到docker用户组(USER为环境变量,代表当前用户名)
echo $USER
sudo usermod -aG docker $USER
# docker 文件访问权限修改 (WARNING: Error loading config file)
sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
sudo chmod g+rwx "/home/$USER/.docker" -R
ubuntu镜像
# 从dockerhub下载ubuntu镜像
docker pull ubuntu
# 列出所有镜像
docker images
创建共享文件夹
cd ~
mkdir build
# 执行docker镜像并进入
docker run -it -v /home/sea/Projects/docker/build:/root/build --name ubuntu ubuntu
参数
- -it interactive, terminal 进入交互环境
- -v 表示将本地文件与docker内部ubuntu系统的路径文件夹共享,便于将本地文件传输到docker内部
- —name 表示镜像启动名称,如果没有指定,docker随机分配
- 最后参数ubuntu,表示docker run启动的镜像文件
ubuntu系统初始化(docker内部)
安装一些必备软件
# 更新系统源
apt-get update
# 安装vim
apt-get vim
配置ssh
# 安装sshd, 分布式hadoop需要使用ssh连接slave
apt-get install ssh
# 开启sshd服务器
/etc/init.d/ssh start
# 每次开启镜像时,都需要开启sshd服务,所以写入~/.bashrc文件的最后一行(G)
vim ~/.bashrc
/etc/init.d/ssh start
# 配置sshd
ssh-keygen -t rsa
# 将本地的公钥文件~/.ssh/id_rsa.pub,重定向追加到远程文件authorized_keys的末尾
cat id_rsa.pub >> authorized_keys
安装java
# install
apt-get install openjdk-8-jdk
# config
vim ~/.bashrc
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
export PATH=$PATH:$JAVA_HOME/bin
source ~/.bashrc
保存镜像文件
Docker 内部的容器修改是不会自动保存的,意味着关闭容器后重新开启,之前的配置会消失,因此我们在每个步骤完成后都保存成一个新的镜像,然后开启保存的新镜像即可
docker hub
不能关闭当前镜像的终端窗口,再打开一个新的Terminal,执行镜像保存
# 登陆
docker login
# 登录保存的信息
cat ~/.docker/config.json
# 查看
docker info
# 找到当前修改并运行的container id
docker ps
# 提交镜像
# docker commit <id> ubuntu/jdk-installed
# 查看特定镜像
docker images ubuntu/jdk*
2. 安装Hadoop
2.1 install
# 启动docker镜像
docker run -it -v /home/sea/Projects/docker/build:/root/build --name ubuntu-jdk8-installed ubuntu/jdk8-installed
# 解压,改名
tar -zxvf hadoop-3.3.0.tar.gz -C /usr/local/
cd /usr/local
mv hadoop-3.3.0/ hadoop
cd /usr/local/hadoop/etc/hadoop
2.2 config
1. hadoop-env.sh
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
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
2. hdfs-site.xml
其中dfs.replication表示冗余因子,即一份数据保存三分副本
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/local/hadoop/tmp/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/local/hadoop/tmp/dfs/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
</configuration>
3. core-site.xml
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/local/hadoop/tmp</value>
<description>Abase for other temporary directories.</description>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
</configuration>
4. mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
5. yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
</configuration>
6. workers
添加分布式从节点的hostname
vim worker
slave01
slave02
完成配置,提交docker镜像
docker commit ae3ce957e599 ubuntu/hadoop3.3.0-installed
2.3 启动Hadoop集群(可忽略)
2.3.1 运行三个镜像
docker run 退出docker即停止容器
-h 表示设定运行镜像的hostname
# 第一个终端
docker run -it -h master --name master ubuntu/hadoop3.3.0-installed
# 第二个终端
docker run -it -h slave01 --name slave01 ubuntu/hadoop3.3.0-installed
# 第三个终端
docker run -it -h slave02 --name slave02 ubuntu/hadoop3.3.0-installed
2.3.2 进入每个镜像,获取ip
cat /etc/hosts
172.17.0.5 master
172.17.0.6 slave01
172.17.0.7 slave02
将上述多条ip信息,分别复制到master和slave01, slave02的/etc/hosts中
# 测试ssh连接
ssh slave01
ssh slave02
2.3.3 启动Hadoop
cd /usr/local/hadoop
bin/hdfs namenode -format
sbin/start-all.sh
# 查看运行结果
jps
3. Spark
3.1 install
docker run -it -v /home/sea/Projects/docker/build:/root/build --name hadoop3-3 ubuntu/hadoop3.3.0-installed
cd ~/build
# 解压,改名
tar -zxvf spark-3.0.1-bin-hadoop3.2.tgz -C /usr/local/
cd /usr/local
mv spark-3.0.1-bin-hadoop3.2/ spark
3.2 环境变量
vim ~/.bashrc
# Hadoop, Spark
export HADOOP_HOME=/usr/local/hadoop
export SPARK_HOME=/usr/local/spark
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin:$SPARK_HOME/bin:$SPARK_HOME/sbin
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib:$HADOOP_COMMON_LIB_NATIVE_DIR"
# 立即生效
source ~/.bashrc
3.3 spark-master配置
1. slaves
# 配置slaves
cd /usr/local/spark
cp ./conf/slaves.template ./conf/slaves
# 将localhost改为连个从节点host
slave01
slave02
2. spark-env.sh
cp ./conf/spark-env.sh.template ./conf/spark-env.sh
vim ./conf/spark-env.sh
export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)
export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
export SPARK_MASTER_IP=master
提交
docker commit a1b6bfbdcecc ubuntu/spark3
4. Zookeeper (可选)
安装
cd ~/build
# 解压,改名
tar -zxvf apache-zookeeper-3.6.2-bin.tgz -C /usr/local/
cd /usr/local
mv apache-zookeeper-3.6.2-bin/ zookeeper
# 配置
cd zookeeper/conf
cp zoo_sample.cfg zoo.cfg
#dataDir中的文件夹要自己创建mkdir
vim zoo.cfg
server.1=master:2888:3888
server.2=slave01:2888:3888
server.3=slave02:2888:3888
# 写入1
echo 1 > ~/tmp/zookeeper/myid
!!!Notice: 每台机器都在dataDir中创建myid文件,master在myid文件中写入1,slave1写入2,slave2写入3
**
启动
zkServer.sh start (启动)
zkServer.sh restart (重启)
zkServer.sh status (查看状态)
zkServer.sh stop (关闭)
zkServer.sh start-foreground (以打印日志方式启动)
由于两台机器间出现拒绝连接:先在每台机器上启动服务器,之后再重启一边
zkServer.sh start
zkServer.sh restart
zkServer.sh status
5. History Server
intro
我们可以在Spark应用程序运行结束后,将应用程序的运行信息写入指定目录,而Spark History Server可以将这些信息以Web形式展现
config (spark on yarn)
只需要在history server运行的节点上配置
Hadoop yarn
vim $HADOOP_HOME/etc/hadoop/yarn-site.xml
<property>
<description>Whether to enable log aggregation</description>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log.server.url</name>
<value>http://master:19888/jobhistory/logs</value>
</property>
vim $HADOOP_HOME/etc/hadoop/mapred-site.xml
<property>
<name>mapreduce.jobhistory.address</name>
<value>master:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>master:19888</value>
</property>
Spark-yarn
# 1. 新建spark events目录
hadoop fs -mkdir -p /user/spark/applicationHistory
hadoop fs -chmod -R 777 /user/spark/applicationHistory
# 2. 配置spark-defaults.conf
vim $SPARK_HOME/conf/spark-defaults.conf
spark.eventLog.dir=hdfs:///user/spark/applicationHistory
spark.eventLog.enabled=true
spark.history.ui.port=18018
# 3. 配置spark-env.sh
vim $SPARK_HOME/conf/spark-env.sh
export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=8088 -Dspark.history.fs.logDirectory=hdfs:///user/spark/applicationHistory"
启动集群
集群web端口
- hadoop namenode - 50070
- yarn - 8088
- spark - 8080 端口占用改为8084
- spark-job - 4040
- historyserver - 18018
# 第一个终端
docker run -it -h master --name master -p 50070:50070 -p 8088:8088 -p 8080:8080 -p 4040:4040 -p 18018:18018 ubuntu/spark3
# 第二个终端
docker run -it -h slave01 --name slave01 ubuntu/spark3
# 第三个终端
docker run -it -h slave02 --name slave02 ubuntu/spark3
1. 修改hosts
每个节点都需修改vim etc/hosts
172.17.0.4 master
172.17.0.5 slave01
172.17.0.6 slave02
2. 启动hadoop
master有四个进程:Jps、NameNode、ResourceManager、SecondaryNameNode# 第一次需要格式化
hdfs namenode -format
start-all.sh
slave节点进程有:Jps、DataNode、NodeManager
3. 启动spark
# 主节点
start-master.sh
# 从节点
start-slaves.sh
# 启动history server
start-history-server.sh
主节点进程:master
slave节点进程:worker
关闭集群
# master
stop-master.sh
stop-all.sh
# slaves
stop-slaves.sh
ERROR
docker login timeout
Reason
DNS resolve
# 检查是否为解析问题
curl https://registry-1.docker.io/v2/
# 修改dns
sudo vim /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
50070 namenode 远程web页面无法访问
docker run -it -h
Hadoop官方文档默认IP绑定在127.0.0.1上,因此本地开放端口为127.0.0.1:50070,无法远程访问(在别的主机上访问页面)
Solution
vim $HADOOP_HOME/etc/hadoop/hdfs-site.xml
<property>
<name>dfs.http.address</name>
<value>0.0.0.0:50070</value>
</property>
# 重启生效
stop-all.sh
start-all.sh
docker映射spark web端口8080冲突
修改为8084
docker run -it -h master --name master -p 50070:50070 -p 8088:8088 -p 8084:8084 -p 4040:4040 ubuntu/master
vim $SPARK_HOME/conf/spark-env.sh
export SPARK_MASTER_WEBUI_PORT=8084