2020.12
host: sea132, ubuntu16, docker19.03.12
reference: XMU
http://dblab.xmu.edu.cn/blog/1233/#more-1233

Docker命令

  1. # 启动master
  2. 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进行退出容器

  1. # 在运行的容器
  2. docker ps
  3. # 进入运行中的容器,退出不停止
  4. docker exec -it d70015007d89 /bin/bash
  5. # 删除指定镜像生成的容器
  6. docker rm $(docker ps -a | grep 45c548e0e0aa | awk '{print $1}')
  7. # 文件拷贝/传输
  8. docker cp <container_name/id>:/usr/local/... /home/...
  9. # 删除已停止的容器
  10. sudo docker rm `docker ps -a|grep Exited|awk '{print $1}'`
  11. sudo docker rm $(sudo docker ps -qf status=exited)
  12. # 删除孤立容器
  13. sudo docker container prune

镜像

  1. # 显示指定镜像
  2. docker images ubuntu/*
  3. docker image ls
  4. # 删除
  5. docker image rm <id1> <id2>

1. 搭建ubuntu镜像

添加docker用户权限

docker默认只有root才能执行docker命令,因此需要添加用户权限

  1. # 创建docker组
  2. sudo groupadd docker
  3. # 添加当前用户到docker用户组(USER为环境变量,代表当前用户名)
  4. echo $USER
  5. sudo usermod -aG docker $USER
  6. # docker 文件访问权限修改 (WARNING: Error loading config file)
  7. sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
  8. sudo chmod g+rwx "/home/$USER/.docker" -R

ubuntu镜像

  1. # 从dockerhub下载ubuntu镜像
  2. docker pull ubuntu
  3. # 列出所有镜像
  4. docker images

创建共享文件夹

  1. cd ~
  2. mkdir build
  3. # 执行docker镜像并进入
  4. 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内部)

安装一些必备软件

  1. # 更新系统源
  2. apt-get update
  3. # 安装vim
  4. apt-get vim

配置ssh

  1. # 安装sshd, 分布式hadoop需要使用ssh连接slave
  2. apt-get install ssh
  3. # 开启sshd服务器
  4. /etc/init.d/ssh start
  5. # 每次开启镜像时,都需要开启sshd服务,所以写入~/.bashrc文件的最后一行(G)
  6. vim ~/.bashrc
  7. /etc/init.d/ssh start
  8. # 配置sshd
  9. ssh-keygen -t rsa
  10. # 将本地的公钥文件~/.ssh/id_rsa.pub,重定向追加到远程文件authorized_keys的末尾
  11. cat id_rsa.pub >> authorized_keys

安装java

  1. # install
  2. apt-get install openjdk-8-jdk
  3. # config
  4. vim ~/.bashrc
  5. export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
  6. export PATH=$PATH:$JAVA_HOME/bin
  7. source ~/.bashrc

保存镜像文件

Docker 内部的容器修改是不会自动保存的,意味着关闭容器后重新开启,之前的配置会消失,因此我们在每个步骤完成后都保存成一个新的镜像,然后开启保存的新镜像即可
docker hub

不能关闭当前镜像的终端窗口,再打开一个新的Terminal,执行镜像保存

  1. # 登陆
  2. docker login
  3. # 登录保存的信息
  4. cat ~/.docker/config.json
  5. # 查看
  6. docker info
  7. # 找到当前修改并运行的container id
  8. docker ps
  9. # 提交镜像
  10. # docker commit <id> ubuntu/jdk-installed
  11. # 查看特定镜像
  12. docker images ubuntu/jdk*

2. 安装Hadoop

2.1 install

  1. # 启动docker镜像
  2. docker run -it -v /home/sea/Projects/docker/build:/root/build --name ubuntu-jdk8-installed ubuntu/jdk8-installed
  3. # 解压,改名
  4. tar -zxvf hadoop-3.3.0.tar.gz -C /usr/local/
  5. cd /usr/local
  6. mv hadoop-3.3.0/ hadoop
  7. cd /usr/local/hadoop/etc/hadoop

2.2 config

1. hadoop-env.sh

  1. export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
  2. export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
  3. export HDFS_NAMENODE_USER=root
  4. export HDFS_DATANODE_USER=root
  5. export HDFS_SECONDARYNAMENODE_USER=root
  6. export YARN_RESOURCEMANAGER_USER=root
  7. export YARN_NODEMANAGER_USER=root

2. hdfs-site.xml

其中dfs.replication表示冗余因子,即一份数据保存三分副本

  1. <configuration>
  2. <property>
  3. <name>dfs.namenode.name.dir</name>
  4. <value>file:/usr/local/hadoop/tmp/dfs/name</value>
  5. </property>
  6. <property>
  7. <name>dfs.datanode.data.dir</name>
  8. <value>file:/usr/local/hadoop/tmp/dfs/data</value>
  9. </property>
  10. <property>
  11. <name>dfs.replication</name>
  12. <value>3</value>
  13. </property>
  14. </configuration>

3. core-site.xml

  1. <configuration>
  2. <property>
  3. <name>hadoop.tmp.dir</name>
  4. <value>file:/usr/local/hadoop/tmp</value>
  5. <description>Abase for other temporary directories.</description>
  6. </property>
  7. <property>
  8. <name>fs.defaultFS</name>
  9. <value>hdfs://master:9000</value>
  10. </property>
  11. </configuration>

4. mapred-site.xml

  1. <configuration>
  2. <property>
  3. <name>mapreduce.framework.name</name>
  4. <value>yarn</value>
  5. </property>
  6. </configuration>

5. yarn-site.xml

  1. <configuration>
  2. <!-- Site specific YARN configuration properties -->
  3. <property>
  4. <name>yarn.nodemanager.aux-services</name>
  5. <value>mapreduce_shuffle</value>
  6. </property>
  7. <property>
  8. <name>yarn.resourcemanager.hostname</name>
  9. <value>master</value>
  10. </property>
  11. </configuration>

6. workers

添加分布式从节点的hostname

  1. vim worker
  2. slave01
  3. slave02

完成配置,提交docker镜像

  1. docker commit ae3ce957e599 ubuntu/hadoop3.3.0-installed

2.3 启动Hadoop集群(可忽略)

2.3.1 运行三个镜像

docker run 退出docker即停止容器
-h 表示设定运行镜像的hostname

  1. # 第一个终端
  2. docker run -it -h master --name master ubuntu/hadoop3.3.0-installed
  3. # 第二个终端
  4. docker run -it -h slave01 --name slave01 ubuntu/hadoop3.3.0-installed
  5. # 第三个终端
  6. docker run -it -h slave02 --name slave02 ubuntu/hadoop3.3.0-installed

2.3.2 进入每个镜像,获取ip

  1. cat /etc/hosts
  2. 172.17.0.5 master
  3. 172.17.0.6 slave01
  4. 172.17.0.7 slave02

将上述多条ip信息,分别复制到master和slave01, slave02的/etc/hosts中

  1. # 测试ssh连接
  2. ssh slave01
  3. ssh slave02

2.3.3 启动Hadoop

  1. cd /usr/local/hadoop
  2. bin/hdfs namenode -format
  3. sbin/start-all.sh
  4. # 查看运行结果
  5. jps

3. Spark

3.1 install

  1. docker run -it -v /home/sea/Projects/docker/build:/root/build --name hadoop3-3 ubuntu/hadoop3.3.0-installed
  2. cd ~/build
  3. # 解压,改名
  4. tar -zxvf spark-3.0.1-bin-hadoop3.2.tgz -C /usr/local/
  5. cd /usr/local
  6. mv spark-3.0.1-bin-hadoop3.2/ spark

3.2 环境变量

  1. vim ~/.bashrc
  2. # Hadoop, Spark
  3. export HADOOP_HOME=/usr/local/hadoop
  4. export SPARK_HOME=/usr/local/spark
  5. export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin:$SPARK_HOME/bin:$SPARK_HOME/sbin
  6. export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
  7. export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib:$HADOOP_COMMON_LIB_NATIVE_DIR"
  8. # 立即生效
  9. source ~/.bashrc

3.3 spark-master配置

1. slaves

  1. # 配置slaves
  2. cd /usr/local/spark
  3. cp ./conf/slaves.template ./conf/slaves
  4. # 将localhost改为连个从节点host
  5. slave01
  6. slave02

2. spark-env.sh

  1. cp ./conf/spark-env.sh.template ./conf/spark-env.sh
  2. vim ./conf/spark-env.sh
  3. export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)
  4. export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
  5. export SPARK_MASTER_IP=master

提交

  1. docker commit a1b6bfbdcecc ubuntu/spark3

4. Zookeeper (可选)

安装

  1. cd ~/build
  2. # 解压,改名
  3. tar -zxvf apache-zookeeper-3.6.2-bin.tgz -C /usr/local/
  4. cd /usr/local
  5. mv apache-zookeeper-3.6.2-bin/ zookeeper
  6. # 配置
  7. cd zookeeper/conf
  8. cp zoo_sample.cfg zoo.cfg
  9. #dataDir中的文件夹要自己创建mkdir
  10. vim zoo.cfg
  11. server.1=master:2888:3888
  12. server.2=slave01:2888:3888
  13. server.3=slave02:2888:3888
  14. # 写入1
  15. echo 1 > ~/tmp/zookeeper/myid

!!!Notice: 每台机器都在dataDir中创建myid文件,master在myid文件中写入1,slave1写入2,slave2写入3
**

启动

  1. zkServer.sh start  (启动)
  2. zkServer.sh restart  (重启)
  3. zkServer.sh status  (查看状态)
  4. zkServer.sh stop  (关闭)
  5. zkServer.sh start-foreground  (以打印日志方式启动)

由于两台机器间出现拒绝连接:先在每台机器上启动服务器,之后再重启一边

  1. zkServer.sh start
  2. zkServer.sh restart
  3. zkServer.sh status

5. History Server

intro

我们可以在Spark应用程序运行结束后,将应用程序的运行信息写入指定目录,而Spark History Server可以将这些信息以Web形式展现

config (spark on yarn)

只需要在history server运行的节点上配置

Hadoop yarn

  1. vim $HADOOP_HOME/etc/hadoop/yarn-site.xml
  2. <property>
  3. <description>Whether to enable log aggregation</description>
  4. <name>yarn.log-aggregation-enable</name>
  5. <value>true</value>
  6. </property>
  7. <property>
  8. <name>yarn.log.server.url</name>
  9. <value>http://master:19888/jobhistory/logs</value>
  10. </property>
  11. vim $HADOOP_HOME/etc/hadoop/mapred-site.xml
  12. <property>
  13. <name>mapreduce.jobhistory.address</name>
  14. <value>master:10020</value>
  15. </property>
  16. <property>
  17. <name>mapreduce.jobhistory.webapp.address</name>
  18. <value>master:19888</value>
  19. </property>

Spark-yarn

  1. # 1. 新建spark events目录
  2. hadoop fs -mkdir -p /user/spark/applicationHistory
  3. hadoop fs -chmod -R 777 /user/spark/applicationHistory
  4. # 2. 配置spark-defaults.conf
  5. vim $SPARK_HOME/conf/spark-defaults.conf
  6. spark.eventLog.dir=hdfs:///user/spark/applicationHistory
  7. spark.eventLog.enabled=true
  8. spark.history.ui.port=18018
  9. # 3. 配置spark-env.sh
  10. vim $SPARK_HOME/conf/spark-env.sh
  11. 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
    1. # 第一个终端
    2. docker run -it -h master --name master -p 50070:50070 -p 8088:8088 -p 8080:8080 -p 4040:4040 -p 18018:18018 ubuntu/spark3
    3. # 第二个终端
    4. docker run -it -h slave01 --name slave01 ubuntu/spark3
    5. # 第三个终端
    6. docker run -it -h slave02 --name slave02 ubuntu/spark3

    1. 修改hosts

    每个节点都需修改
    1. vim etc/hosts
    2. 172.17.0.4 master
    3. 172.17.0.5 slave01
    4. 172.17.0.6 slave02

    2. 启动hadoop

    1. # 第一次需要格式化
    2. hdfs namenode -format
    3. start-all.sh
    master有四个进程:Jps、NameNode、ResourceManager、SecondaryNameNode
    slave节点进程有:Jps、DataNode、NodeManager

3. 启动spark

  1. # 主节点
  2. start-master.sh
  3. # 从节点
  4. start-slaves.sh
  5. # 启动history server
  6. start-history-server.sh

主节点进程:master
slave节点进程:worker

关闭集群

  1. # master
  2. stop-master.sh
  3. stop-all.sh
  4. # slaves
  5. stop-slaves.sh


ERROR

docker login timeout

Reason
DNS resolve

  1. # 检查是否为解析问题
  2. curl https://registry-1.docker.io/v2/
  3. # 修改dns
  4. sudo vim /etc/resolv.conf
  5. # Google
  6. nameserver 8.8.8.8
  7. nameserver 8.8.4.4

50070 namenode 远程web页面无法访问

  1. docker run -it -h

Hadoop官方文档默认IP绑定在127.0.0.1上,因此本地开放端口为127.0.0.1:50070,无法远程访问(在别的主机上访问页面)

Solution

  1. vim $HADOOP_HOME/etc/hadoop/hdfs-site.xml
  2. <property>
  3. <name>dfs.http.address</name>
  4. <value>0.0.0.0:50070</value>
  5. </property>
  6. # 重启生效
  7. stop-all.sh
  8. start-all.sh

docker映射spark web端口8080冲突

修改为8084

  1. docker run -it -h master --name master -p 50070:50070 -p 8088:8088 -p 8084:8084 -p 4040:4040 ubuntu/master
  2. vim $SPARK_HOME/conf/spark-env.sh
  3. export SPARK_MASTER_WEBUI_PORT=8084