티스토리 뷰

HDFS Client 코드리뷰를 하다가 테스트를 위해 소규모 하둡 클러스터를 도커에 실행시키고 외부에서 DFSClient를 이용한 애플리케이션을 디버깅 모드로 돌려보고 싶었다. 미리 구축해 놓은 PM(Physical Machine) 기반의 하둡 클러스터나 Stand Alone 모드의 하둡을 사용해도 되지만 필요할 때마다 그때 그때 컨테이너를 생성해서 클러스터를 구축해보는 경험도 좋을 것 같아서 도커(Docker) 기반으로 하둡 클러스터를 구축해보기로 했다.

 

물론 이미 다양한 종류의 하둡 클러스터 이미지들이 공개되어 있다. 하지만 직접 컨테이너 이미지를 만들어 쓰는 방법을 기술하고 해보는 것도 좋은 경험이 될 것 같아서 그렇게 진행했다.

실행환경

  • Host : Mac OS Catalina

  • Ubuntu Image : Ubuntu 18.04.3 LTS

  • Docker version 19.03.4 build 9013bf5

  • Java version : 1.8

하둡 베이스 도커 이미지 만들기

우선 우분투 이미지를 받아서 하둡을 설치할 컨테이너를 띄워 보자.

$ docker run -it --name hadoop-base ubuntu

 

깡통 우분투 컨테이너에 하둡을 설치할 수 있도록 패키지들을 여러개 설치해보자. apt-get 을 최신으로 업데이트 한다.

# apt-get update

 

여기에 써 놓은것 이외에 필요한 패키지가 더 있다면 추가로 설치해도 좋다. 우선 자바를 설치한다.

# apt-get install openjdk-8-jdk -y

 

일단은 그냥 Open JDK 를 설치하겠다. 오라클 버전의 JDK 를 설치하려면 이것저것 추가로 해줘야하는게 있는데 귀찮기도하고 테스트를 위한 클러스터 구축이기 때문에 그냥 Open JDK 를 설치하겠다. (나중에 오라클 JDK가 필요하게 되면 그 때 정리해놓겠다.)

 

자바 설치 후 java -version 명령을 이용해서 잘 설치되었는지 확인하자. apt-get 으로 설치한 JAVA_HOME의 경로는 /usr/lib/jvm/java-8-openjdk-amd64 다.

 

하둡 바이너리를 다운받기 위해 'wget'을 설치하자.

# apt-get install wget -y

 

정신건강을 위해 추가로 vim 도 설치해주자. (emacs 설치해도 된다.)

# apt-get install vim -y

 

클러스터의 다른 노드들과의 연결을 위해 ssh 설치를 해준다.

# apt-get install ssh -y

 

별도의 로그인 없이 동작할 수 있도록 키 파일을 생성해주자.

# ssh-keygen -t rsa -P '' -f ~/.ssh/id_dsa
# cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

 

'Missing privilege separation directory: /run/sshd' 오류가 발생하지 않도록 관련 디렉토리도 만들어준다.

# mkdir /var/run/sshd

 

이제 하둡 바이너리를 다운로드해서 설치할 디렉토리를 세팅하고, wget 을 이용해서 하둡 바이너리를 다운로드하자.

# mkdir /hadoop_home
# cd /hadoop_home
# wget http://mirrors.sonic.net/apache/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz
# tar xvzf hadoop-2.7.7.tar.gz

 

tar 를 이용해서 아카이브 파일을 풀어놓으면 하둡 바이너리 설치가 끝난 것이다.

 

이제 편의를 위해 .bashrc 파일에 하둡 관련 환경 변수들을 세팅해보자.

# vi ~/.bashrc
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HADOOP_HOME=/hadoop_home/hadoop-2.7.7
export HADOOP_CONFIG_HOME=$HADOOP_HOME/etc/hadoop
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin

# run sshd
/usr/sbin/sshd

 

이제 docker attach 혹은 run -it 등을 이용해서 컨테이너에 붙을 때 환경 변수가 세팅된다.

# source ~/.bashrc 

환경변수를 적용한다.

 

하둡 클러스터의 네임노드와 데이터 노드가 사용할 디렉토리 그리고 임시 디렉토리를 만들어 주자.

# mkdir /hadoop_home/temp
# mkdir /hadoop_home/namenode_home
# mkdir /hadoop_home/datanode_home

 

다음으로 하둡관련 xml 파일들을 수정해보자. 최초 아카이브에는 mapred-site.xml 파일이 없고 mapred-site.xml.template 파일만 있다. mapred-site.xml 파일을 만들어 준다.

# cd $HADOOP_CONFIG_HOME
# cp mapred-site.xml.template mapred-site.xml

 

이제 'core-site.xml', 'hdfs-site.xml', 'mapred-site.xml' 파일을 수정해줘야 한다. 각 파일의 내용을 다음과 같이 수정해주면 된다.

 

