Hadoop with Kerberos認証の設定手順

前回の[「Kerberosインストール手順」](http://qiita.com/bwtakacy/items/a8cd1349a9d150f65eb3)の続き。
当初の目的であるHadoopのKerberos化を行う手順を整理する。

# Hadoopのインストール

[過去記事](http://qiita.com/bwtakacy/items/306afa1b8261f2d4d76e)参照。
今回利用するのはCDH5.6.0。

# JCE Policyのインストール

AES暗号化をJavaから利用するために、Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy FilesをOracleからダウンロードしてインストールする。
インストール方法は添付のREADME.txtに従う。

```
# cd UnlimitedJCEPolicyJDK8-2/
# ls
README.txt  US_export_policy.jar  local_policy.jar
# ll /usr/java/latest/jre/lib/security/
合計 152
-rw-r--r-- 1 root root  2920  1月 30 11:00 US_export_policy.jar
-rw-r--r-- 1 root root  4054  1月 30 10:49 blacklist
-rw-r--r-- 1 root root  1273  1月 30 10:49 blacklisted.certs
-rw-r--r-- 1 root root 99954  1月 30 10:49 cacerts
-rw-r--r-- 1 root root  2466  1月 30 10:49 java.policy
-rw-r--r-- 1 root root 26224  1月 30 10:49 java.security
-rw-r--r-- 1 root root    98  1月 30 10:49 javaws.policy
-rw-r--r-- 1 root root  3405  1月 30 11:00 local_policy.jar
-rw-r--r-- 1 root root     0  1月 30 10:49 trusted.libraries
# mkdir default_jars
# mv /usr/java/latest/jre/lib/security/*.jar default_jars/
# cp *.jar /usr/java/latest/jre/lib/security/
# ll /usr/java/latest/jre/lib/security/
合計 152
-rw-r--r-- 1 root root  3023  3月 17 00:52 US_export_policy.jar
-rw-r--r-- 1 root root  4054  1月 30 10:49 blacklist
-rw-r--r-- 1 root root  1273  1月 30 10:49 blacklisted.certs
-rw-r--r-- 1 root root 99954  1月 30 10:49 cacerts
-rw-r--r-- 1 root root  2466  1月 30 10:49 java.policy
-rw-r--r-- 1 root root 26224  1月 30 10:49 java.security
-rw-r--r-- 1 root root    98  1月 30 10:49 javaws.policy
-rw-r--r-- 1 root root  3035  3月 17 00:52 local_policy.jar
-rw-r--r-- 1 root root     0  1月 30 10:49 trusted.libraries
```

# Hadoopプロセス向けのKerberosプリンシパルの作成

必要なのは、hdfs/[FQDN], mapred/[FQDN], yarn/[FQDN], HTTP/[FQDN]。
今回は擬似分散環境なのでそれぞれ1つずつだが、完全分散環境だとサーバ毎に1つずつ作成する必要がある。

```
# kadmin.local 
Authenticating as principal root/admin@EXAMPLE.COM with password.
kadmin.local:  addprinc -randkey hdfs/locke.example.com@EXAMPLE.COM
WARNING: no policy specified for hdfs/locke.example.com@EXAMPLE.COM; defaulting to no policy
Principal "hdfs/locke.example.com@EXAMPLE.COM" created.
kadmin.local:  addprinc -randkey mapred/locke.example.com@EXAMPLE.COM
WARNING: no policy specified for mapred/locke.example.com@EXAMPLE.COM; defaulting to no policy
Principal "mapred/locke.example.com@EXAMPLE.COM" created.
kadmin.local:  addprinc -randkey yarn/locke.example.com@EXAMPLE.COM
WARNING: no policy specified for yarn/locke.example.com@EXAMPLE.COM; defaulting to no policy
Principal "yarn/locke.example.com@EXAMPLE.COM" created.
kadmin.local:  addprinc -randkey HTTP/locke.example.com@EXAMPLE.COM
WARNING: no policy specified for HTTP/locke.example.com@EXAMPLE.COM; defaulting to no policy
Principal "HTTP/locke.example.com@EXAMPLE.COM" created.
kadmin.local:  listprincs 
HTTP/locke.example.com@EXAMPLE.COM
K/M@EXAMPLE.COM
alice/locke.example.com@EXAMPLE.COM
hdfs/locke.example.com@EXAMPLE.COM
kadmin/admin@EXAMPLE.COM
kadmin/changepw@EXAMPLE.COM
kadmin/locke.example.com@EXAMPLE.COM
kiprop/locke.example.com@EXAMPLE.COM
krbtgt/EXAMPLE.COM@EXAMPLE.COM
mapred/locke.example.com@EXAMPLE.COM
yarn/locke.example.com@EXAMPLE.COM
```

# Keytabファイルの作成

各Hadoopプロセスの認証用のkeytabファイルを作成する。これまたサーバ個別にファイルを作成する必要がある。今回は擬似分散なので1つずつでOK。

```
kadmin.local:  ktadd -norandkey -k hdfs.keytab hdfs/locke.example.com@EXAMPLE.COM HTTP/locke.example.com@EXAMPLE.COM
Entry for principal hdfs/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:hdfs.keytab.
Entry for principal hdfs/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:hdfs.keytab.
Entry for principal hdfs/locke.example.com@EXAMPLE.COM with kvno 1, encryption type arcfour-hmac added to keytab WRFILE:hdfs.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:hdfs.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:hdfs.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type arcfour-hmac added to keytab WRFILE:hdfs.keytab.
kadmin.local:  ktadd -norandkey -k mapred.keytab mapred/locke.example.com@EXAMPLE.COM HTTP/locke.example.com@EXAMPLE.COM
Entry for principal mapred/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:mapred.keytab.
Entry for principal mapred/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:mapred.keytab.
Entry for principal mapred/locke.example.com@EXAMPLE.COM with kvno 1, encryption type arcfour-hmac added to keytab WRFILE:mapred.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:mapred.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:mapred.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type arcfour-hmac added to keytab WRFILE:mapred.keytab.
kadmin.local:  ktadd -norandkey -k yarn.keytab yarn/locke.example.com@EXAMPLE.COM HTTP/locke.example.com@EXAMPLE.COM
Entry for principal yarn/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:yarn.keytab.
Entry for principal yarn/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:yarn.keytab.
Entry for principal yarn/locke.example.com@EXAMPLE.COM with kvno 1, encryption type arcfour-hmac added to keytab WRFILE:yarn.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:yarn.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:yarn.keytab.
Entry for principal HTTP/locke.example.com@EXAMPLE.COM with kvno 1, encryption type arcfour-hmac added to keytab WRFILE:yarn.keytab.
```

# Keytabファイルの配置

作成したkeytabファイルをHadoopの設定ファイルを配置したディレクトリに置く。
パーミッションを各ユーザ向けにすることを忘れないように。

```
# ls
hdfs.keytab  mapred.keytab  yarn.keytab
# cp * /etc/hadoop/conf/
# chown hdfs:hadoop /etc/hadoop/conf/hdfs.keytab 
# chown mapred:hadoop /etc/hadoop/conf/mapred.keytab 
# chown yarn:hadoop /etc/hadoop/conf/yarn.keytab 
# ll /etc/hadoop/conf/
合計 52
-rwxr-xr-x 1 root   root    1104 11月 27 03:20 README
-rwxr-xr-x 1 root   root    2133 11月 27 03:20 core-site.xml
-rwxr-xr-x 1 root   root    1366 11月 27 03:20 hadoop-env.sh
-rwxr-xr-x 1 root   root    2890 11月 27 03:20 hadoop-metrics.properties
-rwxr-xr-x 1 root   root    2324  1月 29 15:08 hdfs-site.xml
-rw------- 1 hdfs   hadoop   707  3月 17 01:02 hdfs.keytab
-rwxr-xr-x 1 root   root   11291  1月 29 15:08 log4j.properties
-rwxr-xr-x 1 root   root    1549 11月 27 03:20 mapred-site.xml
-rw------- 1 mapred hadoop   478  3月 17 01:02 mapred.keytab
-rwxr-xr-x 1 root   root    2375 11月 27 03:20 yarn-site.xml
-rw------- 1 yarn   hadoop   472  3月 17 01:02 yarn.keytab
```

# HDFSのKerberos化

## 設定ファイルの変更

以下の項目を追加する。

```core-site.xml
  <!-- For Kerberos -->
  <property>
    <name>hadoop.security.authentication</name>
    <value>kerberos</value> 
  </property>

  <property>
    <name>hadoop.security.authorization</name>
    <value>true</value>
  </property>
```

```hdfs-site.xml
  <!-- For Kerberos -->
  <!-- General HDFS security config -->
  <property>
    <name>dfs.block.access.token.enable</name>
    <value>true</value>
  </property>
  
  <!-- NameNode security config -->
  <property>
    <name>dfs.namenode.keytab.file</name>
    <value>/etc/hadoop/conf/hdfs.keytab</value> <!-- path to the HDFS keytab -->
  </property>
  <property>
    <name>dfs.namenode.kerberos.principal</name>
    <value>hdfs/_HOST@EXAMPLE.COM</value>
  </property>
  <property>
    <name>dfs.namenode.kerberos.internal.spnego.principal</name>
    <value>HTTP/_HOST@EXAMPLE.COM</value>
  </property>
  
  <!-- Secondary NameNode security config -->
  <property>
    <name>dfs.secondary.namenode.keytab.file</name>
    <value>/etc/hadoop/conf/hdfs.keytab</value> <!-- path to the HDFS keytab -->
  </property>
  <property>
    <name>dfs.secondary.namenode.kerberos.principal</name>
    <value>hdfs/_HOST@EXAMPLE.COM</value>
  </property>
  <property>
    <name>dfs.secondary.namenode.kerberos.internal.spnego.principal</name>
    <value>HTTP/_HOST@EXAMPLE.COM</value>
  </property>
  
  <!-- DataNode security config -->
  <property>
    <name>dfs.datanode.data.dir.perm</name>
    <value>700</value> 
  </property>
  <property>
    <name>dfs.datanode.address</name>
    <value>0.0.0.0:1004</value>
  </property>
  <property>
    <name>dfs.datanode.http.address</name>
    <value>0.0.0.0:1006</value>
  </property>
  <property>
    <name>dfs.datanode.keytab.file</name>
    <value>/etc/hadoop/conf/hdfs.keytab</value> <!-- path to the HDFS keytab -->
  </property>
  <property>
    <name>dfs.datanode.kerberos.principal</name>
    <value>hdfs/_HOST@EXAMPLE.COM</value>
  </property>
  
  <!-- Web Authentication config -->
  <property>
    <name>dfs.web.authentication.kerberos.principal</name>
    <value>HTTP/_HOST@EXAMPLE.COM</value>
  </property>
```

今回はSecondaryNameNodeを利用しているが、JournalNodeを使っている場合はJournalNode向けの設定が必要となる。その場合は、以下のような項目を指定する。

```
<property>
  <name>dfs.journalnode.keytab.file</name>
  <value>/etc/hadoop/conf/hdfs.keytab</value> <!-- path to the HDFS keytab -->
</property>
<property>
  <name>dfs.journalnode.kerberos.principal</name>
  <value>hdfs/_HOST@EXAMPLE.COM</value>
</property>
<property>
  <name>dfs.journalnode.kerberos.internal.spnego.principal</name>
  <value>HTTP/_HOST@EXAMPLE.COM</value>
</property>
```

## DataNodeの環境変数の設定変更

以下を設定する。JSVC_HOME以外はコメントアウトを外すだけ。

```/etc/default/hadoop-hdfs-datanode
export HADOOP_SECURE_DN_USER=hdfs
export HADOOP_SECURE_DN_PID_DIR=/var/run/hadoop-hdfs
export HADOOP_SECURE_DN_LOG_DIR=/var/log/hadoop-hdfs
export JSVC_HOME=/usr/lib/bigtop-utils/
```

## NameNodeの起動

最初の関門である。
祈りながら起動する。

```
# systemctl start hadoop-hdfs-namenode.service
# jps
8053 Jps
7976 NameNode
```

念のためログを見てKerberos認証に成功しているかどうかを確認する。

```
2016-03-17 01:21:52,803 INFO org.apache.hadoop.security.UserGroupInformation: Login successful for user hdfs/locke.example.com@EXAMPLE.COM using keytab file /etc/hadoop/conf/hdfs.keytab
```

### うまくいかない時

悲劇の始まり。今までの手順で何かしら間違っているところがあるはずなので、真摯に振り返る。SAN値がモリモリ下がるので、精神の安定を図る手段は必須である。

第一歩として、JavaからKerberos周りのDEBUGログを出すようにすると良かった。

```hadoop-env.sh
export HADOOP_OPTS="-Dsun.security.krb5.debug=true -Djava.net.preferIPv4Stack=true $HADOOP_CLIENT_OPTS"
```

その他、[Clouderaのドキュメント](http://www.cloudera.com/documentation/enterprise/latest/topics/cm_sg_sec_troubleshooting.html)にFAQ的な情報があるので、参考にする。

自分がハマった点を挙げておくと

* Kerberosの設定ミス(kdc.conf, krb.conf)
* JCEのインストール忘れ
* keytabファイルのパーミッション設定ミス
* keytabファイルにHTTPプリンシパルを入れ忘れている

あたりを引いた。


## SecondaryNameNodeの起動

```
# systemctl start hadoop-hdfs-secondarynamenode.service
```

## DataNodeの起動

```
# systemctl start hadoop-hdfs-datanode.service
```

## hdfsユーザによる起動確認

hdfsユーザでkey tabを使って認証して、hdfsコマンドを打ってみる。

```
# su - hdfs
-bash-4.2$ kinit hdfs/locke.example.com@EXAMPLE.COM -kt /etc/hadoop/conf/hdfs.keytab 
-bash-4.2$ klist -e
Ticket cache: FILE:/tmp/krb5cc_993
Default principal: hdfs/locke.example.com@EXAMPLE.COM

Valid starting       Expires              Service principal
2016-03-17T02:42:54  2016-03-18T02:42:54  krbtgt/EXAMPLE.COM@EXAMPLE.COM
	Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96 
-bash-4.2$ hdfs dfsadmin -report
Configured Capacity: 9082765312 (8.46 GB)
Present Capacity: 6496538624 (6.05 GB)
DFS Remaining: 6496038912 (6.05 GB)
DFS Used: 499712 (488 KB)
DFS Used%: 0.01%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0
Missing blocks (with replication factor 1): 0

-------------------------------------------------
Live datanodes (1):

Name: 192.168.56.101:1004 (locke.example.com)
Hostname: locke.example.com
Decommission Status : Normal
Configured Capacity: 9082765312 (8.46 GB)
DFS Used: 499712 (488 KB)
Non DFS Used: 2586226688 (2.41 GB)
DFS Remaining: 6496038912 (6.05 GB)
DFS Used%: 0.01%
DFS Remaining%: 71.52%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 2
Last contact: Thu Mar 17 02:43:06 JST 2016


-bash-4.2$ hdfs dfs -ls /
Found 5 items
drwxrwxrwx   - hdfs  supergroup          0 2016-03-17 00:37 /benchmarks
drwxr-xr-x   - hbase supergroup          0 2016-03-17 00:37 /hbase
drwxrwxrwt   - hdfs  supergroup          0 2016-03-17 00:37 /tmp
drwxr-xr-x   - hdfs  supergroup          0 2016-03-17 00:38 /user
drwxr-xr-x   - hdfs  supergroup          0 2016-03-17 00:38 /var
```

# YARNのKerberos化

## 設定ファイルの変更

```yarn-site.xml
  <!-- For Kerberos -->
  <!-- ResourceManager security configs -->
  <property>
    <name>yarn.resourcemanager.keytab</name>
    <value>/etc/hadoop/conf/yarn.keytab</value>       <!-- path to the YARN keytab -->
  </property>
  <property>
    <name>yarn.resourcemanager.principal</name>
    <value>yarn/_HOST@EXAMPLE.COM</value>
  </property>
 
  <!-- NodeManager security configs -->
  <property>
    <name>yarn.nodemanager.keytab</name>
    <value>/etc/hadoop/conf/yarn.keytab</value>       <!-- path to the YARN keytab -->
  </property>
  <property>
    <name>yarn.nodemanager.principal</name>
    <value>yarn/_HOST@EXAMPLE.COM</value>
  </property>
  <property>
    <name>yarn.nodemanager.container-executor.class</name>
    <value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor</value>
  </property>
  <property>
    <name>yarn.nodemanager.linux-container-executor.group</name>
    <value>yarn</value>
  </property>
```

```mapped-site.xml
  <!-- MapReduce Job History Server security configs -->
  <property>
    <name>mapreduce.jobhistory.address</name>
    <value>locke.example.com:10020</value> <!-- Host and port of the MapReduce Job History Server; default port is 10020  -->
  </property>
  <property>
    <name>mapreduce.jobhistory.keytab</name>
    <value>/etc/hadoop/conf/mapred.keytab</value>     <!-- path to the MAPRED keytab for the Job History Server -->
  </property>
  <property>
    <name>mapreduce.jobhistory.principal</name>
    <value>mapred/_HOST@EXAMPLE.COM</value>
  </property>
```

ContainerExecutorをLinuxContainerExecutorに設定しているので、container-executor.cfgも必要となる。設定内容はこんな感じ。環境に合わせて設定値は変える。

```container-executor.cfg
yarn.nodemanager.local-dirs=/var/lib/hadoop-yarn/cache/yarn/nm-local-dir
yarn.nodemanager.linux-container-executor.group=yarn
yarn.nodemanager.log-dirs=/var/log/hadoop-yarn/containers
banned.users=hdfs,yarn,mapred,bin       
min.user.id=500
```

注意する点として、きもいパーミッションにする必要がある。

```
 chown root:yarn /etc/hadoop/conf/container-executor.cfg 
# chmod 040 /etc/hadoop/conf/container-executor.cfg 
# chmod +s /etc/hadoop/conf/container-executor.cfg 
# ll /etc/hadoop/conf/container-executor.cfg 
---Sr-S--- 1 root yarn 241  3月 17 02:59 /etc/hadoop/conf/container-executor.cfg
```

## YARNの起動

```
# systemctl start hadoop-yarn-resourcemanager.service
# systemctl start hadoop-yarn-nodemanager.service
```

## yarnユーザによる確認

```
# su - yarn
-bash-4.2$ kinit yarn/locke.example.com@EXAMPLE.COM -kt /etc/hadoop/conf/yarn.keytab 
-bash-4.2$ klist -e
Ticket cache: FILE:/tmp/krb5cc_992
Default principal: yarn/locke.example.com@EXAMPLE.COM

Valid starting       Expires              Service principal
2016-03-17T03:06:40  2016-03-18T03:06:40  krbtgt/EXAMPLE.COM@EXAMPLE.COM
	Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96 
-bash-4.2$ yarn node -list 
16/03/17 03:06:45 INFO client.RMProxy: Connecting to ResourceManager at /0.0.0.0:8032
Total Nodes:1
         Node-Id	     Node-State	Node-Http-Address	Number-of-Running-Containers
locke.example.com:46070	        RUNNING	locke.example.com:8042	                           0
```

## MapReduce JobHistoryServerの起動

```
# systemctl start hadoop-mapreduce-historyserver.service
```

## MapReduceジョブの実行確認

aliceユーザでMapReduceジョブを実行してみる。まずはHDFS上にユーザディレクトリを作成する。

```
# su - hdfs
-bash-4.2$ hdfs dfs -mkdir /user/alice
-bash-4.2$ hdfs dfs -chown alice /user/alice
```

aliceユーザでサンプルMapReduceを実行してみる。

```
# su - alice
$ hadoop jar /usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.6.0.jar pi 1 1000
Number of Maps  = 1
Samples per Map = 1000
Wrote input for Map #0
Starting Job
16/03/17 03:10:55 INFO client.RMProxy: Connecting to ResourceManager at /0.0.0.0:8032
16/03/17 03:10:55 INFO hdfs.DFSClient: Created HDFS_DELEGATION_TOKEN token 1 for alice on 192.168.56.101:8020
16/03/17 03:10:55 INFO security.TokenCache: Got dt for hdfs://locke.example.com:8020; Kind: HDFS_DELEGATION_TOKEN, Service: 192.168.56.101:8020, Ident: (HDFS_DELEGATION_TOKEN token 1 for alice)
16/03/17 03:10:55 INFO input.FileInputFormat: Total input paths to process : 1
16/03/17 03:10:55 INFO mapreduce.JobSubmitter: number of splits:1
16/03/17 03:10:55 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1458151346929_0001
16/03/17 03:10:55 INFO mapreduce.JobSubmitter: Kind: HDFS_DELEGATION_TOKEN, Service: 192.168.56.101:8020, Ident: (HDFS_DELEGATION_TOKEN token 1 for alice)
16/03/17 03:10:56 INFO impl.YarnClientImpl: Submitted application application_1458151346929_0001
16/03/17 03:10:56 INFO mapreduce.Job: The url to track the job: http://locke.example.com:8088/proxy/application_1458151346929_0001/
16/03/17 03:10:56 INFO mapreduce.Job: Running job: job_1458151346929_0001
16/03/17 03:11:05 INFO mapreduce.Job: Job job_1458151346929_0001 running in uber mode : false
16/03/17 03:11:05 INFO mapreduce.Job:  map 0% reduce 0%
16/03/17 03:11:10 INFO mapreduce.Job:  map 100% reduce 0%
16/03/17 03:11:15 INFO mapreduce.Job:  map 100% reduce 100%
16/03/17 03:11:16 INFO mapreduce.Job: Job job_1458151346929_0001 completed successfully
16/03/17 03:11:16 INFO mapreduce.Job: Counters: 49
	File System Counters
		FILE: Number of bytes read=28
		FILE: Number of bytes written=227605
		FILE: Number of read operations=0
		FILE: Number of large read operations=0
		FILE: Number of write operations=0
		HDFS: Number of bytes read=273
		HDFS: Number of bytes written=215
		HDFS: Number of read operations=7
		HDFS: Number of large read operations=0
		HDFS: Number of write operations=3
	Job Counters 
		Launched map tasks=1
		Launched reduce tasks=1
		Data-local map tasks=1
		Total time spent by all maps in occupied slots (ms)=2352
		Total time spent by all reduces in occupied slots (ms)=2775
		Total time spent by all map tasks (ms)=2352
		Total time spent by all reduce tasks (ms)=2775
		Total vcore-seconds taken by all map tasks=2352
		Total vcore-seconds taken by all reduce tasks=2775
		Total megabyte-seconds taken by all map tasks=2408448
		Total megabyte-seconds taken by all reduce tasks=2841600
	Map-Reduce Framework
		Map input records=1
		Map output records=2
		Map output bytes=18
		Map output materialized bytes=28
		Input split bytes=155
		Combine input records=0
		Combine output records=0
		Reduce input groups=2
		Reduce shuffle bytes=28
		Reduce input records=2
		Reduce output records=0
		Spilled Records=4
		Shuffled Maps =1
		Failed Shuffles=0
		Merged Map outputs=1
		GC time elapsed (ms)=136
		CPU time spent (ms)=1050
		Physical memory (bytes) snapshot=503672832
		Virtual memory (bytes) snapshot=5563736064
		Total committed heap usage (bytes)=445644800
	Shuffle Errors
		BAD_ID=0
		CONNECTION=0
		IO_ERROR=0
		WRONG_LENGTH=0
		WRONG_MAP=0
		WRONG_REDUCE=0
	File Input Format Counters 
		Bytes Read=118
	File Output Format Counters 
		Bytes Written=97
Job Finished in 21.452 seconds
Estimated value of Pi is 3.14800000000000000000
```

やった！

正直、手で設定するのはつらいので、素直にClouderaManagerやAmbariを利用した方が良いと思われる。
一度は手でやっておくとわかった気になるという利点はある。数学の定理の証明みたいなものか。。。

# 2016/03/25 追記

一部環境でhdfsコマンド実行時に以下のようなエラーが出ることがあった。

```
16/03/25 12:09:10 WARN security.UserGroupInformation: Exception encountered while running the renewal command. Aborting renew thread. ExitCodeException exitCode=1: kinit: Ticket expired while renewing credentials
```

これは、hdfsコマンドが内部でKerberosのチケットのrenewをしようとして失敗しているために出力されている。

直接的に確認するには、`kinit -R`を実行してみる。

```
$ kinit -R
kinit: Ticket expired while renewing credentials
```

原因としては、Kerberos側で作成したプリンシパルのmaxrenewlifeがデフォルトの0となっていて、renewしようとしても伸ばせなくなっていることが多い。

この状態になっていることを確認するには、kadminでKDCに接続して以下のコマンドを実行する。

```
kadmin.local:  getprinc alice/locke.example.com@EXAMPLE.COM
Principal: alice/locke.example.com@EXAMPLE.COM
Expiration date: [never]
Last password change: Tue Mar 15 17:09:55 JST 2016
Password expiration date: [none]
Maximum ticket life: 1 day 00:00:00
Maximum renewable life: 0 days 00:00:00   ★ここが0 daysになっているかどうか。
Last modified: Tue Mar 15 17:09:55 JST 2016 (root/admin@EXAMPLE.COM)
Last successful authentication: [never]
Last failed authentication: [never]
Failed password attempts: 0
Number of keys: 3
Key: vno 1, aes256-cts-hmac-sha1-96, no salt
Key: vno 1, aes128-cts-hmac-sha1-96, no salt
Key: vno 1, arcfour-hmac, no salt
MKey: vno 1
Attributes:
Policy: [none]
```

modprincでプリンシパルのmaxrenewlifeを変更できる。

```
kadmin.local:   modprinc -maxrenewlife 1week
```

なお、今後新しく作られるプリンシパルに対してのデフォルト設定を変更する場合、krbtgt/EXAMPLE.COM@EXAMPLE.COMのmaxrenewlifeを変更しておくと良いらしい。

以下のページが参考になった。
http://championofcyrodiil.blogspot.jp/2014/01/kinit-ticket-expired-while-renewing.html