2019년 6월 19일 수요일

Ubuntu 18.04 + CUDA 9.2에서 nvidia-smi가 UNKNOWN ERROR를 보일 때 해결 방법


현재 최신 CUDA는 10.1이고, 10.0을 쓰기 시작한지도 꽤 되었습니다만, 여전히 Ubuntu 18.04 ppc64le 환경에서 CUDA 9.2를 설치해야 하는 경우가 있습니다.

NVIDIA 홈페이지에서 CUDA 9.2를 download 받아보면 이건 Ubuntu 16.04에서 지원된다고 되어 있습니다만, 실제로 설치해보면 Ubuntu 18.04에서도 문제없이 잘 설치됩니다.

그런데, 생각하지 않은 문제가 발생하는 경우가 있습니다.   정상적으로 CUDA 9.2가 설치되었고 nvidia-persistenced도 제대로 구동되고 있는데, 아래와 같이 nvidia-smi에서 UNKNOWN ERROR가 뜨는 것입니다.

$ nvidia-smi
Wed Jun 19 21:13:35 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.104      Driver Version: 410.104      CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  On   | 00000004:04:00.0 Off |                    0 |
| N/A   37C    P0    39W / 300W |        UNKNOWN ERROR |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla V100-SXM2...  On   | 00000004:05:00.0 Off |                    0 |
| N/A   39C    P0    39W / 300W |        UNKNOWN ERROR |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla V100-SXM2...  On   | 00000035:03:00.0 Off |                    0 |
| N/A   35C    P0    38W / 300W |        UNKNOWN ERROR |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla V100-SXM2...  On   | 00000035:04:00.0 Off |                    0 |
| N/A   40C    P0    38W / 300W |        UNKNOWN ERROR |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+


이건 Ubuntu 16.04 위의 CUDA 9.2에서 nvidia-persistenced를 구동하던 방법이 (이유는 잘 모르겠으나) Ubuntu 18.04 위의 CUDA 9.2에서는 제대로 작동하지 않기 때문입니다.  해결책은 다음과 같이 /lib/systemd/system/nvidia-persistenced.service에서 nvidia-persistenced의 시작 옵션을 바꾸어 주시면 됩니다.


$ sudo vi /lib/systemd/system/nvidia-persistenced.service
...
#ExecStart=/usr/bin/nvidia-persistenced --user root --no-persistence-mode --verbose
ExecStart=/usr/bin/nvidia-persistenced --verbose
...


이렇게 한 뒤 nvidia-persistenced를 restart 하고 다시 nvidia-smi를 해보시면 아래와 같이 잘 되는 것을 보실 수 있습니다.

$ nvidia-smi
Wed Jun 19 21:21:13 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.104      Driver Version: 410.104      CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  On   | 00000004:04:00.0 Off |                    0 |
| N/A   37C    P0    39W / 300W |      0MiB / 16128MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla V100-SXM2...  On   | 00000004:05:00.0 Off |                    0 |
| N/A   39C    P0    39W / 300W |      0MiB / 16128MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla V100-SXM2...  On   | 00000035:03:00.0 Off |                    0 |
| N/A   35C    P0    38W / 300W |      0MiB / 16128MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla V100-SXM2...  On   | 00000035:04:00.0 Off |                    0 |
| N/A   40C    P0    38W / 300W |      0MiB / 16128MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+





2019년 6월 14일 금요일

H2O Driverless AI의 NLP (자연어처리) demo


H2O Driverless AI의 최신 버전에서는 자연어처리(NLP, Natural Language Processing) 기능도 제공합니다.  Expert tab을 눌러 보면 tensorflow를 사용할 수 있게 되어있지요.  이번 posting에서는 H2O Driverless AI의 자연어처리를 이용한 예측 모델을 만들어보겠습니다.

먼저, dataset은 아래에서 제공하는 항공사 고객 만족도 data를 사용했습니다.  이 csv 표에는 여러가지 column이 난잡하게 들어가 있는데, 여기서는 airline_sentiment라는 column의 'positive'냐 'negative'냐라는 값을 예측해 보겠습니다.  이를 위해 사용되는 column은 딱 하나, text라는 column입니다.  이는 이 항공사를 사용한 고객이 올린 tweeter의 문장입니다.  나머지는 다 불필요한 column로서 출발일자, 출발지 등등의 data입니다.

