본문 바로가기

Docker & Hadoop

Docker로 Hadoop 클러스터 구축 (기본 구성)

Hadoop base 이미지 생성

기본 centos 이미지 위에서 hadoop 클러스터 구축을 위한 이미지를 만들어보자

centos 컨테이너 생성 및 접속

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

필요 디렉토리 생성

$ mkdir -p /home/hadoop     하둡 홈 디렉토리
$ mkdir -p /home/hadoop/tmp        하둡 환경에서 발생하는 로그 등의 파일 저장

필요 패키지 설치

$ yum install -y net-tools
$ yum install -y vim-enhanced
$ yum install -y wget
$ yum install -y openssh-server openssh-clients openssh-askpass
$ yum update -y

JAVA 설치 및 환경변수 설정

  • java 설치
$ yum install java-1.8.0-openjdk-devel.x86_64 -y
  • java 위치 확인
$ which java
/usr/bin/java
  • java 실제경로 확인
$ readlink -f /usr/bin/java
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.362.b08-1.el7_9.x86_64/jre/bin/java
  • java 링크 생성
$ ln -s /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.362.b08-1.el7_9.x86_64 /usr/lib/jvm/current
  • 자바 환경변수 정의
$ vim ~/.bashrc

...
export JAVA_HOME=/usr/lib/jvm/current
export PATH=$PATH:$JAVA_HOME/bin

Hadoop 설치 및 환경변수 설정

  • 하둡 설치 및 심볼릭 링크 설정
$ cd /home/hadoop
$ wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.4/hadoop-3.3.4.tar.gz
$ tar xvzf hadoop-3.3.4.tar.gz
$ ln -s /home/hadoop/hadoop-3.3.4 /home/hadoop/current
  • 하둡 환경변수 설정
$ vim ~/.bashrc

...
export HADOOP_HOME=/home/hadoop/current
export HADOOP_CONFIG_HOME=/home/hadoop/current/etc/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

sshd 설정

  • sshd 실행을 위해 필요한 key 생성
$ ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N ""
$ ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -t ecdsa -N ""
$ ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -t ed25519 -N ""
  • /etc/profile 에서 sshd 실행시키도록 작성
$ vim /etc/profile

...
/usr/sbin/sshd
  • /etc/profile의 내용들을 적용
$ source /etc/profile

ssh 통신을 위한 key 생성

$ ssh-keygen -t rsa -P ""
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

이후 ssh가 잘 작동하는지 확인하기 위해 다음의 코드를 입력해본다.

$ ssh localhost

언어변경

docker에 기본으로 설치된 언어는 영어이다. 이를 한글로 변경해 보자

$ locale -a
C
POSIX
en_US.utf8

yum.conf를 수정하여 한글을 설치하자.

$ vi /etc/yum.conf

#yum.conf 파일 내용중에
#override_install_langs=ko_KR (주석처리 한다. 주석처리시 전체 locale 설치)

#언어 관련 패키지를 재설치 한다.
$ yum -y -q reinstall glibc-common

#설치된 언어를 확인한다.
$ locale -a | grep ko_KR
ko_KR
ko_KR.euckr
ko_KR.utf8

$ vi /etc/profile
#파일의 제일 하단부에 다음과 같이 작성하고 저장한다.
...
export LANG=ko_KR.utf8

# 언어를 적용한다.
$ source /etc/profile

#적용된 언어를 확인한다.
$ locale
LANG=ko_KR.utf8
LC_CTYPE="ko_KR.utf8"
LC_NUMERIC="ko_KR.utf8"
LC_TIME="ko_KR.utf8"
LC_COLLATE="ko_KR.utf8"
LC_MONETARY="ko_KR.utf8"
LC_MESSAGES="ko_KR.utf8"
LC_PAPER="ko_KR.utf8"
LC_NAME="ko_KR.utf8"
LC_ADDRESS="ko_KR.utf8"
LC_TELEPHONE="ko_KR.utf8"
LC_MEASUREMENT="ko_KR.utf8"
LC_IDENTIFICATION="ko_KR.utf8"
LC_ALL=

timezone 변경

$ rm -rf /etc/localtime
$ ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime

다음으로는 하둡 설정을 해보겠다.

Hadoop 설정

하둡 설정 파일이 있는 디렉토리로 이동한다.

$ cd $HADOOP_CONFIG_HOME

 

  • hadoop-env.sh
$ vim hadoop-env.sh

