目录
- 背景
- 第一部分
Docker
镜像准备 - 第二部分 运行容器
- 第三部分
cloudera-manager
管理 - 第四部分 组件使用测试
- 第五部分 总结
- 参考文献及资料
背景
通常在个人笔记本上部署Hadoop
测试集群(含生态圈各组件)是个很耗时的工作。Cloudera
公司提供一个快速部署的Docker
镜像,可以快速启动一个测试集群。
测试环境为
Ubuntu
服务器
第一部分 Docker镜像准备
首先本机需要部署有docker
环境,如果没有需要提前部署。
1.1 拉取Docker镜像
可以从DockerHub
上拉取cloudera/quickstart
镜像。
1 | docker pull cloudera/quickstart:latest |
如果不具备联网环境,可以通过镜像介质包安装。介质可以在官网(需要注册用户)下载:https://www.cloudera.com/downloads/quickstart_vms/5-13.html
由于墙的原因下载会很慢
1 | wget https://downloads.cloudera.com/demo_vm/docker/cloudera-quickstart-vm-5.13.0-0-beta-docker.tar.gz |
1.2 检查镜像库
1 | docker images|grep cloudera |
说明镜像准备好了,下面基于镜像启动容器。
第二部分 运行容器
2.1 使用镜像启动容器
启动CDH
集群的命令格式为:
1 | docker run --hostname=quickstart.cloudera --privileged=true -t -i [OPTIONS] [IMAGE] /usr/bin/docker-quickstart |
官方提示的参数介绍如下:
Option | Description |
---|---|
–hostname=quickstart.cloudera | Required: Pseudo-distributed configuration assumes this hostname.容器主机名(/etc/hosts中指定hostname)。 |
–privileged=true | Required: For HBase, MySQL-backed Hive metastore, Hue, Oozie, Sentry, and Cloudera Manager.这是Hbase组件需要的模式。 |
-t | Required: Allocate a pseudoterminal. Once services are started, a Bash shell takes over. This switch starts a terminal emulator to run the services. |
-i | Required: If you want to use the terminal, either immediately or connect to the terminal later. |
-p 8888 | Recommended: Map the Hue port in the guest to another port on the host.端口映射参数。 |
-p [PORT] | Optional: Map any other ports (for example, 7180 for Cloudera Manager, 80 for a guided tutorial). |
-d | Optional: Run the container in the background.容器后台启动。 |
–name | 容器的名字 |
-v host_path:container_path | 主机上目录挂载到容器中目录上,主机上该放入任何东西,Docker容器中对于目录可以直接访问。 |
当然还可以自定义其他docker启动参数。最后启动命令整理为:
1 | docker run -t -i -d \ |
Cloudera 本身的 manager 是 7180 端口,提前配置端口映射。
启动容器我们使用了-d后台启动参数,如果没有指定后台启动,终端将自动连接到容器,退出shell后容器会中止运行(可以通过使用Ctrl + P + Q命令退出,这样容器会继续保持运行)。
对于已经后台运行的容器,我们使用下面的命令进入容器shell:
1 | docker attach [CONTAINER HASH] |
建议使用下面的命令:
1 | docker exec -it 容器名 /bin/bash |
2.2 时钟同步问题
容器内部使用的时间时区为UTC,和主机(宿主机通常为CST(东八区))不同时区,会提示时钟同步问题。解决的办法是:
在环境变量中添加时区变量,并source生效:
1 | vi /etc/profile |
最后启动时钟同步服务:
1 | [root@quickstart home]# service ntpd start |
这样完成时钟同步。
2.3 使用集群服务
这样集群的大部分服务组件均可使用。
第三部分 cloudera-manager管理
3.1 启动管理服务
CDH在该镜像中提供cloudera-manager组件,用户集群web管理界面,可以通过下面的命令启动。
需要注意的是,启动后CDH会停止其他组件服务。
1 | #./home/cloudera/cloudera-manager --express [--force] |
用户名和密码为:cloudera/cloudera,登录界面如下:
登录后,下图是集群控制台:
从管理界面上可以看到除了主机和 manager ,其他服务组件均未启动。
3.2 启动集群组件服务
在控制台上,我们按照顺序启动HDFS、Hive、Hue、Yarn服务。
如果服务启动异常,可以尝试重启服务组件。注意需要先启动HDFS后启动Hive,否则需要重启Hive。
第四部分 组件使用测试
4.1 HDFS组件使用
我们使用HDFS的Python API与集群hdfs文件系统进行交互测试:
4.1.1 查看文件系统
1 | from hdfs.client import Client |
4.1.2 上传新增文件
注意这里需要在宿主机(客户端机器)配置hosts文件:
1 | 192.168.31.3 quickstart.cloudera |
然后执行:
1 | client.upload("/tmp", "/root/jupyter/nohup.out") |
4.1.3 下载hdfs文件
1 | client.download("/tmp/nohup.out", "/tmp") |
第五部分 启用安全模式(Kerberos)
默认情况下集群是非安全模式,如果测试需要安全集群模式,可以在菜单:管理-安全中开启Kerberos。需要注意的是需要在容器中安装Kerberos。安装步骤如下:
注释到无关源(docker容器执行);
1
2部署yum源(宿主机执行)
1
2然后安装Kerberos(docker容器执行)
1
./home/cloudera/kerberos
等待安装完成即可。
接下来就是配置kerberos
,主要涉及的配置文件有:
1 | /etc/krb5.conf |
主要调整是将EXAMPLE.COM
调整为HADOOP.COM
。另外配置文件krb5.conf
需要个性化指定KDC
服务器:
1 | HADOOP.COM = { |
然后创建Kerberos
数据库:
1 | kdb5_util create –r HADOOP.COM -s |
创建Kerberos
管理账户:
1 | kadmin.local |
最后启动服务:
1 | [root@quickstart cloudera]# service krb5kdc start |
查看票据:
1 | [root@quickstart cloudera]# kinit admin/admin@HADOOP.COM |
生成keytab文件:
1 | [root@quickstart keytab]# kadmin.local |
这样就生成了admin.keytab文件。然后使用下面的命令测试一下:
1 | kinit -kt admin.keytab admin/admin@HADOOP.COM |
第六部分 测试运行Spark
我们只测试Spark on Yarn场景。
6.1 运行Spark 1.6.0
CDH 5.7.0 版本自带Spark版本是1.6.0的。所以我们不需要部署相关运行依赖。例如下面的命令运行一个pyspark的任务。
1 | /usr/lib/spark/bin/spark-submit \ |
6.2 运行Spark 2.3.0
对于Spark 2.3.0 需要下载官网相关的版本的介质包。并且由于Spark 2.3.0的编译是java 8,所以需要配置JAVA_HOME环境变量为1.8。
具体命令如下:
1 | export YARN_CONF_DIR=/etc/hadoop/conf |
需要主要点有:
- 配置YARN_CONF_DIR环境变量
- 需要指定Driver和Excutor运行的JDK环境。需要注意的是对于分布式集群前提就是所有节点上均有相同路径jdk,或者需要配置一致的JAVA_HOME。
另外一种方法还没验证:
某些特殊的场景下,我们对集群没有管理权限,只能通过YARN提交Application,并且集群里没有部署我们需要的JDK版本,这种情形就需要将JDK的安装包也一并提交了。
这里要求我们的JDK安装包必须为gz格式的,和你代码打包后的jar包放在同一目录下,假设我们下载的JDK的安装包为:jdk-8u141-linux-x64.tar.gz。
关键配置如下:
1 | SPARK_HOME/bin/spark-submit \ |
我们可以通过指定spark.yarn.dist.archives
配置,将JDK的安装包分发到所有Executor的工作目录下(包括Application Master的Executor),另外tar.gz的压缩包也会被自动解压,假设jdk-8u141-linux-x64.tar.gz
解压后的目录为jdk1.8.0_141
,那么我们特定的JDK的目录就是:./jdk-8u141-linux-x64.tar.gz/jdk1.8.0_141
,不同的JDK版本以此类推即可。
注意:由于Spark Standalone没有提供分发JDK安装包并自动解压的功能,所以,这种方式只能用在YARN下。
第七部分 测试运行Flink
我们测试使用Flink 1.7.2和Flink 1.12.7两个版本进行测试。两个版本类似。
7.1 运行Flink 1.7.2
部署好Flink介质后,使用下面的命令运行:
1 | ./bin/flink run -m yarn-cluster examples/batch/WordCount.jar |
结果报错了,报错如下:
1 | org.apache.flink.client.program.ProgramInvocationException: The main method caused an error: Could not deploy Yarn job cluster. |
上面的报错是JDK的兼容性报错。Flink运行需要在JDK 1.8版本下运行,但是集群的JDK为1.7版本。
这个报错Spark同样会出现这个问题。但是Spark可以通过spark.executorEnv.JAVA_HOME
和spark.yarn.appMasterEnv.JAVA_HOME
两个参数设置执行器和AM容器的java运行环境。
但是对于Flink查看了官方各种资料没有找到规避方法。其中有方案说通过flink-conf.yaml
配置下面的参数。笔者实践后,证实是无效的。
1 | env.java.home: /home/openjdk |
所以最后的解决方案是调整集群的JDK的版本为1.8版本。
第八部分 总结
1、Cloudera 的 docker 版本分成两部分启动。(1)启动各组件启动,使用命令为: /usr/bin/docker-quickstart,(2) 启动Cloudera manager 管理服务,启动命令为:/home/cloudera/cloudera-manager。docker启动时选择启动一项。
参考文献及材料
1、cloudera/quickstart镜像地址:https://hub.docker.com/r/cloudera/quickstart
2、cloudera/quickstart镜像部署指引:https://www.cloudera.com/documentation/enterprise/5-6-x/topics/quickstart_docker_container.html