Hadoop 클러스터를 구성하고 나면 관제 및 몇몇 기능을 제공하는 웹 인터페이스가 있음.

참조: Hadoop Web Interface Port List


이게 아무 인증도 없이 그냥 포털사이트마냥 뻥 뚫려 있어서, 네트워크 레벨에서 차단되어 있지 않다면 누군가 홀랑 다 벗겨갈 수 있음.

어느 미친 또라이가 Hadoop cluster를 외부에 개방된 네트워크에 구성하겠냐마는 그래도 혹시 몰라 인증이 필요하면 아래의 방법을 사용할 수 있음.

결국엔 Jetty의 Realm을 설정하는 방식.


[주의]

1. 이 방법은 NameNode, JobTracker, Datanode 등 기존 Hadoop을 구성하던 것들만 가능함. YARN에 딸린 ResourceManager 등은 이 방법으로 인증기능을 구현할 수 없음.

2. Web UI에 인증을 달면 Servlet Component를 이용하는 일부 커맨드가 동작하지 않을 수 있으므로 주의를 요함. 예를 들어 NameNode에 인증을 달고 콘솔에서 hdfs fsck 명령어를 넣으면 인증을 못해서 에러(Exception in thread "main" java.io.IOException: Server returned HTTP response code: 401)가 났다면서 Exception을 토해냄. 우회하는 법은 맨 아래에 적음.




인증달기.


위에서 적었듯이 결국엔 Jetty Realm 설정임.

기준은 NameNode. 나머지 것들은 어차피 경로만 차이가 남.


1. web.xml 

$HADOOP_HOME/webapps/hdfs/WEB-INF/web.xml 파일을 까서 아래 내용 추가.

Hadoop2는 $HADOOP_HOME/share/hadoop/hdfs/webapps/hdfs/WEB-INF/web.xml


<security-constraint> 
    <web-resource-collection> 
        <web-resource-name>Protected</web-resource-name> 
        <url-pattern>/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
        <role-name>admin</role-name> 
    </auth-constraint> 
</security-constraint> 
<login-config> 
    <auth-method>BASIC</auth-method> 
    <realm-name>namenodeRealm</realm-name> 
</login-config>


참고로 각 프로세스에 대한 web.xml 경로는 아래와 같음.

NameNode

Ver1: $HADOOP_HOME/webapps/hdfs/WEB-INF/web.xml

Ver2: $HADOOP_HOME/share/hadoop/hdfs/webapps/hdfs/WEB-INF/web.xml


SecondaryNameNode

Ver1: $HADOOP_HOME/webapps/secondary/WEB-INF/web.xml

Ver2: $HADOOP_HOME/share/hadoop/hdfs/webapps/secondary/WEB-INF/web.xml


JobTracker

Ver1: $HADOOP_HOME/webapps/job/WEB-INF/web.xml

Ver2: 없음


DataNode

Ver1: $HADOOP_HOME/webapps/datanode/WEB-INF/web.xml

Ver2: $HADOOP_HOME/share/hadoop/hdfs/webapps/datanode/WEB-INF/web.xml


TaskTracker

Ver1: $HADOOP_HOME/webapps/task/WEB-INF/web.xml

Ver2: 없음




2. jetty-web.xml

web.xml 을 수정한 디렉토리에 jetty-web.xml 파일을 만들고 내용을 아래처럼 구성.


<Configure class="org.mortbay.jetty.webapp.WebAppContext"> 
    <Get name="securityHandler"> 
        <Set name="userRealm"> 
            <New class="org.mortbay.jetty.security.HashUserRealm"> 
                <Set name="name">namenodeRealm</Set> 
                <Set name="config"> 
                    <SystemProperty name="hadoop.home.dir"/>/jetty/etc/realm.properties 
                </Set> 
            </New> 
        </Set> 
    </Get> 
</Configure>




3. 비번생성


아래 명령어로 폴더 만들고 해당 폴더로 이동한 다음,

[root@localhost]# mkdir -p $HADOOP_HOME/jetty/etc

[root@localhost]# cd $HADOOP_HOME/jetty/etc


jetty로 비번 생성

참고로 버전별 jetty jar 파일 경로는 다음과 같음.

Ver1: $HADOOP_HOME/lib

Ver2: $HADOOP_HOME/share/hadoop/tools/lib

[root@localhost]# java -cp $HADOOP_HOME/lib/jetty-6.1.26.jar:$HADOOP_HOME/lib/jetty-util-6.1.26.jar org.mortbay.jetty.security.Password USERNAME PASSWORD

// 위 명령어를 입력하면 아래와 같은 출력이 나옴.

PASSWORD

OBF:1iff1i7i1l6r1mrf1mrn1l6j1i8g1ier

