Ubuntu 安装 Hadoop 和 Kerberos
花了两天多时间,终于让 Hadoop 可以安安稳稳的跑几个 MapReduce 的程序了,安装的过程很折腾,但我觉得应该用不着花这么长时间的。
很久以前就深知 RTFM 的重要性,但很多时候第一反应仍然是去 Google,而不是去官网找 Documentation,诚然,有些东西的文档的确很烂,但其实 Google 出来的 Blog 转载来转载去也就那么几份,很多里面都存在问题,毕竟需求是不一样的,态度也是不一样的。
这篇文章内容大部分参照自官方文档,并且包含若干我的配置错误,以及解决方法。
这个安装过程适用于配置 Kerberos V5 1.8.4 to Cloudera CDH3 on Ubuntu 11.04
安装 JDK 6
1. 添加源到 ubuntu source list
1 | $ sudo add-apt-repository "deb http://archive.canonical.com/ natty partner" |
natty 是ubuntu 11.04 的 codename,可以使用 “lsb_release -c” 查看 ubuntu 对应版本的 codename,如不是 natty,请更改。
最新的 ubuntu 11.10,好像已经不提供第三方 JDK 了,只有 openjdk 可用了。
2. 安装
1 | $ sudo apt-get update |
如果还装过其他 JDK 的话,需要将该 jdk 设成默认:
1 | $ sudo update-java-alternatives -s java-6-sun |
安装 Cloudera CDH 3
我是单机使用的,所以选择安装 Pseudo-Distributed Mode
参考文档:Cloudera CDH3 Installation 中 Installing CDH3 on Ubuntu Systems 一节。
因为 CDH3 ubuntu 最新的支持包是 10.10 Maveric,所以我选用的是这个包,目前没有发现有其他问题。
在添加 ubuntu 源后,进行如下操作
1 | $ apt-cache search hadoop |
有输出则代表源添加成功,不要按照文档里面安装 hadoop-0.20
1 | $ sudo apt-get install hadoop-0.20 |
而是应该安装
1 | $ sudo apt-get install hadoop-0.20-conf-pseudo |
见 Cloudera 文档 CDH3 Deployment in Pseudo-Distributed Mode
这个 Hadoop 伪分布式配置是 5 个 daemons 跑在一个 node 上,分别是 namenode, jobtracker, secondarynamenode, datanode, trasktracker.
启动所有 node:
1 | $ for x in /etc/init.d/hadoop-*; do sudo $x start; done |
运行如下命令来检验 Hadoop 是否启动成功
1 | $ hadoop fs -ls / |
上述命令会打印出 hdfs 根目录信息,如果成功,那就可以开始 MapReduce 吧,可以跑下面几个例子:
Pi
1 | $ hadoop jar /usr/lib/hadoop/hadoop-*-examples.jar pi 2 100000 |
Grep
1 | $ hadoop fs -mkdir input |
如果例子都没有问题,那么停止所有 node,准备安装 Kerberos
1 | $ for x in /etc/init.d/hadoop-* ; do sudo $x stop ; done |
安装 Kerberos
Kerberos 是什么我就不在这里累赘了,请猛点 Kerberos
1. 安装
下载 Kerberos V5 1.8.4 下载地址
安装很传统,解压,cd 到 src,接着
./configure; make; sudo make install
就 OK 了。
2. 添加配置文件
/etc 下面创建 krb5.conf 文件,内容如下:
1 | [kdc] |
[realms] 设置 KDC 相关服务的地址,因为是单机,所以用的是 localhost
(如果是配集群的话,只有 kdc 需要配 [kdc] 里面的内容,其他 node 包括 client 都需要有这个文件,并且添加除了 [kdc] 以外的内容在这个里面。后面的其他配置文件,非 kdc 不需要。另外如果在 client 里面设置 kdc 地址采用的是 IP 地址,那么需要在 hosts 设置 “hostname IP”,否则很有可能出现这样的错误 log: “Not attempting to re-login since the last re-login was attempted less than 600 seconds before.”,这是因为解析到了错误的 hostname,导致 principal instance 错误,kdc 认证时不能识别而出错。)
接着创建 kdc.conf 文件到 /usr/local/var/krb5kdc 目录下, 就是 krb5.conf 里面 profile 的路径,内容如下:
1 | [kdcdefaults] |
然后创建 kadm5.acl 文件到同一目录,见上面 acl_file 路径,内容如下
1 | */[email protected] * |
3. 创建 Kerberos 数据库
1 | $ /usr/local/sbin/kdb5_util create -r LOCAL.DOMAIN -s |
生成 kadmin/admin kadmin/changepw 两个用户的 keytab 文件到 krb5kdc 目录
1 | $ sudo kadmin.local |
运行
1 | $ sudo /usr/local/sbin/krb5kdc |
Kerberos 就正常工作了
可以运行 kadmin 或者 kadmin.local 进行测试 (运行 kadmin.local 需要 sudo)
1 | $ kadmin |
会显示所有 principals
4. Hadoop Kerberos 安全认证配置
参考文档 Configuring Hadoop Security in CDH3
可以跳过前面步骤,直接从 Step 4 开始。不过提醒下,一定要装这个包(必须和 hadoop 版本一致),要不后面会报一些奇奇怪怪的错误,这个地方浪费了我不少时间。
1 | $ sudo apt-get install hadoop-0.20-sbin |
Cloudera CDH3 默认会建立两个用户 hdfs 和 mapred,而网上的摘抄转载大多是建一个 hadoop 用户,然后创建 hadoop principal 以及创建 keytab,那 datanode 和 nodenode 启动时都会因为 Kerberos 验证不过而失败,因为 Hadoop 是使用的 hdfs 用户来启动的,而 keytab 里面的用户是 hadoop。
有些还说要往 hadoop_env.sh
里面添加
HADOOP_DATANODE_USER=hadoop 的,这样会因为连写 log 的权限都没有而导致
datanode 启动失败的,因为其用户是 hdfs。
上面两个错误都让我花了不少时间去定位。
强烈建议按照 Step 4 的方式来生成 hdfs, mapred 的 principal 以及 keytab 权限设置,生成 keytab 方法可以采用这个
1 | $sudo kadmin.local |
参考 Step 6, 7 配置 Hadoop 的 core-site.xml 和 hdfs-site.xml
配置完成之后启动所有 node
1 | $ for x in /etc/init.d/hadoop-*; do sudo $x start; done |
查看 namenode 和 datanode 的 log,如果有下述 log ,就代表 Hadoop 已经在使用 Kerberos 验证了。
1 | hdfs/[email protected] using keytab file /etc/hadoop/conf/hdfs.keytab |
可以验证下:
1 | $ hadoop fs -ls |
如果你是 jdk 6 update 26,那么恭喜你,你很可能碰见下面错误:
1 | any Kerberos tgt)] |
这个是已知 bug
Workaround 是在 kinit 成功之后,执行
1 | $ kinit -R |
运行之后就可以访问 hdfs 了。我当时死活成功不了,然后找了另一台机器同样设置做了一遍,workaround 是可以的。折腾了好久,最后把 Kerberos 数据库删掉,重新创建了一个,然后重新添加所有 principals 后,就好了。
1 | $ /usr/local/sbin/kdb5_util destroy -r LOCAL.DOMAIN -f |
HDFS 可以正常访问了,接下来按照 Step 12 的方式来配置 MapReduce
注意在 mapred-site.xml 添加配置时,Guide 里面只是关于 Kerberos 的,还需要添加 mapred.local.dir 路径,必须和同目录下 taskcontroller.cfg 里面的设置一致。
1 | mapred.local.dir=/tmp/mapred-tmp |
taskcontroller.cfg 必须设置,如果不设置,tasktrackernode 压根就不会启动的
hadoop.log.dir 就填 hadoop 的 logs 目录 /usr/lib/hadoop/logs
mapred.local.dir 填一个本地目录就可以,但必须是把上面这段配置添加到 mapred-site.xml 里面后重启 node,否则 tasktracker.xml 会报文件不存在或不能读写而启动失败的。
做完 Step 12,重启所有 node,启动成功后,运行前面的 PI 例子,成功就代表 MapReduce 也木有问题了。
Mission Complete!
Have Fun!
在上面的这些都成功之后,又遇到了几个错误
1. Secondarynamenode 做 checkpoint 时认证出错
1 | che/hdfs/dfs/namesecondary from failed checkpoint. |
我 hdfs-site.xml 里面明明配的都是 host/ubuntu。
hdfs-site.xml 里面默认的是 host/_HOST
这类格式的
principal 设置,我之前没有改,启动 node 时,datanode 是
host/ubuntu
,namenode 成了 host/localhost
,
所有我怀疑是这个 _HOST
宏展开的问题,试着加了好几个配置,都不行,最后没办法了,只得添加了
host/localhost
到 hdfs.keytab,算是
workaround
吧,我觉得正式环境应该不会有这样的问题,所以不想折腾了。
2. Secondarynamenode 做 checkpoint 时 fetch image 出错
1 | /cache/hdfs/dfs/namesecondary from failed checkpoint. |
在加了 Kerberos 后,Hadoop 做 checkpoint 的时候走的是 Kerberized SSL,所以需要在 krb5.conf 里面的 [libdefaults] 里面添加 allow_weak_crypto 设置
1 | [libdefaults] |
这个问题折腾了俩小时,添加了很多配置在 hdfs-site.xml 里面,都不行。
最后还是找到了答案,但吃惊的是依然来自一直在用的这个文档 Configuring Hadoop Security in CDH3 Step 11 给出的链接
Appendix D – Enabling Debugging Output for the Sun Kerberos Classes
3. 执行 hadoop fsck 出错
1 | $ hadoop fsck / |
解决了 2,这个问题也木有了。
真是不细看文档会死人的。。。
在此,感谢 Cloudera,是个靠谱的公司。