Dataset은 다음과 같이 download 받을 수 있습니다.

root@63e8f0c0eac9:/home# wget https://www.figure-eight.com/wp-content/uploads/2016/03/Airline-Sentiment-2-w-AA.csv

이 dataset 중에서 10%를 test data로 떼어내겠습니다.  이를 위해서는 아래의 간단한 python code를 이용합니다.

root@63e8f0c0eac9:/home# vi split_sentiment.py
import numpy as np
import pandas as pd
from sklearn import model_selection
al = pd.read_csv("Airline-Sentiment-2-w-AA.csv", encoding='ISO-8859-1')
train_al, test_al = model_selection.train_test_split(al, test_size=0.1, random_state=2018)
train_al.to_csv("train_airline_sentiment.csv", index=False)
test_al.to_csv("test_airline_sentiment.csv", index=False)

이를 아래와 같이 수행하면 9대1로 나누어진 train 및 test csv 파일이 각각 생성됩니다.

root@63e8f0c0eac9:/home# python split_sentiment.py

root@63e8f0c0eac9:/home# ls -ltr *.csv
-rw-r--r-- 1 root root 3704908 Apr 26  2018 Airline-Sentiment-2-w-AA.csv
-rw-r--r-- 1 root root 3368890 Jun 14 02:43 train_airline_sentiment.csv
-rw-r--r-- 1 root root  376891 Jun 14 02:43 test_airline_sentiment.csv

root@63e8f0c0eac9:/home# wc -l *.csv
    232 Airline-Sentiment-2-w-AA.csv
   1486 test_airline_sentiment.csv
  13388 train_airline_sentiment.csv
  15106 total


이 중 train_airline_sentiment.csv의 구조를 살짝 보겠습니다.  Header 포함해서 딱 2줄만 보시지요.  여기서의 text는 @USAirways this is crazy. Haven't spoken to a human yet. There has to be a better way. http://t.co/mEOAlCIPdD 인데, 이런 tweet을 남긴 고객의 평가는 당연히 negative였습니다.

root@63e8f0c0eac9:/home# head -n 2 train_airline_sentiment.csv
_unit_id,_golden,_unit_state,_trusted_judgments,_last_judgment_at,airline_sentiment,airline_sentiment:confidence,negativereason,negativereason:confidence,airline,airline_sentiment_gold,name,negativereason_gold,retweet_count,text,tweet_coord,tweet_created,tweet_id,tweet_location,user_timezone
681462771,False,finalized,3,2/25/15 3:38,negative,1.0,Customer Service Issue,1.0,US Airways,,djxsv,,0,@USAirways this is crazy. Haven't spoken to a human yet. There has to be a better way. http://t.co/mEOAlCIPdD,,2/18/15 8:27,5.68084e+17,"Charlottesville, VA.",Eastern Time (US & Canada)


그에 비해 test_airline_sentiment.csv의 (header 제외하고) 첫줄을 보면, 이 고객이 남긴 tweet 문장은 @USAirways We did. @AmericanAir said to open one with you, too. 인데 평가는 negative였습니다.  이것만 보면 tweet 문장과 postive/negative의 관계가 이해는 가지 않는군요.

root@63e8f0c0eac9:/home# head -n 2 test_airline_sentiment.csv
_unit_id,_golden,_unit_state,_trusted_judgments,_last_judgment_at,airline_sentiment,airline_sentiment:confidence,negativereason,negativereason:confidence,airline,airline_sentiment_gold,name,negativereason_gold,retweet_count,text,tweet_coord,tweet_created,tweet_id,tweet_location,user_timezone
681461790,False,finalized,3,2/25/15 1:47,negative,1.0,Lost Luggage,1.0,US Airways,,LindsaySweeting,,0,"@USAirways We did. @AmericanAir said to open one with you, too.",,2/21/15 13:32,5.69248e+17,"Asheville, NC",Central Time (US & Canada)


아무튼 이 dataset을 H2O Driverless AI에 다음과 같이 올립니다. 