core-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/hadoop_home/temp</value>
    </property>

    <property>
        <name>fs.default.name</name>
        <value>hdfs://master:9000</value>
        <final>true</final>
    </property>
</configuration>

 

hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
        <final>true</final>
    </property>

    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/hadoop_home/namenode_home</value>
        <final>true</final>
    </property>

    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/hadoop_home/datanode_home</value>
        <final>true</final>
    </property>
</configuration>

 

mapred-site.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>
    <property>
        <name>mapred.job.tracker</name>
        <value>master:9001</value>
    </property>
</configuration>

 

hadoop-env.sh 파일의 마지막에 JAVA_HOME 환경 변수를 지정해준다.

...

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

 

이제 네임노드를 포맷한다.

# hadoop namenode -format

 

'SHUTDOWN_MSG: Shutting down NameNode at ??? ' 뭐 이런 메시지가 출력되면서 포맷이 성공적으로 종료된다. '/hadoop_home/namenode_home' 디렉토리에 가보면 뭔가 파일들이 생성되어 있다.

 

이제 하둡 컨테이너가 완성되었다. 이 컨테이너의 변경 사항을 도커 이미지로 만들어 놓자. 호스트 운영체제에서 도커 컨테이너를 커밋한다.

$ docker commit hadoop-base ubuntu:hadoop

 

하둡 클러스터 구동하기

이제 만들어진 도커 이미지를 이용해서 마스터 노드 하나와 슬레이브 노드 두 개를 구동시켜보자. 터미널 3개를 열어서 다음 명령을 각각 실행한다.

$ docker run -it -h master --name master -p {HostMachinePort for admin page}:50070 ubuntu:hadoop
$ docker run -it -h slave1 --name slave1 --link master:master ubuntu:hadoop
$ docker run -it -h slave2 --name slave2 --link master:master ubuntu:hadoop

 

여기서 마스터를 구동할 때 {HostMachinePort for admin page} 부분에 네임노드의 admin 웹 페이지로 접속할 때 사용할 호스트 운영체제의 포트 번호를 입력하면 된다. 도커의 -p 옵션을 이용하여 입력한 포트를 마스터 노드의 50070 포트로 포트포워딩을 해준다.

 

3개의 컨테이너가 구동중이지만 아직 하둡 데몬들은 구동되지 않았다. 하둡 데몬을 구동하기 위한 몇 가지 작업을 해보자. 우선 두 개의 슬레이브 노드의 가상 IP 주소를 확인해보자. 호스트 운영체제에서 도커의 inspect 명령을 이용해서 가상 IP 정보를 확인해본다.

$ docker inspect slave1 | grep IPAddress
$ docker inspect slave2 | grep IPAddress

 

현재 도커에서 구동중인 컨테이너가 마스터와 슬레이브 1, 슬레이브 2 밖에 없는 상황이라 할당된 가상 IP는 다음과 같았다.

  • Master : 172.17.0.2

  • Slave1 : 172.17.0.3

  • Slave2 : 172.17.0.4

이 값은 실제 inspect 명령으로 돌려봐야 정확하게 알 수 있으며, 사용자의 도커 컨테이너 구동 상황에 따라 다를 수 있다. 직접 확인한 다음 사용하기 바란다.

 

이제 마스터 컨테이너로 붙어서 호스트 파일을 수정해준다.

$ docker attach master
root@master:~# vi /etc/hosts

 

/etc/hosts 파일에 슬레이브 노드들의 가상 IP 주소를 추가해 준다.

 

/etc/hosts 파일

...
172.17.0.2 master

172.17.0.3 slave1
172.17.0.4 slave2

 

$HADOOP_CONFIG_HOME 디렉토리로 이동해서 slaves 파일을 수정한다.

# cd $HADOOP_CONFIG_HOME
# vi slaves

 

이 파일에는 데이터 노드로 동작할 컨테이너들의 목록이 적힌다.

slave1
slave2
master

 

3개의 컨테이너 모두 데이터노드로 동작하도록 구성을 해보자.

 

이제 'start-all.sh' 스크립트로 하둡 클러스터를 구동시킨다.

# start-all.sh

 

하둡의 sbin을 PATH 경로로 잡아뒀으므로 그냥 동작할꺼다. 스크립트를 실행하면 뭔가를 자꾸 말해주면서 'yes/no'를 선택하라고 할 텐데 그냥 전부 yes 로 입력하면 된다. (stdout, stderr 의 메시지가 한번에 섞이면서 헷갈릴 수 있는데, 그냥 뭔가 화면에 출력되는 내용이 멈췄다 싶으면 'yes'를 계속해서 입력해주면 된다. )

 

jps 명령을 입력해보면,

# jps
704 NodeManager
273 DataNode
440 SecondaryNameNode
138 NameNode
990 Jps
591 ResourceManager

 