...
export HADOOP_PID_DIR=/home/hadoop/current/pids
export JAVA_HOME=/usr/lib/jvm/current
export HDFS_NAMENODE_USER="root"
export HDFS_DATANODE_USER="root"
export HDFS_SECONDARYNAMENODE_USER="root"
export YARN_RESOURCEMANAGER_USER="root"
export YARN_NODEMANAGER_USER="root"
  • core-site.xml
$ vim core-site.xml

...
<configuration>
        <property>
                <name>fs.defaultFS</name>
                <value>hdfs://name01:9000</value>
        </property>
</configuration>
  • hdfs-site.xml
$ vim hdfs-site.xml

...
<configuration>
        <property>
                <name>dfs.replication</name>
                <value>3</value>
        </property>
        <property>
                <name>dfs.permissions</name>
                <value>false</value>
        </property>
        <property>
                <name>dfs.datanode.data.dir</name>
                <value>file:/home/hadoop/data/datanode</value>
        </property>
</configuration>
  • yarn-site.xml
$ vim yarn-site.xml

...
<configuration>
<!-- Site specific YARN configuration properties -->
        <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
        </property>
        <property>
                <name>yarn.resourcemanager.hostname</name>
                <value>name01</value>
        </property>
        <property>
                <name>yarn.nodemanager.resource.memory-mb</name>
                <value>2048</value>
        </property>
        <property>
                <name>yarn.nodemanager.resource.cpu-vcores</name>
                <value>1</value>
        </property>
        <property>
                <name>yarn.nodemanager.env-whitelist</name>
                <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
        </property>
</configuration>
  • mapred-site.xml
$ vim mapred-site.xml

...
<configuration>
        <property>
                <name>mapreduce.framework.name</name>
                <value>yarn</value>
        </property>
</configuration>

여기까지 hadoop base 이미지를 만들었다. 이미지를 commit 하여 저장한다.

$ docker commit hadoop-base woo-hadoop  # 로컬에 저장

$ docker commit hadoop-base dockerID/woo-hadoop  # Docker hub에 로그인된 ID에 저장

# docker에 로그인 하는 방법
$ docker login

클러스터 구성하기

우리는 master 노드 2개와 slave 노드 3개를 이용하여 총 5대를 클러스터로 구성할 것이다.

name01는 Namenode,

name02는 SecondaryNamenode,

이 외 data01~data03은 Datanode로 사용할 것이다.

$ docker run -it --privileged=True -h name01 --name name01 -p 9870:9870 woo-hadoop
$ docker run -it --privileged=True -h name02 --name name02 -p 9868:9868 woo-hadoop
$ docker run -it --privileged=True -h data01 --name data01 woo-hadoop
$ docker run -it --privileged=True -h data02 --name data02 woo-hadoop
$ docker run -it --privileged=True -h data03 --name data03 woo-hadoop

systemctl 명령을 사용할 수 있게 실행하기와 접속하기

$ docker run -it --privileged=True -v /sys/fs/cgroup:/sys/fs/cgroup:ro -h name01 --name name01 -p 9870:9870 woo-hadoop /usr/sbin/init

# 위와 같이 실행 후 해당 컨테이너에 접속하기 위해서는
$ docker exec -it 컨테이너ID /bin/bash   

# 컨테이너ID 는 docker 가 실행되지 않은 터미널에서 다음 명령으로 확인
$ docker ps -a

그리고 각 노드들에 대해서 도커 이미지를 저장하자

$ docker commit name01 hadoop-name01
$ docker commit name02 hadoop-name02
$ docker commit data01 hadoop-data01
$ docker commit data02 hadoop-data02
$ docker commit data03 hadoop-data03

모든 노드에서 수행

각 노드들에 대해서 /etc/profile을 실행시켜준다.

$ source /etc/profile

각 노드들의 IP 주소를 알아내야 한다.

$ docker inspect name01 | grep IPAddress
$ docker inspect name02 | grep IPAddress
$ docker inspect data01 | grep IPAddress
$ docker inspect data02 | grep IPAddress
$ docker inspect data03 | grep IPAddress

그리고 알아낸 IP주소를 이용하여 각 노드들의 /etc/hosts를 다음과 같이 수정해준다.

Docker의 실행 순서에 따라서 IP가 변경된다. 보통은 마지막 자리가 2부터 시작하며, 실행순서에 따라 순차적으로 부여된다. 172.17.0.1의 경우 Host 컴퓨터의 docker0 인터페이스 IP이다. 시험중에는 다른 실행중인 컨테이너가 있어서 5부터 부여되었다.

