3.3. Networking

3.3.1. 사설 네트워크 구축

사설 네트워크를 구축하는 이유는 다음과 같다.

3.3.2. 관리노드 셋업

OS 설치가 끝났다면 모든 노드에서 작업할수 있는 일반 유저 계정을 하나 만들자. 실제 계정이름은 어떠한 것이든 상관없다.

[root@master root]# useradd -d /home/share micro
[root@master root]# passwd micro

클러스터 노드간 네트워크 세팅을 한다. 필자의 연구실 내부 네트웍은 사설망으로 이루어져 있다. 따라서 관리노드 의 IP 주소는 접속가능한 (내부 네트웍에서 관리노드로) ip 주소여야 한다. 여기서 주어지는 ip 주소는 필자의 환경에 맞게 세팅된 것 이며 실제로는 어떠한 값이 주어져도 상관없다.

[root@master root]# /sbin/ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:E0:81:20:07:84
inet addr:10.1.1.1  Bcast:10.1.1.255  Mask:255.255.255.0
eth0:0    Link encap:Ethernet  HWaddr 00:E0:81:20:07:85
inet addr:192.168.0.64 Bcast:192.168.0.255 Mask:255.255.255.0
eth1      Link encap:Ethernet  HWaddr 00:E0:81:20:07:85
inet addr:10.1.2.1  Bcast:10.1.2.255  Mask:255.255.255.0
	   

eth0 의 10.1.1.0~254 C class 사설 IP 대역은 노드간 NFS 를 위한 네트웍 인터페이스 이다. 모든 노드는 eh0 를 통해 NFS 서비스를 주고 받을 것이다. eth0:0 은 필자가 임의로 마스커레이딩을 통해 가상 IP 를 준것이며 내부 혹은 외부 사용자 네트웍 환경에서 접속할 IP 주소를 세팅한다. 모든 사용자 및 관리자는 관리노드의 eth0:0 의 네트웍 인터페이스 로 접속 할것이다. eth1 의 10.1.2.0 ~ 254 C class 사설 IP 대역은 계산작업 용 통신을 위한 네트웍 인터페이스 이다. 관리용, NFS 용 통신망과 논리적으로 분리를 시켜 독립적인 인터페이스를 사용하도록 한다. 한편 라우팅은 아래와 같이 설정해 주어야 한다. netconfg 명령이나 xwindow 상에서 netcfg 명령으로 설정할수 있다.

[root@master root]# /sbin/route 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.0.0     *              	255.255.255.0   U     0      0        0 eth0
10.1.1.0        *               255.255.255.0   U     0      0        0 eth0
10.1.2.0        *               255.255.255.0   U     0      0        0 eth1
127.0.0.0       *               255.0.0.0       U     0      0        0 lo
default         your.gateway   	0.0.0.0         UG    0      0        0 eth0
	   

/etc/hosts 파일을 편집 한다. 클러스터를 이루고 있는 각노드의 주소와 이름을 정 의 해준다. 이것은 관리노드와 모든 컴퓨팅 노드에 동일하게 설정해 준다.

[root@master root]# vi /etc/hosts
# 각 node 용 ip 대역
10.1.2.1        node00          master
10.1.2.2        node01
10.1.2.3        node02
10.1.2.4        node03
10.1.2.5        node04
10.1.2.6        node05
10.1.2.7        node06
127.0.0.1       localhost
# NFS 용 IP 대역
10.1.1.1	nfsserver
10.1.1.2	nfs01
10.1.1.3	nfs02
10.1.1.4	nfs03
10.1.1.5	nfs04
10.1.1.6	nfs05
10.1.1.7	nfs06
	   

공유디렉토리 를 설정 한다. 여기선 /home/share 를 공유디렉토리로 설정한다. 다음과 같이 /etc/exports 파일을 편집하자.

[root@master root]# cat /etc/exports
/home/share     *(rw)
	   

그리고 다음의 명령을 사용하여 nfs 서버를 다시 시작해주자.

[root@master root]# /etc/rc.d/init.d/nfs restart
	   

마스터 노드에 nfs 데몬이 제대로 떠있는지 확인해 보자. 아래와 비슷하게 나와야 한다.