Hadoop 관련된 데몬들이 정상적으로 실행되고 있는게 보일꺼다.

 

slave 노드에 붙어서 jps 명령을 실행하면,

# jps
245 Jps
149 NodeManager
39 DataNode

 

역시 하둡관련 데몬들이 떠있다. 하둡 클러스터의 현 상황을 보고 싶으면

# hdfs dfsadmin -report

 

명령을 실행해보면 된다. 'Live datanodes (3): ' 라는 출력에서 3개의 데이터노드가 구동되고 있음을 확인할 수 있다. 다음 명령을 이용해서 HDFS에 디렉토리를 만들어보자.

# hadoop fs -mkdir -p /user/dave
# hadoop fs -ls /

 

ls 명령을 실행해보면,

# hadoop fs -ls /
Found 1 items
drwxr-xr-x - root supergroup 0 2019-11-16 14:16 /user

 

디렉토리가 만들어졌음을 볼 수 있다.

 

Admin 페이지

웹 브라우저를 열고 'localhost:{Host Machine Port}' 주소를 입력하면 마스터 컨테이너에서 동작하고 있는 Admin 웹 페이지 데몬으로 접속해서 현재 하둡 클러스터의 상태를 웹 브라우저로 볼 수 있다. (Host Machine Port 값은 마스터 컨테이너를 띄울 때 입력했던 포트 번호를 사용하면 된다.)

이 페이지의 'Utilities' 탭을 선택해보면 구축한 HDFS 의 파일 시스템 디렉토리 구조를 웹에서 볼 수도 있다. 매우 유용하다.

 

간단한 테스트 해보기

하둡 책을 보면 항상 'Wordcount' 예제를 실행한다. 파일에 있는 단어들을 파싱하고 개수를 세어서 결과로 출력해주는 MapReduce 예제를 하둡 클러스터를 구축하고나서 한번씩 돌려본다. 하둡의 'Hello World' 프로그램이라고 보면 된다.

 

위에서 구축한 클러스터에 붙기 위해 클라이언트 컨테이너를 하나 더 띄워보자.

$ docker run -it -h client --name client --link master:master ubuntu:hadoop

 

설치된 하둡의 LICENSE.txt 파일에 WordCount 예제를 돌려보겠다.

# cd $HADOOP_HOME
# ls
LICENSE.txt NOTICE.txt README.txt bin etc include lib libexec sbin share

 

테스트를 위한 테스트 디렉토리를 HDFS에 생성하고, hadoop fs 명령을 이용해서 구축한 클러스터에 LICENSE.txt 파일을 올린다.

# hadoop fs -mkdir -p /test
# hadoop fs -put LICENSE.txt /test
# hadoop fs -ls /test
Found 1 items
-rw-r--r-- 2 root supergroup 86424 2019-11-16 07:05 /test/LICENSE.txt

 

하둡 패키지에 기본적으로 제공되는 jar 파일을 이용해서 wordcount 예제를 돌려본다.

# hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar wordcount /test /test_out

 

MapReduce 작업이 Submit 되고 짧은 수행시간안에 작업이 끝난다. 이제 WordCount 결과를 살펴보자.

# hadoop fs -cat /test_out/*
...
wherever 1
whether 9
which 32
which, 2
which: 1
who 2
whole, 2
whom 8
will 7
with 99
withdraw 2
within 20
without 42
work 11
work, 3
work. 2
works 3
works, 1
world-wide, 4
worldwide, 4
would 1
writing 2
writing, 3
written 11
xmlenc 1
year 1
you 9
your 4
252.227-7014(a)(1)) 1
§ 1
“AS 1
“Contributor 1
“Contributor” 1
“Covered 1
“Executable” 1
“Initial 1
“Larger 1
“Licensable” 1
“License” 1
“Modifications” 1
“Original 1
“Participant”) 1
“Patent 1
“Source 1
“Your”) 1
“You” 2
“commercial 3
“control” 1

 

이런 결과가 나온다.

 

결과 파일을 보면,

# hadoop fs -ls /test_out
Found 2 items
-rw-r--r-- 2 root supergroup 0 2019-11-16 07:08 /test_out/_SUCCESS
-rw-r--r-- 2 root supergroup 22239 2019-11-16 07:08 /test_out/part-r-00000

 

리듀서에서 만든 결과 파일이 HDFS 클러스터에 잘 만들어져 있는걸 확인할 수 있다.

 

 

댓글
  • 프로필사진 개발자 안녕하세요. 도커와 하둡 클러스터링 관련해서 자료를 찾아 보다가 오게됐습니다. 정말 알기쉽게 설명해 놓으셨네요. 덕분에 많은 도움이 되었습니다. 감사합니다. 자주 들르겠습니다. 2020.02.06 09:45
댓글쓰기 폼
공지사항
최근에 달린 댓글
Total
1,455
Today
0
Yesterday
21
링크
«   2020/02   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
글 보관함