올리고나서 training dataset의 'Details' 항목을 보면 다음과 같이 각 column들의 구조와 맨 위의 20줄 값을 볼 수 있습니다.   아래 화면은 우리가 training의 대상으로 삼을 text column에 cursor를 올려 놓은 화면입니다.



이제 predict 메뉴를 이용해서 training에 들어갑니다.



예측하고자 하는 대상인 Target column은 당연히 'airline_sentiment' column을 택하면 됩니다.




그리고 이번에는 'text' column 외에는 모두 필요없으므로 상단의 'Drop columns...' 메뉴에서 'text' 이외의 모든 column을 선택합니다.




이번 training에서는 NLP를 위해 tensorflow를 사용하므로, Expert Tab에서 tensorflow를 ON 시켜줍니다. 




그리고 dial을 8(Accuracy)-5(Time)-8(Interpretation)에 놓고 'Launch Experiment' 버튼을 눌러 training을 시작합니다.



칼럼이 딱 하나, 'text' 뿐이므로 기본 feature는 1개 뿐이지만, training이 진행되면서 H2O DAI의 자랑인 auto feature engineering에 의해 feature 수는 점점 늘어납니다.  21% 진행시에는 76개 feature에 대해 2188개의 model을 train 중이고, 45% 진행시에는 247개 feature, 90% 진행시에는 818개 feature에 대해 train 중인 것을 보실 수 있습니다.





Training이 끝나면 다음과 같이 'Score on another dataset'을 눌러 아까 준비해둔 test dataset을 선택합니다.




Download prediction을 하면 이 dataset에 대한 'airline_sentiment' column의 예측치를 보실 수 있습니다.

쉽게 비교를 해보기 위해서는 'Diagnose Model on New Dataset' 메뉴를 사용하셔도 됩니다.  여기서도 아까 준비해둔 test dataset을 선택하면 되는데, 그러면 GINI, MCC 등 각종 scoring 기준에 따른 정확도가 평가되어 나올 뿐만 아니라 오른쪽 상단의 'Download predictions' 버튼을 누르면 예측치와 함께 test dataset 속의 실제값도 함께 나와 비교하기 좋습니다.






이 예측치는 negative, neutral, positive의 3개 값에 대한 classification이므로 각 값일 확률이 세개의 column에 나오고, 네번째 column에는 test dataset 속의 실제값이 제시되는 것입니다.   이대로는 한눈에 보기 어려우니, 간단한 excel 함수 IFS와 countif 등을 써서 아래와 같이 정리했습니다.



즉, 제대로 맟춘 것은 1464개 중 1160개로서, 적중률은 79% 입니다.  이 정도면 매우 훌륭합니다.

Accuracy-Time-Interpretability의 dial을 10-10-4로 높여보면 어떨까요 ?  일단 생성되는 feature들과 model들의 수가 확 늘어납니다.



그리고 당연히 그 정확도도 향상됩니다.  이번에는 83%까지 나오네요.  Dataset이 더 커지면 그 정확도도 더 늘어날 것으로 예상할 수 있습니다.




단, 이렇게 NLP를 사용한 예측 모델을 만들 때는 H2O DAI의 또다른 자랑거리인 XAI (혹은 MLI, 즉 eXplainable AI)는 제대로 사용하실 수가 없습니다.   'Interpret this model'을 눌러보면 다음과 같은 error가 나오는데, 충분히 이해가 가는 일이지요.

Model interpretation failed.
Traceback (most recent call last):
  File "/root/dai-1.6.2-linux-ppc64le/python/lib/python3.6/site-packages/h2oai/procedures.py", line 3297, in do_mli_api
    dt_tree_depth, config_overrides, logger=logger, id_columns=id_columns)
  File "h2oaicore/mli.py", line 807, in h2oaicore.mli.do_mli
  File "h2oaicore/mli.py", line 1485, in h2oaicore.mli.input_check
h2oaicore.systemutils.InvalidDataError: All input columns are of type string and have cardinality > max allowed(25), which is currently not useful for MLI



2019년 5월 22일 수요일

ppc64le 환경에서 IBM Cloud private (ICP) 설치하기


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개 이상 할당하는 메뉴도 있습니다.