$ vim /etc/hosts

...
172.17.0.5	name01
172.17.0.6	name02
172.17.0.7	data01
172.17.0.8	data02
172.17.0.9	data03

마스터 노드에서 수행

먼저 $HADOOP_HOME/etc/hadoop 디렉토리로 이동하여 name01, name02 노드에서 다음을 수정해준다.

  • hdfs-site.xml
$ vim hdfs-site.xml

...
<configuration>
        <property>
                <name>dfs.replication</name>
                <value>3</value>
        </property>
        <property>
                <name>dfs.permissions</name>
                <value>false</value>
        </property>
        <property>
                <name>dfs.namenode.http.address</name>
                <value>name01:9870</value>
        </property>
        <property>
                <name>dfs.secondary.http.address</name>
                <value>name02:9868</value>
        </property>
        <property>
                <name>dfs.namenode.name.dir</name>
                <value>file:/home/hadoop/data/namenode</value>
        </property>
</configuration>

그리고 name01 노드에서 다음을 수정해준다. workers 파일은 worker가 수행할 노드를 적어 놓는 파일이다.

$ vim workers

data01
data02
data03

여기까지 설정을 마쳤으면 네임노드를 포맷한 후 하둡을 실행시켜보자.

$ hdfs namenode -format
$ start-all.sh

이렇게 실행이 완료되면 각 노드에서 jps를 한 결과는 다음과 같다.

[root@name01]$ jps
Namenode
ResourceManager

[root@name02]$ jps
SecondaryNamenode

[root@data01]$ jps
Nodemanager
Datanode

[root@data02]$ jps
Nodemanager
Datanode

[root@data03]$ jps
Nodemanager
Datanode

그리고 localhots:9870 으로 접속 시 GUI를 확인할 수 있다.

만약 name01 에 firewalld 가 실행되고 있다면, 접속되지 않으므로, firewalld 데몬을 down하거나, port를 열어줘야 한다.

도커 중지 후 재시작시 수행 순서

!! Docker 컨테이너 다운 또는 이미지 변경 후 다시 시작할 경우에 다음의 순서를 따라야 한다.

도커의 실행상태를 확인하여야 한다.

$> docker ps -a    # docker 실행중인 컨테이너 확인

만약 위의 명령에서 STATUS에 재시작 하려는 컨테이너가 있다면, 다음의 명령을 이용하여 컨테이너를 삭제한 후에 다음 순서를 진행한다.

$> docker rm 컨테이너ID

컨테이너를 삭제하지 않고, 실행하고 싶다면, 다음과 같이 docker start명령을 사용한다.

$> docker start hadoop-name01
$> docker start hadoop-name02
$> docker start hadoop-data01
$> docker start hadoop-data02
$> docker start hadoop-data03
  • name01, name02, data01, data02, data03 순서로 docker를 실행한다.
$> docker run -it --privileged=True -v /sys/fs/cgroup:/sys/fs/cgroup:ro -h name01 --name name01 -p 9870:9870 hadoop-name01 /usr/sbin/init
$> docker ps -a    # docker 실행중인 컨테이너 확인
$> docker exec -it 컨테이너ID /bin/bash  # name01의 컨테이너ID를 사용하여 name01에 접속
$> docker run -it --privileged=True -h name02 --name name02 -p 9868:9868 hadoop-name02
$> docker run -it --privileged=True -h data01 --name data01 hadoop-data01
$> docker run -it --privileged=True -h data02 --name data02 hadoop-data02
$> docker run -it --privileged=True -h data03 --name data03 hadoop-data03
  1. 전체 컨테이너의 /etc/hosts 파일의 내용을 수정한다.
$ vim /etc/hosts

...
172.17.0.5	name01
172.17.0.6	name02
172.17.0.7	data01
172.17.0.8	data02
172.17.0.9	data03
  1. name01을 제외하고 name02, data01, data02, data03 노드에서 /etc/profile을 실행한다.
$> source /etc/profile
  1. name01에서 start-all.sh를 실행한다.
name01> start-all.sh
  1. 각 컨테이너에서 jps 명령을 통해서 실행중인 프로세스를 확인한다.
$> jps

'Docker & Hadoop' 카테고리의 다른 글

도커(docker) entrypoint.sh 사용 방법  (0) 2023.02.15