[root@master root]# ps -auex | grep nfs
root      4633  0.0  0.0     0    0 ?        SW   May01   0:00 [nfsd]
root      4634  0.0  0.0     0    0 ?        SW   May01   0:00 [nfsd]
root      4635  0.0  0.0     0    0 ?        SW   May01   0:00 [nfsd]
root      4636  0.0  0.0     0    0 ?        SW   May01   0:00 [nfsd]
root      4637  0.0  0.0     0    0 ?        SW   May01   0:00 [nfsd]
root      4638  0.0  0.0     0    0 ?        SW   May01   0:00 [nfsd]
root      4639  0.0  0.0     0    0 ?        SW   May01   0:00 [nfsd]
root      4640  0.0  0.0     0    0 ?        SW   May01   0:00 [nfsd]
	   

nfs 데몬이 떠있지 않다면 nfs 는 RPC(Remote Procedure Call) 을 사용하기 때문에 포트매퍼 (Port mapper) 라는 데몬이 먼저 떠있어야 한다. 이를 확인해 보자.

[root@master root]# rpcinfo -p
program vers proto   port
100000    2   tcp    111  portmapper
100000    2   udp    111  portmapper
………
	   

이 데몬이 떠 있지 않다면 다음과 같은 명령을 사용하여 portmapper 를 먼저 띄우고 nfs 를 재시작 해보자.

[root@master root]# /etc/rc.d/init.d/portmap start
	   

위 두가지 모두 정상적으로 작동한다면 nfs 가 제대로 동작 할것이다. 그러나 그렇 지 않다면 nfs 가 커널에서 지원되지 않는 경우일수 있다. 이를 위해서는 커널 컴 파일을 해주어야 한다. 커널 컴파일시 nfs 관련 옵션들을 모두 커널에 포함 시켜 주어야 한다. 이것은 커널 컴파일에 익숙한 사용자 라면 별 어려움이 없겠지만 그 렇지 않은 사용자라면 KLDP homepage에서 "kernel compile" 이라는 검색어로 검색하면 많은 문서를 찾을수 있을것이다. 이를 참고하자. 커널 컴파일 옵션에서 FileSystem -> Network File Systems a NFS 관련된 옵션은 모두 선택을 하고 컴파일 을 한다. 커널 컴파일을 마쳤으면 커널과 모듈들을 적재하고 재부팅 한후 nfs 를 다시 시작 해 보자.

이상이 없으면 rsh 을 허가한다. 클러스터 내의 모든 노드들간에 rsh 이 가능하도 록 세팅해야 한다. 이것은 병렬 라이브러리 의 하나인 MPI (Message Passing Interface) 가 정상작동하기 위해 필요하다. rsh 관련 세팅은 관리 노드와 컴퓨팅 노드에 동일하게 설정해 줘야만 한다. /etc/xinetd.d 디렉토리 에서 rsh , rlogin, rexec 등의 파일을 편집한다.

