음성인식 HMM 모델 훈련 등을 위해 간단한 클러스터를 제작한다.
편리한 관리를 위해 디스크를 노드마다 따로 두지 않고 PXE를 이용해 네트워크 부팅을 하도록 한다. 로컬 디스크는 작업용 저장소로 쓴다.
1 하드웨어 사양
- 주 노드
품명 수량 Pentium 4 2.4G 1 삼성 SDRAM 256M DDR 2 Gigabyte GA-8?IPE1000 pro 1 3Com 100M Lan card 1 HDD 다수 - 부 노드
품명 수량 가격 셀러론 노스우드 2.4G 5 525000 삼성 SDRAM 256M DDR 5 265000 인텔 ?D845GERG2L 5 745000 시게이트 40G(7200rpm) 5 390000 다오 ?CX3 케이스 5 175000 슬림케이스용 파워 200W 5 110000 합계 2155000 - 스위칭 허브 100M 8port 이상
2 지원 소프트웨어 스펙
- rsh, dsh
- MPICH
- Parallel HTK
- 자동 부팅, 재부팅, 정지 스크립트
3 제작 과정
관리상의 편의를 위해 diskless 클러스터로 세팅하고, 부 노드의 하드는 임시 데이터 저장소로만 사용하도록 구성하였다.
운영체제로는 주 노드와 부 노드 모두 리눅스 데비안 Sarge(testing) 배포본을 사용한다.
3.1 주 노드 설정
주 노드는 부 노드의 네트워크 부팅을 위해 DHCP를 지원해야 하고, tftp로 PXE 부팅 이미지와 리눅스 커널을 제공해야 한다. PXE 리눅스 부팅 이미지는 ?SYSLinux 프로젝트의 일환인 ?PXELinux로부터 얻을 수 있었다.
또한 부 노드들이 diskless 노드이기 때문에 부 노드의 루트 파일시스템이 마스터에 존재하며, 이를 nfs로 슬레이브가 부팅시 마운트한다.
또한 각 부 노드별로 /etc, /var, /tmp를 주 노드의 파일시스템에 가져야 하므로 이 역시 설정해야 한다. 이를 쉽게 하기 위해 데비안의 diskless 패키지를 이용하였다.
주 노드의 운영체제로 데비안 Sarge를 businesscard 설치 이미지 CD-ROM으로 설치한다.
다음으로 Beowulf 클러스터에 필요한 각종 패키지를 설치한다.
3.1.2.1 네트웍 설정
- /etc/hosts
127.0.0.1 localhost 143.248.139.4 cluster.gloine.co.kr gloine 192.168.1.1 magi 192.168.1.2 magi1 192.168.1.3 magi2 192.168.1.4 magi3 192.168.1.5 magi4 192.168.1.6 magi5
- /etc/network/interfaces
auto lo iface lo inet loopback auto eth1 iface eth1 inet static address 192.168.1.1 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 auto eth0 iface eth0 inet static address 143.248.139.4 netmask 255.255.255.0 network 143.248.139.0 broadcast 143.248.139.255 gateway 143.248.139.1
- /etc/hosts.allow
ALL:LOCAL 192.168.1. 143.248.139.
- /etc/hosts.deny
ALL:ALL
3.1.2.2 DHCP 설정
- DHCP는 2.0 버전을 사용하였다.
dpkg --install dhcp
- 각 부 노드에게 자동으로 IP를 분배할 수 있도록 한다.
- 또한 bootp 프로토콜을 지원한다.
- /etc/dhcpd.conf
allow booting; allow bootp; option domain-name "gloine.co.kr"; option domain-name-servers 143.248.1.177; option subnet-mask 255.255.255.0; default-lease-time 21600; max-lease-time 21600; subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.2 192.168.1.10; option broadcast-address 192.168.1.255; option routers 192.168.1.1; filename "/tftpboot/pxelinux.0"; # pxe 부팅을 위해 이미지를 전송한다. }
- DHCP 데몬을 시작한다.
/etc/init.d/dhcpd restart
3.1.2.3 ?PXELinux와 tftp 설정
- 랜카드가 온보드인 최신(2001년 이후) 메인보드들은 PXE(Preboot eXecution Environment)를 지원한다. 따라서 이를 이용하면 쉽게 네트워크 부팅을 수행할 수 있다.
- 리눅스에서 PXE는 syslinux 패키지에 딸려서 지원된다. 따라서 syslinux 데비안 패키지를 설치한다.
- 데비안의 경우 /usr/lib/syslinux/pxelinux.0 에 PXE 부팅 후 리눅스 커널을 로딩해주는 이미지가 들어 있다. 따라서 이를 DHCPD가 각 클라이언트에 전송해주면 이들은 이 이미지를 실행하여 다시 서버로부터 커널 이미지를 받을 수 있다.
- 이를 위해 우선 tftp 패키지를 설치한다. 데비안에서는 tftpd-hpa 패키지를 선택해야 한다. 기존의 tftpd의 경우 확장 명령을 지원하지 못해 동작하지 않는다.
- /etc/inetd.conf 의 다음 줄을 수정한다.
tftp dgram udp wait root /usr/sbin/in.tftpd /tftpboot
- 다음으로 /tftpboot 디렉토리를 만들고 이곳에 /usr/lib/syslinux/pxelinux.0 파일을 복사한다. 위의 DHCPD 설정에서 부 노드 부팅시 이 파일을 로딩하도록 이미 설정되어 있다.
- pxelinux.0 이미지는 자신이 있는 곳과 같은 디렉토리의 pxelinux.cfg/default 파일을 읽어서 로딩할 커널명과 그 인자를 결정한다. lilo와 같은 부팅 화면 역시 만들 수 있다.
- 이 때 여러 부 노드에 서로 다른 커널을 로딩하게 하고 싶으면 IP를 HEX 코드로 바꾼 파일을 pxelinux.cfg에 넣으면 된다. 특정 서브넷에 지정하는 것도 IP의 일부분만 HEX코드로 바꾼 이름의 파일을 넣음으로 해결할 수 있다. 부팅시 어떤 파일을 검색하는지가 화면에 표시되므로 이를 참조하면 편하게 파일명을 결정할 수 있다.
- /tftpboot/pxelinux.cfg/default
default nfs timeout 1 prompt 1 label nfs kernel vmlinuz-2.4.22 append root=/dev/nfs nfsroot=192.168.1.1:/var/lib/diskless/default/root/ ip=dhcp apm=on
- nfs 루트 지원과 DHCP로 IP 받기, 종료시 파워 오프를 위한 커널 인자들이 들어있다.
- 커널은 위 기능들을 지원하기 위해 다시 컴파일되어야 한다. 이는 다음에서 설명한다.
3.1.2.4 부 노드용 커널 컴파일
- NFS 파일 시스템을 루트로 마운트할 수 있고, 부팅시 DHCP로 IP를 자동으로 설정할 수 있으며, ACPI 모듈이 포함되어 자동 파워 오프 기능이 지원되어야 한다. 또한 편의를 위해 /dev 파일시스템을 메모리에 생성하는 기능을 사용한다.
- 우선 kernel-source-2.4.22 데비안 패키지를 설치한다.
- cd /usr/src/kernel-source-2.4.22
- make menuconfig
[*] Prompt for development and/or incomplete code/drivers [*] ACPI Support [*] IP: kernel level autoconfiguration [*] IP: DHCP support [*] IP: BOOTP support [*] Ethernet (10 or 100Mbit) <*> EtherExpressPro/100 support (eepro100, original Becker driver) <*> Kernel automounter version 4 support (also supports v3) [*] /dev file system support (EXPERIMENTAL) [*] Automatically mount at boot [ ] /dev/pts file system for Unix98 PTYs <*> NFS file system support [*] Provide NFSv3 client support [*] Root file system on NFS
- 다음을 수행한다.
make dep; make-kpkg clean; make-kpkg --revision=diskless.nfs.eepro.1.3 kernel_image
- 커널 이미지가 /usr/src/kernel-image-*.deb 라는 이름으로 생성된다.
3.1.2.5 부 노드용 파일시스템 생성
- 다음으로 해야 할 일은 부 노드가 마운트할 루트 파일시스템 구조를 만드는 일이다. 데비안은 이와 같은 일을 위하여 diskless라는 패키지를 지원한다. 이 패키지를 사용하면 주 노드의 /var/lib/diskless/default/root에 자동으로 루트 파일시스템 구조를 만들어 준다.
- diskless 데비안 패키지를 설치하고, diskless-image-simple 데비안 패키지는 그냥 받아오기만 한다.
- diskless 패키지 사용방법에 대한 자세한 문서는 /usr/share/doc/diskless/html/book1.html 에 있다.
- 이제 diskless-createbasetgz를 실행하여 데비안 기본 루트 파일시스템 구조를 생성한다. 이 스크립트는 debootstrap 명령을 이용하여 베이스 패키지를 받아온 후 이를 압축해 준다.
cd /tmp mkdir sarge diskless-createbasetgz /tmp/sarge sarge http://mirrors.kernel.org/debian /root/base.tgz
- 여기서 sarge는 아직 testing이라 debootstrap 스크립트에 의존성 버그가 있다. 다음을 수정한다.(man-db 패키지를 위해 libgdbm3을 추가로 설치한다.)
- /usr/lib/debootstrap/scripts/sarge
base="adduser apt apt-utils at base-config ................. man-db libgdbm3 ............ wget $additional"
- 다음으로 이 베이스 이미지와, nfs 부트를 위한 /sbin/init 스크립트등의 집합인 diskless-image-simple*.deb를 이용하여 최종 루트 파일시스템을 만든다. diskless-newimage 명령을 사용한다. 이 명령은 실행되는 디렉토리에서 base.tgz와 diskless-image-simple*.deb를 읽어서 지정한 경로에 루트 파일시스템을 생성한다. 옵션은 적당히 설정한다.
cd /root cp /var/cache/apt/archives/diskless-image-simple*.deb . diskless-newimage /var/lib/diskless/default/root
- 옵션 설정 참고 파일(설정 후 /var/lib/diskless/default/root/etc/diskless-image/config 에 생성)
master=magi nfsserver=192.168.1.1 nfsimagedir=/var/lib/diskless/default/root nfshostsdir=/var/lib/diskless/default nfshomedir=/home nameserver=210.94.0.7 domain=magi maildomain=gloine.co.kr mailroute=magi devfs=yes
- 다음으로 컴파일해 두었던 커널을 설치한다.
cd /usr/src dpkg --root /var/lib/diskless/default/root --install kernel-image-*.deb cp /var/lib/diskless/default/root/boot/vmlinuz-2.4.22 /tftpboot
- 새로 만들어진 루트 파일시스템의 /sbin/init은 nfs 파일시스템을 마운트하기 위해 스크립트로 짜여 있다. 마운트 테이블이 이상하다거나 할 경우 이곳을 편집해서 에러를 줄일 수 있다.
- sbin/init
mount -n none /proc -t proc #IP=`cat /proc/cmdline | sed 's/^.*nfsaddrs=\([0-9\.]\+\).*$/\1/'` IP=`ifconfig | grep -A1 eth0 | grep -v eth0 | sed 's/^.*inet addr:\([0-9\.]\+\).*$/\1/'` echo "Client IP address is $IP" # Mount client's /etc directory echo -n "Mounting NFS-root directories..." mount -n $nfsserver:/$nfshostsdir/$IP/etc /etc -orw,nolock # Update entries in /etc/mtab rm -f /etc/mtab~ /etc/nologin : > /etc/mtab mount -o remount / mount -o remount /etc mount -o remount /proc
- 이제 각 호스트별 /etc, /var, /tmp를 생성한다. 이는 diskless-newhost 명령으로 가능하다.
- /var/lib/diskless/default/root/usr/lib/diskless-image/template/etc/fstab을 미리 편집하여 각 노드에 생성될 fstab을 조정한다.
#/dev/hda1 - swap defaults 1 2 none /proc proc defaults 1 0 #image_nfsserver:image_nfsimagedir / nfs remount,rw,defaults,nolock 0 1 image_nfsserver:image_nfshostsdir/host_ip/etc /etc nfs remount,rw,defaults,nolock 0 1 ifelse(image_devfs,<[yes]>,<[dnl]>,<[ image_nfsserver:image_nfshostsdir/host_ip/dev /dev nfs rw,defaults,nolock 0 1]>) image_nfsserver:image_nfshostsdir/host_ip/var /var nfs rw,defaults,nolock 0 1 image_nfsserver:image_nfshostsdir/host_ip/tmp /tmp nfs rw,defaults,nolock 0 1 ifelse(image_nfshomedir,<[none]>,<[dnl]>,<[dnl image_nfsserver:image_nfshomedir /home nfs rw,defaults,nolock 0 2]>) ifelse(image_nfshomedir,<[none]>,<[dnl]>,<[dnl image_nfsserver:/db /db nfs ro,defaults,nolock 0 2 image_nfsserver:/db/0 /db/0 nfs ro,defaults,nolock 0 2 image_nfsserver:/db/1 /db/1 nfs ro,defaults,nolock 0 2 image_nfsserver:/db/2 /db/2 nfs ro,defaults,nolock 0 2 #image_nfsserver:/db/3 /db/3 nfs ro,defaults,nolock 0 2 image_nfsserver:/db/4 /db/4 nfs ro,defaults,nolock 0 2 image_nfsserver:/db/5 /db/5 nfs ro,defaults,nolock 0 2 image_nfsserver:/db/6 /db/6 nfs ro,defaults,nolock 0 2]>) image_nfsserver:image_nfsimagedir/var/lib/dpkg /var/lib/dpkg nfs ro,defaults,nolock 0 2 /dev/hda /data ext2 defaults 1 2
- /dev/hda와 /db/* 들은 필요에 따라 조절한다. 처음에는 /dev/hda는 초기화되어있지 않으므로 나중에 넣어야 한다.
diskless-newhost /var/lib/diskless/default/root 192.168.1.2 192.168.1.3 192.168.1.4 192.168.1.5 192.168.1.6 192.168.1.7
chroot /var/lib/diskless/default/root dselect
dpkg --purge lilo dpkg --purge pcmcia-cs dpkg --install devfsd dpkg --install nfs-common dpkg --install mpich-common dpkg --install mpich dpkg --install rsh-server dpkg --install rsh-client dpkg --install dhcp-client dpkg --install perl dpkg --install rdate dpkg --install sshd
3.1.2.6 NFS 설정
- 부 노드에서 주 노드의 하드를 액세스하기 위하여 NFS 서버를 주 노드에 설정한다.
- chroot 상태에서 exit한 후
dpkg --install nfs-common dpkg --install nfs-kernel-server
- /etc/exports
/var/lib/diskless/default/root 192.168.1.0/255.255.255.0(rw,sync,no_root_squash) /db 192.168.1.0/255.255.255.0(ro,sync,no_root_squash) /db/0 192.168.1.0/255.255.255.0(ro,sync,no_root_squash) /db/1 192.168.1.0/255.255.255.0(ro,sync,no_root_squash) /db/2 192.168.1.0/255.255.255.0(ro,sync,no_root_squash) #/db/3 192.168.1.0/255.255.255.0(ro,sync,no_root_squash) /db/4 192.168.1.0/255.255.255.0(ro,sync,no_root_squash) /db/5 192.168.1.0/255.255.255.0(ro,sync,no_root_squash) /db/6 192.168.1.0/255.255.255.0(ro,sync,no_root_squash) /home 192.168.1.0/255.255.255.0(rw,sync,no_root_squash) /var/lib/diskless/default/192.168.1.2 192.168.1.2(rw,sync,no_root_squash) /var/lib/diskless/default/192.168.1.3 192.168.1.3(rw,sync,no_root_squash) /var/lib/diskless/default/192.168.1.4 192.168.1.4(rw,sync,no_root_squash) /var/lib/diskless/default/192.168.1.5 192.168.1.5(rw,sync,no_root_squash) /var/lib/diskless/default/192.168.1.6 192.168.1.6(rw,sync,no_root_squash) /var/lib/diskless/default/192.168.1.7 192.168.1.7(rw,sync,no_root_squash) /var/lib/diskless/default/192.168.1.8 192.168.1.8(rw,sync,no_root_squash)
- /etc/init.d/nfs-kernel-server start 또는 reload
3.1.2.7 부 노드 부팅 테스트
- 이제 부 노드를 부팅할 준비가 완료되었다. DHCP, NFS, tftp가 정상동작하는지 확인한다.
- 부 노드들의 네트워크 연결을 확인하고 모두 부팅한다.
- 문제없이 부팅이 진행되어 로그인 화면이 떠야 한다.
3.1.2.8 rsh 설정
- 주 노드에도 rsh-client를 설치한다. 부 노드에는 rsh-server, rsh-client를 모두 설치한다.
- 마운트될 홈 디렉토리의 사용자별 홈 디렉토리에 .rhosts 파일을 만들고(유저만 읽기쓰기 권한을 가지도록), 주 노드의 풀 도메인 이름을 추가한다.
magi.gloine.co.kr
- /usr/bin/netkit-{rsh,rlogin} 에 setuid를 준다.
chmod 4755 netkit-r*
3.1.2.9 dsh 설정
- 주 노드에 dsh를 설치한다.
- /etc/dsh/machines.list
magi1 magi2 magi3 magi4 magi5
- /etc/dsh/dsh.conf
verbose = 0 remoteshell =rsh showmachinenames = 1 waitshell=1 # whether to wait for execution
- dsh -a w 를 실행시켜 클라이언트들이 응답하는지 확인한다.
3.1.2.10 부 노드 초기화
- 다음을 실행해서 /dev/hda를 초기화한다.
dsh -a "/sbin/mke2fs /dev/hda" mount 수행 chmod 777 /data
- /dev/hda를 /data로 마운트하도록 /etc/fstab 템플릿을 고치고 다시 diskless-newhost를 실행하여 설정을 갱신한다.
3.1.2.11 MPICH 설정
- 주 노드, 부 노드에 모두 mpich, mpich-common을 설치한다.
- /usr/share/doc/mpich/examples 에 실행 예제가 있다.
cd /usr/share/doc/mpich/examples make srtest mpirun -np 5 srtest
3.1.2.12 각종 관리 스크립트
- 모든 노드가 부팅되면 주 노드에서 arp를 실행한다.
magi5 ether 00:07:E9:F3:52:0E C eth1 magi4 ether 00:07:E9:F3:51:B9 C eth1 magi3 ether 00:07:E9:F3:51:A0 C eth1 magi2 ether 00:07:E9:F3:52:56 C eth1 magi1 ether 00:07:E9:F3:51:B0 C eth1
- 이를 토대로 wakeall.sh 를 만든다. etherwake 패키지가 설치되어 있어야 한다.
#!/bin/sh etherwake -i eth1 00:07:E9:F3:52:0E etherwake -i eth1 00:07:E9:F3:51:B9 etherwake -i eth1 00:07:E9:F3:51:A0 etherwake -i eth1 00:07:E9:F3:52:56 etherwake -i eth1 00:07:E9:F3:51:B0
- rebootall.sh
#!/bin/sh dsh -a "/sbin/reboot"
- syncall.sh
#!/bin/sh diskless-newhost /var/lib/diskless/default/root 192.168.1.2 192.168.1.3 192.168.1.4 192.168.1.5 192.168.1.6 192.168.1.7
- haltall.sh
#!/bin/sh /usr/bin/dsh -a /sbin/shutdown -h now
- 커널 2.4.22의 버그로 켜져 있는 컴퓨터에 etherwake를 수행하면 keventd가 CPU를 100% 먹는다. 조심할 것.
3.2 부 노드 설정
- diskless 이기 때문에 하드웨어 설정만 존재한다.
- 하드웨어 설정
- BIOS 설정에서 PXE enable, Wake on LAN enable, 첫번째 부팅 장치를 Network으로 설정
- 스위칭 허브에 랜선을 연결
4 설정 변경 방법
- /var/lib/diskless/default/root 내의 파일들을 수정하고 syncall.sh를 수행하면 변경된 설정이 모든 노드에 적용된다.
5 노드 추가 방법
- /etc/dhcpd.conf에서 IP range를 늘린다.
- /etc/hosts 파일에 이름을 추가한다.
- /var/lib/diskless/default/root/etc/hosts 파일에 이름 추가
- /etc/exports 파일 수정
- dhcpd, nfs-kernel-server 재시작
- HVite_Parallel.pl, HERest_Parallel.pl의 num_process 변수 고치기
- /etc/dsh/machine.list에 추가
CategoryLinux
다음검색