GPU 자원에 대해 private cloud를 구축하는 고객분들이 점점 늘어나고 있습니다. NVIDIA가 이제 virtual GPU를 CUDA에서도 지원하기는 합니다만, 주로 deep learning에 사용되는 GPU를 그렇게 virtual GPU로 나눠쓰는 것은 실질적인 이익이 별로 없습니다. 어차피 GPU 메모리가 부족한 상황이니까요. 그래서 GPU cloud를 구축할 때 사용되는 기술은 가상화보다는 docker orchestration이 대세를 이루고 있습니다.
IBM은 docker orchestration에 대해 IBM Cloud private (ICp)라는 솔루션을 제공합니다. 이는 Kubernetes 기반으로 만들어진 private cloud 솔루션이라고 할 수 있습니다. Redhat의 OpenShift와 비슷한 솔루션이라고 보시면 됩니다. 설치도 매우 간단하며, 당연히 IBM POWER9, 즉 ppc64le 아키텍처 버전도 있습니다.
이번 posting에서는 IBM의 POWER9 CPU와 NVIDIA V100 GPU를 장착한 AC922 서버에 ICp를 설치해보도록 하겠습니다.
먼저 docker와 nvidia-docker를 설치해야 하는 것은 당연하고요, 그 외에 다음과 같이 사전 작업을 몇가지 해줘야 합니다. 아래 내용은 이 link에 나온 manual을 따라 한 것입니다. 참조하십시요.
https://www.ibm.com/support/knowledgecenter/en/SSBS6K_2.1.0/installing/install_containers.html
먼저 /etc/hosts에 IP를 등록하거나 DNS에 등록된 IP를 준비합니다. 원래 최소 조건이 master node, proxy node, worker node1, worker node2가 필요합니다. Boot node는 master node와 같은 node에 있어도 괜찮습니다. 그러나 여기서는 GPU 서버인 AC922이 딱 1대 있기 때문에, 어쩔 수 없이 1대가 master node, worker node, proxy node 역할을 모두 하도록 했습니다. 그래서 /etc/hosts에 다음과 같이 IP address 하나에 4개의 이름을 주었습니다.
root@uniac922:~# cat /etc/hosts
127.0.0.1 localhost
192.168.0.20 uniac922 proxy master node1 node2
그리고 vm.max_map_count를 256K로 늘려줍니다. 이는 프로세스가 사용할 수 있는 메모리 맵 영역의 최대 수를 뜻합니다.
root@uniac922:~# sudo sysctl -w vm.max_map_count=262144
vm.max_map_count = 262144
위의 튜닝 효과가 reboot 이후에도 유효하게 하기 위해서는 아래와 같이 /etc/sysctl.conf에도 등록을 해줘야 합니다.
root@uniac922:~# sudo vi /etc/sysctl.conf
vm.max_map_count=262144
그리고 각 node들끼리 passwd 입력 없이 ssh가 되어야 합니다. 제 경우처럼 localhost 자체로 ssh하는 경우도 마찬가지입니다. 이는 아래와 같이 해주면 됩니다.
root@uniac922:~# ssh-keygen -t rsa
root@uniac922:~# vi /etc/ssh/sshd_config
#PermitRootLogin prohibit-password
PermitRootLogin yes
root@uniac922:~# ssh-copy-id master
root@uniac922:~# ssh-copy-id proxy
root@uniac922:~# ssh-copy-id node1
미리 download 받아둔 ICp 설치 파일을 다음과 같이 docker에 load 합니다.
root@uniac922:~# ls -l *.tar.gz
-rw-rw-r-- 1 root root 6163151506 May 14 23:46 ibm-cloud-private-ppc64le-2.1.0.1.tar.gz
root@uniac922:~# tar xf ibm-cloud-private-ppc64le-2.1.0.1.tar.gz -O | docker load
...
2d67d9d7b31b: Loading layer [==================================================>] 2.56kB/2.56kB
f64ed19c4c4c: Loading layer [==================================================>] 3.072kB/3.072kB
Loaded image: ibmcom/metering-reader-ppc64le:2.1.0.1
72e8e5a1b8a4: Loading layer [==================================================>] 5.229MB/5.229MB
45f2ce399ddb: Loading layer [==================================================>] 2.56kB/2.56kB
187003a06729: Loading layer [==================================================>] 3.584kB/3.584kB
8ab0cc971235: Loading layer [==================================================>] 98MB/98MB
Loaded image: ibmcom/icp-identity-manager-ppc64le:2.1.0.1
이를 성공적으로 하고 나면 다음과 같이 수십개의 docker image들이 load된 것을 보실 수 있습니다.
root@uniac922:~# sudo docker images | grep ibmcom
ibmcom/icp-inception-ppc64le 2.1.0.1-ee 526770d6fda6 17 months ago 332MB
ibmcom/icp-catalog-ui-ppc64le 2.1.0.1 eb2a8475a640 17 months ago 725MB
ibmcom/metering-reader-ppc64le 2.1.0.1 f73cd423f4c6 17 months ago 177MB
ibmcom/kubernetes-ppc64le v1.8.3-ee 96d8c62383ff 17 months ago 521MB
...
ibmcom/mariadb-ppc64le 10.1.16 e1d96397e3e8 2 years ago 451MB
ibmcom/pause-ppc64le 3.0 0e777c06d387 3 years ago 739kB
위의 이미지들은 기본 docker image 저장 장소인 /var/lib/docker에 대략 25GB 정도의 space를 차지합니다. 혹시 / 또는 /var 파일시스템에 그런 여유 공간이 없다면 시작 전에 아래와 같이 docker의 root directory를 여유가 많은 filesystem으로 바꿔두셔야 합니다.
[root@ac922 ~]# vi /lib/systemd/system/docker.service
...
#ExecStart=/usr/bin/dockerd
ExecStart=/usr/bin/dockerd -g /data/docker
이어서 ICp configuration 파일들이 저장될 installation directory을 만듭니다. 여기서는 /opt/ibm-cloud-private-2.1.0.1 로 하겠습니다.
root@uniac922:~# mkdir /opt/ibm-cloud-private-2.1.0.1
root@uniac922:~# cd /opt/ibm-cloud-private-2.1.0.1
여기서 ibmcom/icp-inception-ppc64le:2.1.0.1-ee 이미지 속에서 cluster라는 directory 전체를 이 directory로 다음과 같이 copy합니다.
root@uniac922:/opt/ibm-cloud-private-2.1.0.1# sudo docker run -v $(pwd):/data -e LICENSE=accept ibmcom/icp-inception-ppc64le:2.1.0.1-ee cp -r cluster /data
내용을 보면 다음과 같은 configuration file들이 보입니다.
root@uniac922:/opt/ibm-cloud-private-2.1.0.1# ls -l ./cluster
total 20
-rw-r--r-- 1 root root 4799 May 15 14:17 config.yaml
-rw-r--r-- 1 root root 88 May 15 14:17 hosts
drwxr-xr-x 3 root root 4096 May 15 14:17 misc
-r-------- 1 root root 1 May 15 14:17 ssh_key
이 중에서 먼저 hosts에 아래와 같이 IP address를 지정해주고 설정을 해줍니다. 여기서는 모든 서버들이 다 같은 IP를 가지는 비정상적 상태라는 거 잊지 마십시요.
root@uniac922:/opt/ibm-cloud-private-2.1.0.1# vi cluster/hosts
[master]
192.168.0.20 kubelet_extra_args='["--eviction-hard=memory.available<100Mi,nodefs.available<2Gi,nodefs.inodesFree<5%", "--image-gc-high-threshold=100%", "--image-gc-low-threshold=100%"]'
[worker]
192.168.0.20
192.168.0.20
[proxy]
192.168.0.20 kubelet_extra_args='["--eviction-hard=memory.available<100Mi,nodefs.available<2Gi,nodefs.inodesFree<5%", "--image-gc-high-threshold=100%", "--image-gc-low-threshold=100%"]'
#[management]
#4.4.4.4
그리고 다음과 같이 ssh_key를 copy 해줍니다.
root@uniac922:/opt/ibm-cloud-private-2.1.0.1# cp ~/.ssh/id_rsa ./cluster/ssh_key
cluster/images라는 directory를 만들고, 아까 받아둔 ICp 설치 file을 거기로 copy해둡니다.
root@uniac922:/opt/ibm-cloud-private-2.1.0.1# mkdir -p cluster/images
root@uniac922:/opt/ibm-cloud-private-2.1.0.1# cp /home/ibm/files/ICp/ibm-cloud-private-ppc64le-2.1.0.1.tar.gz cluster/images/
그리고 cluster/config.yaml 파일을 다음과 같이 일부 수정하여 /etc/hosts를 써도 error가 나지 않도록 해줍니다.
ibm@uniac922:/opt/ibm-cloud-private-2.1.0.1$ cd cluster
ibm@uniac922:/opt/ibm-cloud-private-2.1.0.1/cluster$ sudo vi config.yaml
# loopback_dns: false
loopback_dns: true
# 위의 수정을 해주지 않고 /etc/hosts에 의존할 경우 아래와 같은 error가 납니다.
TASK [check : Validating DNS server] ************************************************************************************************************
fatal: [192.168.0.20]: FAILED! => {"changed": false, "failed": true, "msg": "A loopback IP is used in your DNS server configuration. For more details, see https://ibm.biz/dns-fails."}
그리고 ICp version 3.x 부터는 아래처럼 config.yaml에서 ansible user의 password를 32글자 이상으로 설정해야 합니다.
[root@c633-met1 cluster]# vi config.yaml
...
## Advanced Settings
default_admin_user: admin
# default_admin_password:
default_admin_password: ibm08ibm08ibm08ibm08ibm08ibm08ibm
# ansible_user: <username>
안 그럴 경우 다음과 같은 이상한 error가 납니다.
fatal: [localhost]: FAILED! => changed=false msg: 'The password is not set. You must specify a password that meets the following criteria : ''^([a-zA-Z0-9\-]{32,})$''
이제 다음과 같이 ibmcom/icp-inception-ppc64le:2.1.0.1-ee image를 run 시켜 install 명령을 수행합니다.
ibm@uniac922:/opt/ibm-cloud-private-2.1.0.1/cluster$ sudo docker run --net=host -t -e LICENSE=accept -v $(pwd):/installer/cluster/ ibmcom/icp-inception-ppc64le:2.1.0.1-ee install
# 혹시 이 과정 중에서 도중에 실패가 일어난다든가 할 경우, 그대로 다시 install 하지 말고 install을 uninstall로 바꿔서 깨끗히 환경을 정리한 뒤 다시 해야 합니다. 그러지 않을 경우 다음과 같은 error를 만날 수 있습니다.
fatal: [192.168.0.20]: FAILED! => {"changed": false, "failed": true, "msg": "The environment was not clean, please first uninstall the ICP and then reinstall."}
다음과 같은 메시지가 나오면 성공적으로 종료된 것입니다. 시간이 생각보다 오래 걸립니다.
...
PLAY RECAP *********************************************************************
192.168.0.20 : ok=176 changed=54 unreachable=0 failed=0
localhost : ok=229 changed=113 unreachable=0 failed=0
POST DEPLOY MESSAGE ************************************************************
The Dashboard URL: https://192.168.0.20:8443, default username/password is admin/admin
Playbook run took 0 days, 1 hours, 30 minutes, 3619 seconds
그리고 혹시 이렇게 설치된 ICp를 재기동하고 싶으면 docker daemon을 다음과 같이 restart 하면 됩니다.
# sudo systemctl docker restart
이후는 https://192.168.0.20:8443 로 들어가서 web browser를 접속하여 둘러보면 됩니다. 이때 default userid/passwd는 admin/admin 입니다.
처음 나오는 메뉴는 dashboard 입니다. 여기서 CPU나 메모리는 물론, deploy된 pod들과 GPU의 상태도 모니터링 가능합니다.
Namespace 관련 메뉴는 화면 왼쪽 Navigation 중 Manage 메뉴에 있습니다. 여기서 새로운 namespace를 생성할 수도 있습니다.
ICp는 local server에 자체적인 local docker image repository를 가지고 있습니다. 여기에 image를 저장하기 위해서는 먼저 다음과 같이 local repository에 login을 해야 합니다. 여기에 사용되는 userid/passwd는 물론 admin/admin 입니다.
ibm@uniac922:~$ sudo docker login mycluster.icp:8500
Username: admin
Password:
Login Succeeded
이제 현재 load된 image 중에서 하나를 다른 이름으로 tagging한 뒤 local repository에 그 새 이름으로 tagging된 image를 push 해보겠습니다. 실은 이름을 mycluster.icp:8500/"namespace"/"image이름"의 형태로 tagging해야 push가 가능합니다. 따라서 다음과 같은 이름으로 tagging하겠습니다.
ibm@uniac922:~$ sudo docker tag ibmcom/kubernetes-ppc64le:v1.8.3-ee mycluster.icp:8500/admin/kubernetes-ppc64le:v1.8.3-ee
다음과 같이 새 이름으로 tag된 image를 확인할 수 있습니다. 이어서 push 하면 됩니다.
ibm@uniac922:~$ sudo docker images | grep kubernetes-ppc64le
ibmcom/kubernetes-ppc64le v1.8.3-ee 96d8c62383ff 17 months ago 521MB
mycluster.icp:8500/kube-system/kubernetes-ppc64le v1.8.3-ee 96d8c62383ff 17 months ago 521MB
ibm@uniac922:~$ sudo docker push mycluster.icp:8500/kube-system/kubernetes-ppc64le:v1.8.3-ee
이렇게 push된 image는 화면 왼쪽 Navigation 중 Catalog --> Images에서 확인하실 수 있습니다.
기타 화면들의 screenshot을 올려둡니다. 보시면 job을 생성하면서 거기에 GPU를 1개 이상 할당하는 메뉴도 있습니다.
댓글 없음:
댓글 쓰기