[root@master root]# vi /etc/xinetd.d/rsh
service shell
	{
        disable = no
	socket_type = stream
	...
	  

위와 같이 disable 란을 no 로 바꿔주자. 해당 파일을 모두 수정했으면 xinetd 데 몬을 재시작 하면 적용이 된다.

[root@master root]# /etc/rc.d/init.d/xinetd restart
	  

이제 어떤 컴퓨터 들이 자신에게 rsh 이 가능하도록 허가할지를 정의해 줘야 한다. 관련 파일은 .rhosts 파일에 적용하는 법과 /etc/hosts.equiv 파일에 적용하는법 이 있는데 여기서는 /etc/hosts.equiv 에 적용하도록 하겠다.

[root@master root]# cat /etc/hosts.equiv
master node00
node01
node02
node03
node04
node05
node06
	  

/etc/hosts.equiv 파일이 없으면 만들고 위와 같이 호스트 네임을 적어주자. 다음은 root 유저가 rsh 을 이용하여 로그인 할수 있도록 /etc/securetty 파일을 수정해 주도록 한다.

[root@master root]# vi /etc/securetty
vc/1
vc/2
vc/3
……
tty1
tty2
……
rsh
rexec
rlogin
	  

위와 같이 마지막 라인에 rsh 관련 명령을 추가 시킨다. 다음으로 노드간 rsh , rlogin 시 패스워드 질의 절차를 생략하기 위해서 /etc/pam.d 디렉토리의 rsh, rlogin, rexec 파일을 수정해주자.

	  [root@master root]# vi /etc/pam.d/rsh
#%PAM-1.0
auth       sufficient   /lib/security/pam_nologin.so
auth       sufficient   /lib/security/pam_securetty.so
auth       sufficient     /lib/security/pam_env.so
auth       sufficient     /lib/security/pam_rhosts_auth.so
account    sufficient   /lib/security/pam_stack.so service=system-auth
session    sufficient   /lib/security/pam_stack.so service=system-auth
[root@master root]# vi /etc/pam.d/rlogin
#%PAM-1.0
# For root login to succeed here with pam_securetty, "rlogin" must be
# listed in /etc/securetty.
auth       sufficient   /lib/security/pam_nologin.so
auth       sufficient   /lib/security/pam_securetty.so
auth       sufficient     /lib/security/pam_env.so
auth       sufficient   /lib/security/pam_rhosts_auth.so
auth       sufficient   /lib/security/pam_stack.so service=system-auth
account    sufficient   /lib/security/pam_stack.so service=system-auth
password   sufficient   /lib/security/pam_stack.so service=system-auth
session    sufficient   /lib/security/pam_stack.so service=system-auth
[root@master root]# vi /etc/pam.d/rexec 
#%PAM-1.0
# For root login to succeed here with pam_securetty, "rexec" must be
# listed in /etc/securetty.
auth       sufficient   /lib/security/pam_nologin.so
auth       sufficient   /lib/security/pam_securetty.so
auth       sufficient     /lib/security/pam_env.so
auth       sufficient   /lib/security/pam_stack.so service=system-auth
account    sufficient   /lib/security/pam_stack.so service=system-auth
session    sufficient   /lib/security/pam_stack.so service=system-auth
	  

수정을 끝마쳤으면 xinetd 데몬을 재시작 한다.

	  [root@master root]# /etc/rc.d/init.d/xinetd restart
	  

3.3.3. 컴퓨팅노드 셋업

관리노드와 마찬가지로 리눅스를 설치하도록 하자 그리고 각 사용자는 모든 노드에 동일한 계정을 가지고 있어야 한다. 권장하는 방법은 관리노드의 /etc/passwd, /etc/passwd- 파일과 /etc/shadow, /etc/shadow- 파일들, /etc/group , /etc/group- 파일들을 모든 노드에 카피 하는 것이다. 이로써 관리노드에서 추가한 유저계정 들을 모든 노드에서 사용할수 있게 되었다. 다음은 네트워크 설정에 들어가보자. 전체적인 설정은 관리노드와 크게 다를바가 없다.

           [root@node01 root]# /sbin/ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:E0:81:20:07:84
inet addr:10.1.1.2 Bcast:10.1.1.255  Mask:255.255.255.0
eth1      Link encap:Ethernet  HWaddr 00:E0:81:20:07:85
inet addr:10.1.2.2  Bcast:10.1.2.255  Mask:255.255.255.0
           

eth0 의 10.1.1.0~254 C class 사설 IP 대역은 노드간 NFS 를 위한 네트웍 인터페이스 이다. 모든 노드는 eh0 를 통해 NFS 서비스를 주고 받을 것이다. eth1 의 10.1.2.0 ~ 254 C class 사설 IP 대역은 계산작업 용 통신을 위한 네트웍 인터페이스 이다. 관리용 과 NFS 용 통신망과 논리적으로 분리를 시켜 독립적인 인터페이스를 사용한다. 한편 라우팅은 아래와 같이 설정해 주어야 한다. 기본 게이트웨이 는 관리 노드가 된다. netconfg 명령이나 xwindow 상에서 netcfg 명령으로 설정할수 있다.

	   [micro@node01 share]$ /sbin/route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.1.1.0        *               255.255.255.0   U     0      0        0 eth0
10.1.2.0        *               255.255.255.0   U     0      0        0 eth1
127.0.0.0       *               255.0.0.0       U     0      0        0 lo
default         node00          0.0.0.0         UG    0      0        0 eth1
	   

etc/hosts 파일을 편집 한다. 클러스터를 이루고 있는 각노드의 주소와 이름을 정의 해준다. 이것은 관리노드와 모든 컴퓨팅 노드에 동일하게 설정해 준다.

[root@master root]# vi /etc/hosts
# 각 node 용 ip 대역
10.1.2.1        node00          master
10.1.2.2        node01
10.1.2.3        node02
10.1.2.4        node03
10.1.2.5        node04
10.1.2.6        node05
10.1.2.7        node06
127.0.0.1       localhost
# NFS 용 IP 대역
10.1.1.1		nfsserver
10.1.1.2		nfs01
10.1.1.3		nfs02
10.1.1.4		nfs03
10.1.1.5		nfs04
10.1.1.6		nfs05
10.1.1.7		nfs06
	   

공유디렉토리 를 설정 한다. 여기선 /home/share 를 공유디렉토리로 설정한다. 이미 관리노드 에서는 모든 node 가 관리노드 자신의 /home/share 를 마운트 하는것을 허락했다. 따라서 컴퓨팅 노드 에서는 관리노드의 /home/share 공간을 /etc/fstab 에 추가해 주도록 하자.

	   [root@node01 /]# vi /etc/fstab
…………
node00:/home/share      /home/share             nfs     bg,intr,noac    0 0
	   

관리노드 node00 의 /home/share 를 자신의 /home/share 로 마운트 하 는 명령이다. 파일시스템은 nfs 이고 nfs 마운팅 옵션은 bg, intr, noac 으 로 세팅 해준다. bg 는 만약 첫번째 NFS 마운트 시도가 타임아웃에 걸리면 백그라운드 에서 실행을 계속한다. noac 옵션은 반드시 설정해줘야 한다. MPI 라이브러리 (특히 MPICH) 에서 NFS V3 와 I/O 관련 충돌 문제가 리포팅 되었는데, 관련 버그를 막기 위해 noac 옵션이 필요하다. 이것은 NFS 의 속성 캐쉬를 해제하는 것으로 서버 효율을 떨어뜨리기는 하지만 두개의 다른 NFS 클라이언트로 하여금 서버상의 공통 파일 시스템에 쓰기 작업을 할때 좋은 효율을 얻을수 있게 해준다. 이제 /home/share 공유디렉토리 를 마운팅 해보자.

	   [root@node01 /]# mount -t nfs node00:/home/share /home/share
	   

이상없이 마운팅이 되었으면 rsh 셋업에 들어가도록 한다. rsh 세팅은 기 본적으로 관리노드와 다르지 않다. rsh 관련 셋업이 완료 되었으면 이제 각 호스트 간에는 rsh 명령이 가능해 질 것이다. 다음은 rsh 이 정상적으로 동작 하는지 확인해 보도록 한다. 관리 노드에서 컴퓨팅 노드로 rsh 이 되는지 확인해 보자.

	   [micro@master micro]$ rsh node01
Last login: ………
[micro@node01 micro]$
	   

컴퓨팅 노드에서 관리노드로 rsh 이 되는지 확인해 보자.

	   [micro@node01 micro]$ rsh master
Last login: ………
[micro@master micro]$
	   

3.3.4. 시간 동기화

클러스터 간 시간을 동기화 한다는건 매우 중요한 일이다. 어떠한 이유가 있더라도 클러스터간에 시간을 맞춰줘야 한다. 모든 시스템의 시각을 현재시각으로 맞춘다. 그 다음 그 시각을 CMOS 실시간 시간으로 "hwclock -w" 을 이용 변경한다. 시간동기화의 좋은 패키지중 하나는 수학자 출신인 D.J.Bernstein 이 만든 clockspeed 가 있다. 자세한 내용은 다음에서 확인할수 있다. http://cr.yp.to/clockspeed.html 혹은 http://kldp.org/~eunjea/clockspeed.php 위의 url 에서 clockspeed 소스를 다운로드 한다.

[root@master opt]# wget http://cr.yp.to/clockspeed/clockspeed-0.62.tar.gz
………………
[root@master opt]# tar xzf clockspeed-0.62.tar.gz
[root@master opt]# cd clockspeed-0.62
[root@master opt]# make
[root@master opt]# make setup check
	   

파일들은 /usr/local/clockspeed 에 설치된다. 실행파일들은 /usr/local/clockspeed/bin 에 설치되므로 사용자의 $PATH 에 추가해 주도록 한다. 다음은 실제 동기화 하는 과정이다. 먼저 ntp 서버와 클러스터서버 와의 시간 동기화를 한다. 여기서는 ntp 서버로 ntp.nasa.gov 를 이용했다.

[root@master /]# nslookup 
…………………
> ntp.nasa.gov
…………………
Non-authoritative answer:
ntp.nasa.gov    canonical name = ntp-nasa.arc.nasa.gov.
Name:   ntp-nasa.arc.nasa.gov
Address: 198.123.30.132   ß----- ntp 서버 주소
[root@master /]# sntpclock 198.123.30.132 | clockadd 
	   

이제 ntp 서버와 클러스터 와의 시간을 동기화 했다. 이제는 좀전에 ntp 서버와 동기화를 맞춘 master 서버와 나머지 클러스터들 간의 동기화 작업을 하도록 하자. 동기화의 기준이 되는 서버는 master 서버 이다. 기본적인 실행은 master 서버에서 taiclockd 서버 데몬을 실행시켜 주고 나머지 서버에서 taiclock 클라이언트 를 사용하여 동기화 를 시켜주는 방식이다.

[micro@master /]$ taiclockd &   ß--- master 서버 (root 권한으로 실행하지 않아도 됨)
[micro@node01 /]$ taiclock 10.1.2.1 > /tmp/adjust   ß--- 클라이언트 서버
[micro@node01 /]$ clockview < /tmp/adjust  ß-- 시간차 확인
before: 2003-05-06 10:50:05.824066000000000000
after:  2003-05-06 10:50:32.290600000000000000
	   

약 23초 정도 차이가 나고 있다. 시간을 맞춰주자.

[micro@node01 /]$ clockadd < /tmp/adjust 
[root@node01 /]# /sbin/hwclock -w 
	   

위의 과정을 클러스터 시스템 에서 정기적으로 실행하면 된다. 필자는 master 서버 에 다음과 같이 shell script 를 만들어 cron 을 사용하여 정기적으로 클러스터간 시간을 동기화 하고 있다.

[root@master bin]# vi /root/bin/sync_nodes_time.sh
#!/bin/sh

#
# First, correct time of this machine
#
/usr/local/clockspeed/bin/sntpclock 198.123.30.132 | \ 
/usr/local/clockspeed/bin/clockadd 
/sbin/hwclock -w 
#
# Next, sync time of each nodes
#

echo Start taiclockd ...
/usr/local/clockspeed/bin/taiclockd &

echo Correct time of node01
rsh node01 '/usr/local/clockspeed/bin/taiclock 10.1.3.1 > /tmp/adjust ; \
                /usr/local/clockspeed/bin/clockadd < /tmp/adjust; \
                /sbin/hwclock -w'
echo Correct time of node02
rsh node02 '/usr/local/clockspeed/bin/taiclock 10.1.3.1 > /tmp/adjust ; \
                /usr/local/clockspeed/bin/clockadd < /tmp/adjust; \
                /sbin/hwclock -w'
echo Correct time of node03
rsh node03 '/usr/local/clockspeed/bin/taiclock 10.1.3.1 > /tmp/adjust ; \
                /usr/local/clockspeed/bin/clockadd < /tmp/adjust; \
                /sbin/hwclock -w'
echo Correct time of node04
rsh node04 '/usr/local/clockspeed/bin/taiclock 10.1.3.1 > /tmp/adjust ; \
                /usr/local/clockspeed/bin/clockadd < /tmp/adjust; \
                /sbin/hwclock -w'
echo Correct time of node05
rsh node05 '/usr/local/clockspeed/bin/taiclock 10.1.3.1 > /tmp/adjust ; \
                /usr/local/clockspeed/bin/clockadd < /tmp/adjust; \
                /sbin/hwclock -w'
echo Correct time of node06
rsh node06 '/usr/local/clockspeed/bin/taiclock 10.1.3.1 > /tmp/adjust ; \
                /usr/local/clockspeed/bin/clockadd < /tmp/adjust; \
                /sbin/hwclock -w'
               
echo Stop taiclockd ...
killall taiclockd

echo done.
# end of file