MD5:319f4d26e3c536b5dd871bb2c52e3178

CRYPT:ro8DyhbzQiPss


이제 $HADOOP_HOME/jetty/etc 디렉토리에서 realm.properties 파일을 하나 만들어 아래와 같은 형태로 작성하고 저장.

비번은 OBF, MD5, CRYPT 아무거나 원하는 거 사용하면 됨.

마지막 부분의 ,admin 빼먹지 않게 주의할 것. role-name 임.

USERNAME: MD5:319f4d26e3c536b5dd871bb2c52e3178,admin




4. namenode restart

[root@localhost]# $HADOOP_HOME/bin/hadoop-daemon.sh stop namenode

[root@localhost]# $HADOOP_HOME/bin/hadoop-daemon.sh start namenode



이제 브라우저로 http://NAMENODE:50070 접속하면 비번 넣으라고 함.

나머지 JobTracker 등도 동일한 방법으로 인증을 다는 것이 가능함.






예외처리


인증을 달고나면 기존에 하던 짓이 안되는 경우가 있음.

예를 들어 NameNode 이미지 백업할 때 아래와 같은 명령어로 할텐데 인증이 없으므로 안됨.

[root@localhost]# curl -s http://NAMENODE:50070/getimage?getimage=1 > $BACKUP_DIR/fsimage


curl 요청할 때 인증내용을 넣어주면 해결됨.

[root@localhost]# curl -s http://USERNAME:PASSWORD@NAMENODE:50070/getimage?getimage=1 > $BACKUP_DIR/fsimage


진짜 골 때리는 건 fsck 임.

인증을 달고 fsck 명령어를 실행하면 아래와 같은 현상이 발생함. (Hadoop 2.6.0 기준)

[root@localhost] $HADOOP_HOME/bin/hdfs fsck /

Connecting to namenode via http://NAMENODE:50070

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 401 for URL: http://NAMENODE:50070/fsck?ugi=root&path=%2F

        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)

        at org.apache.hadoop.hdfs.tools.DFSck.doWork(DFSck.java:307)

        at org.apache.hadoop.hdfs.tools.DFSck.access$000(DFSck.java:72)

        at org.apache.hadoop.hdfs.tools.DFSck$1.run(DFSck.java:145)

        at org.apache.hadoop.hdfs.tools.DFSck$1.run(DFSck.java:142)

        at java.security.AccessController.doPrivileged(Native Method)

        at javax.security.auth.Subject.doAs(Subject.java:416)

        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)

        at org.apache.hadoop.hdfs.tools.DFSck.run(DFSck.java:141)

        at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)

        at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:84)

        at org.apache.hadoop.hdfs.tools.DFSck.main(DFSck.java:341)



이걸 fsck 명령어의 옵션 레벨로 인증하는 방법은 도무지 모르겠고, (누가 알면 가르쳐 주십시오 /굽신굽신/) 

어차피 내부적으로 Web Interface를 이용하므로 그냥 curl 로 해주면 됨...;

[root@localhost] curl 'http://USERNAME:PASSWORD@NAMENODE:50070/fsck?ugi=root&path=/'

FSCK started by root (auth:SIMPLE) from /NAMENODE for path / at Wed Mar 25 15:45:07 KST 2015

................................................................................................Status: HEALTHY

 Total size:    13781737632 B

 Total dirs:    60

 Total files:   96

 Total symlinks:                0

 Total blocks (validated):      272 (avg. block size 50668153 B)

 Minimally replicated blocks:   272 (100.0 %)

 Over-replicated blocks:        0 (0.0 %)

 Under-replicated blocks:       0 (0.0 %)

 Mis-replicated blocks:         0 (0.0 %)

 Default replication factor:    3

 Average block replication:     3.0

 Corrupt blocks:                0

 Missing replicas:              0 (0.0 %)

 Number of data-nodes:          7

 Number of racks:               1

FSCK ended at Wed Mar 25 15:45:07 KST 2015 in 123 milliseconds



The filesystem under path '/' is HEALTHY


// files, blocks 등의 옵션은 query string으로 추가해주면 됨

// 엄청나게 나올 것이므로 결과를 텍스트 파일로 저장함...

[root@localhost]# curl -s 'http://USERNAME:PASSWORD@NAMENODE:50070/fsck?ugi=root&path=/&files=1&blocks=1&locations=1&racks=1' > ./fsck.txt






진짜 제대로 인증기능을 추가하려면 Kerberos가 본격 출동해야 하겠지만, 

이정도만 하면 여하튼 일단 누군가가 포털 사이트 뉴스기사 뒤지듯 클릭질 몇 번으로 내 Hadoop cluster를 뒤질 일은 없게 됨.















Posted by bloodguy
,