[DSM 7.0] Synology DSM Docker에서 Docker-in-Docker (dind) 실행하기

서론

Docker-in-Docker는 이미 존재하는 Docker Daemon에서 새로운 Container를 구동하고, 그 안에서 새로운 Daemon을 구동하는 기법이다.

기존에는 docker:dind 이미지와 --privileged 플래그를 이용하여 새로운 컨테이너를 생성하면 바로 가능한 간단한 문제였으나, Synology DSM 7.0에서는 기본 dockerstorage-driveraufs로 설정되어 있고 overlay2 드라이버를 지원하지 않으므로 이러한 기본적인 접근방식은 불가능하였다.

해결 방법

기존에는 아래와 같이 dind 컨테이너를 생성하였다.

docker run \
   --name jenkins-docker \
   --rm \
   --detach \
   --privileged \
   --network jenkins \
   --network-alias docker \
   --env DOCKER_TLS_CERTDIR=/certs \
   --volume jenkins-docker-certs:/certs/client \
   --volume jenkins-data:/var/jenkins_home \
   --publish 2376:2376 \
   docker:dind \
   --storage-driver overlay2

위 명령어는 jenkins 컨테이너를 위한 dind 컨테이너 생성 명령어(링크)다. 이 마지막 부분에 보면 --storage-driver 인자가 있는데, 이 부분만 aufs로 바꿔주면 바로 문제가 해결된다.

docker run \
   --name jenkins-docker \
   --rm \
   --detach \
   --privileged \
   --network jenkins \
   --network-alias docker \
   --env DOCKER_TLS_CERTDIR=/certs \
   --volume jenkins-docker-certs:/certs/client \
   --volume jenkins-data:/var/jenkins_home \
   --publish 2376:2376 \
   docker:dind \
   --storage-driver aufs

[해결됨] WSL2 CUDA undefined symbol: devicesetgpcclkvfoffset 문제 해결하기

[추가] 현재는 Fix된 이슈임

Windows 11 Insider Preview Build 22000.51이 나온 뒤에는 해결된 문제입니다. 아래 환경에서 테스트하였으니 apt 패키지와 드라이버를 업데이트 해보시기 바랍니다.

  • OS: Windows 11 Insider Preview Build 22000.51
  • Driver: NVIDIA 470.76
  • APT Package Version List
Inst libnvidia-container1 (1.4.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Inst libnvidia-container-tools (1.4.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Inst nvidia-container-toolkit (1.5.1-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Inst nvidia-container-runtime (3.5.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Inst nvidia-docker2 (2.6.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [all])
 Conf libnvidia-container1 (1.4.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Conf libnvidia-container-tools (1.4.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Conf nvidia-container-toolkit (1.5.1-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Conf nvidia-container-runtime (3.5.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [amd64])
 Conf nvidia-docker2 (2.6.0-1 NVIDIA CORPORATION [email protected]:1.0/bionic [all])

Environment: Windows 10 Insider Preview Build 21376.1
WSL2 Ubuntu release: 20.04
NVIDIA Forum Links: https://forums.developer.nvidia.com/t/nvidia-container-cli-error/177403/2?u=ji5489

문제 제기

if I run sudo nvidia-container-cli -k -d /dev/tty info

I got this error
where is ‘devicesetgpcclkvfoffset’ symbol?

– WARNING, the following logs are for debugging purposes only –
I0509 06:20:58.858216 1009 nvc.c:372] initializing library context (version=1.4.0, build=704a698b7a0ceec07a48e56c37365c741718c2df)
I0509 06:20:58.858281 1009 nvc.c:346] using root /
I0509 06:20:58.858287 1009 nvc.c:347] using ldcache /etc/ld.so.cache
I0509 06:20:58.858293 1009 nvc.c:348] using unprivileged user 65534:65534
I0509 06:20:58.858311 1009 nvc.c:389] attempting to load dxcore to see if we are running under Windows Subsystem for Linux (WSL)
I0509 06:20:58.891385 1009 dxcore.c:226] Creating a new WDDM Adapter for hAdapter:40000000 luid:1e946dc
I0509 06:20:58.917427 1009 dxcore.c:267] Adding new adapter via dxcore hAdapter:40000000 luid:1e946dc wddm version:3000
I0509 06:20:58.917515 1009 dxcore.c:325] dxcore layer initialized successfully
W0509 06:20:58.918854 1009 nvc.c:397] skipping kernel modules load on WSL
I0509 06:20:58.919404 1010 driver.c:101] starting driver service
E0509 06:20:58.950931 1010 driver.c:168] could not start driver service: load library failed: /usr/lib/wsl/drivers/nv_dispi.inf_amd64_43efafcd74b2efc9/libnvidia-ml.so.1: undefined symbol: devicesetgpcclkvfoffset
I0509 06:20:58.951399 1009 driver.c:203] driver service terminated successfully
nvidia-container-cli: initialization error: driver error: failed to process request

해결방법

I’m currently installing WSL2 Ubuntu 20.04 within Windows 10 Insider Preview Build 21376.1, and faced same issue like below.

# sudo nvidia-container-cli -k -d /dev/tty info

-- WARNING, the following logs are for debugging purposes only --

I0512 07:05:58.485519 5592 nvc.c:372] initializing library context (version=1.4.0, build=704a698b7a0ceec07a48e56c37365c741718c2df)
I0512 07:05:58.485581 5592 nvc.c:346] using root /
I0512 07:05:58.485601 5592 nvc.c:347] using ldcache /etc/ld.so.cache
I0512 07:05:58.485604 5592 nvc.c:348] using unprivileged user 65534:65534
I0512 07:05:58.485659 5592 nvc.c:389] attempting to load dxcore to see if we are running under Windows Subsystem for Linux (WSL)
I0512 07:05:58.502183 5592 dxcore.c:226] Creating a new WDDM Adapter for hAdapter:40000000 luid:185673b
I0512 07:05:58.512924 5592 dxcore.c:267] Adding new adapter via dxcore hAdapter:40000000 luid:185673b wddm version:3000
I0512 07:05:58.512956 5592 dxcore.c:325] dxcore layer initialized successfully
W0512 07:05:58.513266 5592 nvc.c:397] skipping kernel modules load on WSL
I0512 07:05:58.513404 5593 driver.c:101] starting driver service
E0512 07:05:58.521931 5593 driver.c:168] could not start driver service: load library failed: /usr/lib/wsl/drivers/nv_dispi.inf_amd64_43efafcd74b2efc9/libnvidia-ml.so.1: undefined symbol: devicesetgpcclkvfoffset
I0512 07:05:58.522047 5592 driver.c:203] driver service terminated successfully
nvidia-container-cli: initialization error: driver error: failed to process request

and I found out that apt-get experimental repository and stable one is mixed out – failing to install WSL2 one (which is available in experimental repository). as stable package is released, experimental(=WSL2) package should be released, but It wasn’t. see apt-cache madison result below.

# apt-cache madison libnvidia-container1
libnvidia-container1 |    1.4.0-1 | https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64  Packages
libnvidia-container1 |    1.3.3-1 | https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64  Packages
libnvidia-container1 | 1.3.3~rc.2-1 | https://nvidia.github.io/libnvidia-container/experimental/ubuntu18.04/amd64  Packages
libnvidia-container1 | 1.3.3~rc.1-1 | https://nvidia.github.io/libnvidia-container/experimental/ubuntu18.04/amd64  Packages
libnvidia-container1 |    1.3.2-1 | https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64  Packages
libnvidia-container1 |    1.3.1-1 | https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/amd64  Packages

The point is, we should install libnvidia-container1=1.3.3~rc.2-1 version rather than libnvidia-container1=1.4.0-1. but normal apt-get install nvidia-docker2 command would install 1.4.0-1 version, and It mostly like to fail in WSL2 environment.

I successfully installed older (WSL2-exclusive) packages via apt-get install command below:

apt-get install \
    libnvidia-container1=1.3.3~rc.2-1 \
    libnvidia-container-tools=1.3.3~rc.2-1 \
    nvidia-container-toolkit=1.4.1-1 \
    nvidia-container-runtime=3.4.1-1 \
    nvidia-docker2=2.5.0-1

Those commands will install older packages, and after sudo service docker stop and sudo service docker start, CUDA will work inside docker.

[튜토리얼] Docker로 apt-mirror 미러서버를 구축해보자

결과 확인해보기: https://mirror.limenas.ml

미러 서버는 , 데비안 계열 리눅스에서(Debian, Ubuntu),
시스템에 설치할 수 있는 deb 패키지들을 가지고 있는 서버이며,
이 서버에 빠르게 접근할 수 있도록 서버를 통째로 복제해둔 로컬 서버입니다.

Raspberry PiJetson Nano와 같은 SBC(Single Board Computer)를 사용하다 보면, 같은 Ubuntu/Debian 계열 Linux임에도 불구하고, CPU 아키텍쳐가 ARM이라는 이유로 카카오에서 제공하는 빠른 미러서버를 사용하기 어려워집니다.(이 미러서버에는 ARM 아키텍쳐의 바이너리들을 미러링을 하지 않습니다!) 저는 주로 한국에서 가장 빠른 mirror.kakao.com를 주 미러 서버로 사용하는데, 위의 문제 때문에 카카오 미러서버는 PC나 워크스테이션에만 한정하여 사용합니다.

사실 ports.ubuntu.com 라는 곳에서, 우분투 (반)공식으로 비-인텔 CPU(ARM, ARM64, MIPS 등등)에서 사용할 수 있는 패키지를 배포하긴 합니다. 다만, 서버는 영국에 있어서 경우에 따라서는 매우 느려서 속이 터집니다(한국인).

개인적으로, 라즈베리파이와 Jetson Nano를 모두 사용하고 있고, 연구 목적으로도 사용하고 있어서, 미러 서버를 구축하게 되었습니다.

1단계: apt-mirror-downloader Docker 이미지를 만들어보자

이 튜토리얼에서는 도커를 이용해서, 미러를 수행하는 Downloader를 실행합니다. 아래 Dockerfile을 이용해서 도커 이미지를 생성할 수 있습니다.

Dockerfile이라는 이름(확장자 없음)의 파일을 생성하여, 아래 내용을 저장합니다.

FROM ubuntu:latest

RUN sed -i "s|archive.ubuntu.com|mirror.kakao.com|g" /etc/apt/sources.list &&\
    apt -qq update && apt -y --no-install-recommends -qq install wget curl git make ca-certificates &&\
    rm -rf /var/lib/apt/lists

RUN git clone https://github.com/Stifler6996/apt-mirror.git && cd apt-mirror &&\
    make install && cd .. && rm -rf apt-mirror

ENTRYPOINT apt-mirror

위 파일을 저장한 뒤, 아래 명령어를 실행하여 이미지를 빌드합니다 (물론 이미지 이름이나 태그는 원하는 것으로 변경하면 됩니다).

Ubuntu에서 패키지로 배포하는 apt-mirror의 경우 c-n-f(Content-Not-Found)나 dep11(Dependency 관련)과 같은 특수 태그를 지원하지 않습니다. 이 튜토리얼에서는, 해당 최신 태그를 지원하도록 패치한 apt-mirror 버전인 Stifler6996/apt-mirror를 사용하여 진행합니다.

docker build . -t jungin500/apt-mirror:arm64

이미지를 만들었다면, 이제 미러링 설정 파일을 생성해줍니다. 어떤 사이트를 미러링할지, 쓰레드 수는 얼마나 줄 것인지 등을 설정하는 과정입니다. mirror.list라는 파일을 새로 만들어, 아래 내용을 저장합니다.

####### config
#
set base_path    /var/spool/apt-mirror
#
#set mirror_path  $base_path/mirror
#set skel_path    $base_path/skel
#set var_path     $base_path/var
#set cleanscript $var_path/clean.sh
#set defaultarch  
#set postmirror_script $var_path/postmirror.sh
#set run_postmirror 0
set nthreads     20
#set _tilde 0
#
####### end config

# Begin Raspberry Pi (Debian 10) ARM32/ARM64 configuration
deb [arch=armhf,arm64] http://archive.raspberrypi.org/debian buster main
# deb-src http://archive.raspbian.org/debian buster main
# End Raspberry Pi (Debian 10) ARM32/ARM64 configuration

위쪽 config 파트에서는 디렉토리나 thread수를 결정할 수 있습니다. 이 뒤부터는 보통 사용하는 sources.list와 동일합니다. 다만, 아키텍쳐를 [arch=armhf,arm64] 지시어로 지정합니다. 여기서는 armhf(32비트 ARM Hard Float)와 arm64(64비트 ARM) 두 가지 아키텍쳐에 해당하는 패키지만 다운로드한다는 의미입니다.

이런 식으로, 추가로 mirror.kakao.com나 ftp.kr.debian.org 등의 미러링이 가능합니다. 사용하고 있는 배포판에서 /etc/apt/sources.list를 뜯어서, 그 내용을 그대로 이 파일의 맨 아래에 넣어주면 됩니다. 다만, 아키텍쳐는 기본이 amd64로 지정되므로 위 내용 [arch=armhf,arm64]와 같이 explicit하게 지정해줘야 합니다!

다음으로는 두 번째 설정 파일입니다. 이 스크립트는 미러링이 끝난 뒤 ls-lR.gz 파일을 생성합니다. apt-get으로 패키지 메타데이터를 다운로드하게 되는데, ls-lR.gz는 이 때 필요한 파일입니다. 아래 스크립트를 postmirror.sh 라는 파일로 저장합니다.

#!/bin/bash
# ls-lR Creator Postscript for apt-mirror
# LimeOrangePie [email protected]

MIRROR_ROOT=/var/spool/apt-mirror
cd $MIRROR_ROOT/mirror

IFS=$'\n'
MIRRORS=( $(ls -1) )

for mirror_item in "${MIRRORS[@]}"
do
    cd $MIRROR_ROOT/mirror/$mirror_item
    DISTRIBUTIONS=( $(ls -1) )

    for dist_name in "${DISTRIBUTIONS[@]}"
    do
        cd $MIRROR_ROOT/mirror/$mirror_item/$dist_name
        rm -f ls-lR.gz
        ls -lR > ls-lR
        gzip ls-lR
    done
done

위 두 파일을 준비했다면, 다음으로, 만든 이미지를 이용해서 미러링을 수행합니다. 미러링을 할 디렉토리는 300GB 이상의 여유 공간이 있는 것이 좋습니다. 4개 서버를 미러링했더니 500GB정도가 나오네요. STORAGE_PATH를 변경하여 미러링할 대상 폴더를 지정해주세요.

DOCKER_WORKDIR=pwd
STORAGE_PATH=/mirror-storage
docker run \
         -it \
         --name apt-mirror-downloader \
         -v $DOCKER_WORKDIR/mirror.list:/etc/apt/mirror.list:ro \
         -v $DOCKER_WORKDIR/postmirror.sh:/var/spool/apt-mirror/var/postmirror.sh:ro \
         -v $STORAGE_PATH:/var/spool/apt-mirror:rw \
         --entrypoint apt-mirror \
         --rm \
         jungin500/apt-mirror:arm64

미러링은 3시간에서, 길면 반나절까지 걸립니다. 백그라운드로 돌리려면 docker 명령어에 -d 플래그를 붙여두고 기다리시면 됩니다.

다음 게시물에서는 만든 미러서버를 제공(Serve)하는 방법을 소개해 드리겠습니다. 지금까지 미러링한 서버를 실제로 다른 사람들이 쓸 수 있도록 간단한 웹 서버를 만들어서 배포합니다.

[Tutorial] Building lastest raspberry pi kernel for 64-bit Ubuntu (20.10)

One of the great parts about running Ubuntu is that just about all the Ubuntu-isms you’ve learned for other platforms work here too. Start with these links:

https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel
https://wiki.ubuntu.com/KernelTeam/ARMK … ossCompile
https://wiki.ubuntu.com/KernelTeam/Kern … k_failures
https://askubuntu.com/questions/500095/ … er-version
https://bugs.launchpad.net/ubuntu/+sour … ug/1701756

What follows isn’t very polished, since came out of my notebook verbatim. This is how I built the kernel.

First uncomment the relevant line int /etc/apt/sources.list:

deb-src http://ports.ubuntu.com/ubuntu-ports focal-updates main restricted

Update the package database:

apt update

Get the kernel source package, as root in some place where you want it. Alternatively replace $(uname -r) with the version you want. This is probably easiest to do on the target:

apt-get source linux-image-$(uname -r)

If this is on a target, copy it to a dev machine.

Over on the dev machine, hack up your kernel as you please. Then in debian.raspi/changelog, edit the first version number from something like this:

linux-raspi (5.4.0-1019.21) focal; urgency=medium

to something like this:

linux-raspi (5.4.0-1019.21+g34950~20200925) focal; urgency=medium

Note that CONFIG_LOCALVERSION will break the Ubuntu scripts, and EXTRAVERSION in the highest level makefile doesn’t do anything interesting.

Set some environment variables:

export $(dpkg-architecture -aarm64); export CROSS_COMPILE=aarch64-linux-gnu-

Now change into the root directory of the source tree and clean the build area:

fakeroot debian/rules clean

Kick off a menuconfig session with script:

fakeroot debian/rules editconfigs

menuconfig insists on running once each for 32 and 64 bit builds of kernel.

Now build the kernel and associated packages. We skip checks that are likely to break because of a changed list of modules:

fakeroot debian/rules binary skipmodule=true skipabi=true

This will result in the following .deb packages being created in the level ABOVE the kernel source tree:

linux-buildinfo-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
linux-headers-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
linux-image-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
linux-modules-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
linux-raspi-headers-5.4.0-1019_5.4.0-1019.21+g34950~20200925_arm64.deb

After copying to the target, each of the relevant packages may be installed there with dpkg:

dpkg -i linux-headers-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
dpkg -i linux-image-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
dpkg -i linux-modules-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
dpkg -i linux-raspi-headers-5.4.0-1019_5.4.0-1019.21+g34950~20200925_arm64.deb

[TEST] Tensorflow 2.4.0-rc0 on RTX 3000 series (3070/3080/3090)

Tensorflow on RTX 3000 series (RTX 3070, RTX 3080, RTX 3090)

빌드 환경 (Build environment)

OS: Windows 10 Education (Build 19042.608)
Architecture: x86_64 (amd64)
Git branch: v2.4.0-rc0
Python: 3.7 (anaconda)
Target CUDA and CUDNN: CUDA 11.1 Update 1, CUDNN v8.0.5 (Novemvber 9th, 2020) (requires login)
Target arch: CC 8.6, 6.1 → Must be also usable on GTX 1000 series!
Numpy: 1.19.4 (Must be manually reinstalled back to version 1.19.3 before using!)

사용법 (Usage)

  1. Requirements: CUDA 11.1 Update 1, CUDNN v8.0.5 (Novemvber 9th, 2020) (requires login)
  2. Download tensorflow-2.4.0rc0-cp37-cp37m-win_amd64.whl
  3. Install within CMD or Powershell cmdline (where pip3 is available)
  4. Install tensorflow : pip install tensorflow-2.4.0rc0-cp37-cp37m-win_amd64.whl
  5. (Optional) Install additional requirements
  6. (Required) Roll back numpy version to 1.19.3: pip install numpy==1.19.3
  7. (Maybe optional) cupti library filename mismatch – add “C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\extras\CUPTI\lib64” to PATH and copy “cupti64_2020.2.1.dll” to “cupti64.dll” or “cupti.dll”.

제한 사항 (Restriction, To-Dos)

  • Higher GPU usage might be restricted – use those code to resolve SOME of those problems:
# Memory Pre-configuration
config = tf.compat.v1.ConfigProto(
    gpu_options=tf.compat.v1.GPUOptions(
        per_process_gpu_memory_fraction=0.8,
        allow_growth = True
    )
    # device_count = {'GPU': 1}
)
session = tf.compat.v1.Session(config=config)
tf.compat.v1.keras.backend.set_session(session)
  • Closing application while tensorflow library loads always failes – might be a buggy codes?
  • another unknown restriction would exist – this is a test build for my own use, so use with care! I will edit this article when tensorflow officially supports RTX3000 series (or tested).

[튜토리얼] Oracle Cloud로 내 개인 서버를 열어보자

오늘은 Oracle Cloud를 이용해 평생 무료의(!!!) 개인 서버를 구축해보도록 하겠습니다.
앞 부분에는 간단한 배경 설명으로 채웠습니다. 실제 구축 과정은 여기(클릭)서 시작합니다.

Oracle Cloud란?

요즘 들어 클라우드 컴퓨팅이 대세인 것 같습니다. 인터넷 쇼핑으로 유명한 Amazon의 Amazon Web Service(링크), 세계 최대 검색 엔진 Google의 Google Cloud(링크), Microsoft사의 Azure까지, 가장 유명한 클라우드 서비스라고 하면 저는 이 3개가 먼저 생각납니다. 이 외에도, 중소규모의 클라우드 서비스들이 다양히 존재하고 또 새로이 우후죽순으로 생겨나는 클라우드 서비스들이 있습니다.

Java와 SQL로 유명한 Oracle 역시, 기존 기업을 대상으로 클라우드 서비스를 제공해주고 있었습니다. 그러던 중, 2019년 9월 Free Tier라는 이름으로 평생 무료 클라우드 서비스를 선보였습니다(링크). 기존 클라우드 서비스 업계에서 기간 무료(AWS – 12개월), 혹은 크레딧 제공(Azure, Google Cloud) 등의 이벤트성으로 클라우드를 무료로 사용해볼 수 있었지만, 이제는 무료로 사용할 수 있는 클라우드 서비스가 있다는 점에서 그 강점이 있습니다.

클라우드 리젼 및 가용성

현재 2020년 8월 기준으로, Oracle Cloud에는 한국 내 2개의 Region(서울, 춘천)이 존재합니다. 사실상 위에서 언급한 3대 클라우드사들은 모두 한국에 Region이 존재합니다. 다만 춘천이라는 생소한(!) 곳에 리젼이 존재하는 것은 처음 봐서 너무 신기했습니다.

사실 클라우드 리젼 그 자체보다는 1. 가격과 2. 네트워크 연결성, 그리고 3. 가용성이 가장 큰 선택의 요소가 될 것 같습니다. 저는 체감적으로는 Oracle사가 가격으로는 가장 저렴한 클라우드 서비스가 아닐까 하고 생각합니다. 실제로도 Oracle은 AWS와 비교하며 가격 경쟁력을 무기로 마케팅을 하고 있습니다.

다만 저는 Azure를 주 클라우드로 사용하고 있습니다. 주 신분이 학생이라, 학생 크레딧으로 체험 형식으로 사용중입니다. 개인적으로 테스트해본 결과 네트워크가 가장 빠른 클라우드가 Azure였네요.

1. Oracle Cloud 가입

본격적으로 Oracle Cloud를 사용해보도록 하겠습니다. 여기서는 가입보다는 클라우드 인터페이스 사용을 중점으로 언급하도록 하겠습니다. 가입은 여기(링크)서 “무료로 시작하기” 링크로 시작하실 수 있습니다.

2. 홈 리젼(Home Region) 설정

Oracle Cloud 내 Region을 의미하는 “인프라 지역”

Oracle Cloud를 가입할 당시, 홈 리젼을 선택하는 과정이 포함되어 있습니다. 이 과정에서 “South Korea Central (ap-seoul-1)”과 “South Korea North (ap-chuncheon-1)” 둘 중에서 선택할 수 있습니다 (한번 선택한 리젼은 바꾸기 어려우므로 신중하게 정하시는것이 좋습니다). 저는 춘천을 선택하도록 하겠습니다.

3. VM 인스턴스 생성

Oracle Cloud 첫 화면

Oracle Cloud의 첫 화면으로 이동합니다(좌측 상단의 Oracle Cloud 로고를 클릭하시면 됩니다). 위 빠른 작업 창에 “VM 인스턴스 생성”을 눌러 VM 생성을 시작합니다.

VM 인스턴스 생성 화면 – 이미지 선택 창

VM 인스턴스 생성을 위해 위 인스턴스 이름(ID)을 입력합니다. 저는 임의로 my-vm-instance라는 이름을 사용했습니다. 다음으로, 세번째 선택란에서 “이미지 변경”을 선택해 위 그림처럼 이미지 선택 창을 띄웁니다.

여기서 이미지란, 마치 PC를 새로 설치할 때 사용할 부팅 USB를 고르는 것과 동일한 작업입니다. 어떤 운영체제를 설치할지 고르는 과정으로, 저는 최신 Ubuntu 20.04를 선택하도록 하겠습니다. (선택한 후 반드시 맨 아래까지 페이지를 내려 “이미지 선택”을 눌러야 적용됩니다.)

SSH 개인 키(여기서는 전용 키) 다운로드 화면

마지막으로, SSH 키 추가 부분에서 전용 키 다운로드 버튼을 클릭해 SSH 개인 키를 다운로드합니다. 추후 이 키를 이용해 SSH 원격 접속이 가능하므로 반드시 이 키를 다운로드하고 진행해야 합니다!!

4. 인스턴스 접속

생성중인 VM 인스턴스

인스턴스가 다 만들어지면, 우측 기본 VNIC 아래, 전용 IP 주소가 생성됩니다. 이 주소가 곧 우리가 외부에서 SSH로 접속하는 주소입니다. 이 주소를 이용해 접속하도록 합니다. 그러나…

응? Windows 10에서 SSH로 접속이 안된다.

위 화면은, 다운로드 받은 개인 키를 이용해, Windows 10에서 WSL나 기본 SSH 클라이언트로 해당 IP에 접속할 때 발생하는 오류입니다. (해결 방법)

해결하고 접속을 완료한 화면

이제 이 VM에, 원하시는 어플리케이션을 설치하셔서 웹 서버 등을 운용할 수 있습니다.

참고자료

[1] Windows SSH: Permissions for ‘private-key’ are too open
[2] Oracle Cloud Infrastructure (OCI) : Create a Compute VM

WSL2 CUDA – WSL2에서 Ubuntu와 CUDA 사용하기

Windows Insider Preview 버전 문제 (2020-10-16 빌드에서 해결됨)

Windows 10 Insider Preview 버전에 따라서, WSL2나 CUDA가 아예 동작하지 않는 경우가 많습니다. 여기에서 버전별 작동여부를 확인 후에 설치하시는것이 좋을것 같네요.

WSL2에서 Ubuntu와 CUDA 사용하기

이제 Windows 10 Build 2020에서는 Windows Subsystem for Linux 2와 GPU 가속 지원 기능을 함께 사용할 수 있습니다. 이 가이드에서는 Windows 10 디바이스에서 WSL2와 Ubuntu를 이용하여 CUDA 개발 환경을 구축할 수 있도록 합니다.

이 튜토리얼에서는 WSL에 Docker를 구동하여, 결과적으로 Jupyter Notebook 내에서 CUDA를 End-to-End로 실행할 수 있도록 합니다. 구체적으로는 아래와 같은 구성으로 진행됩니다.

In the Linux guest, the dxgkrnl driver creates the /dev/dxg device for user mode components to access. The requests that come from GPU applications get forwarded to the Windows host system via VMBus where for those the host dxgkrnl driver makes calls to the KMD (Kernel Mode Driver) DDI handlers.
WSL2에서 dxgkrnl(자세히 보기)을 통한 NVIDIA GPU 지원

Windows 10 Insider Preview 채널로 변경하기

이 과정에 앞서, 설치된 Windows 10을 2020년 6월 17일자로 릴리즈된 Windows 10 Insider 빌드로 업그레이드해야 합니다. 이를 위해서 Windows Insider에 가입하여, 사용중인 기기를 Dev Channel에 등록할 수 있습니다(주로 “Fast Ring” 또는 한국어로 “초기”라고도 쓰입니다). 이 후, Windows 10 빌드 20150 버전으로 업그레이드할 수 있습니다.

Windows Insider 프로그램에 가입해서 프리뷰 버전으로 업데이트하기

Windows 10 Insider Preview 빌드 시작 페이지 또는 Windows 10 21H1 빌드 배포 노트(홍차의 꿈님 블로그)를 참조하여 개발자 빌드에 참여하는 방법을 확인하세요.

WSL2 활성화하기 – Step #1

먼저, WSL Version 1을 먼저 활성화합니다. 이 과정 이후, 추후에 WSL2로 업그레이드를 합니다.

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
WSL1 활성화 과정

필요시 재부팅을 해야할 수 있습니다. 보통의 경우 바로 이어서 WSL2를 활성화할 수 있습니다.

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

이 뒤, Windows를 재시작합니다.

Restart-Computer

WSL2 활성화하기 – Step #2

이제 재부팅을 완료하면, 시스템이 WSL2를 구동할 수 있는 상태입니다. 다만, 아직은 호환성 등을 이유로 기본값은 WSL Version 1입니다. 아래 코드로 기본 버전을 변경할 수 있습니다(원할 시 Distro마다, 기존 Version 1으로 다시 설치할 수 있습니다)

wsl.exe --set-default-version 2
WSL2를 기본값으로 설정하기

Ubuntu를 WSL에 설치하기

Microsoft Store으로부터 Ubuntu를 설치할 수 있습니다(링크).

Microsoft Store으로부터 WSL Ubuntu 다운로드

WSL에 Ubuntu를 다른 방식으로 설치할 수 있습니다(링크, 영문).

(옵션) Windows Terminal 설치하기

Windows Terminal은 MS사에서 개발한 대체 터미널 어플리케이션입니다. 기존 MobaXterm이나 Cygwin, ConEmu 등의 솔루션을 대체할 수 있는 Lightweight한 오픈소스 터미널 도구입니다(링크 또는 GitHub). 화면 렌더링의 GPU 가속 및 커스터마이징 등, 다양한 기능들을 가지고 있으며 기존 Windows의 콘솔(cmd, powershell)을 이어 더 나은 사용성을 제공합니다.

Microsoft Store으로부터 Windows Terminal 다운로드

WSL에서 Ubuntu 설치하기

Windows의 시작 메뉴에서 Ubuntu를 선택하고, 초기 실행이므로 WSL내의 Ubuntu 사용자를 설정합니다. 이 Ubuntu 사용자Windows 사용자는 독립입니다(서로 관계가 없으며 이름이 같아도 됩니다).

WSL 초기 실행 시 Linux 계정(사용자) 생성하기

이전 단계에서 Windows Terminal을 다운로드받았다면, 사용자를 생성했던 이전 콘솔을 닫고, + 아이콘을 눌러 새로운 Ubuntu 콘솔을 열 수 있습니다:

새로운 Ubuntu 콘솔 열기

이제, 설치가 완료되었으므로 Ubuntu가 WSL2에서 구동되는지 확인해봅니다:

uname -r
Ubuntu의 커널 버전 확인

커널 버전을 확인했을 때, 4.19.121보다 높아야 합니다.
※ 그렇지 않다면, 아래 명령어를 cmd 또는 powershell 터미널에서 실행해보세요:

wsl.exe --update

위 명령어를 실행한 뒤에도 동일한 커널 버전으로 나타난다면(WSL이나 Windows를 재시작해야할 수도 있습니다), Windows Updates 설정에서 “고급 옵션 > Windows를 업데이트할 때 다른 Microsoft 제품에 대한 업데이트 받기”가 켜져 있는지 확인합니다:

Windows Update “고급 옵션” 창
(변경할 설정확인이 쉽도록 한글로 써 두었습니다.)

이 뒤에, Windows Update를 다시 확인합니다.

Windows 업데이트 시 “Windows Subsystem for Linux Update” 표시

Windows 10용 NVIDIA 드라이버 설치

CUDA on WSL용 NVIDIA 그래픽 드라이버(WDDM 2.9) 다운로드(링크)

이 다음, 시스템에 설치된 GeForce 또는 Quadro 그래픽카드에 따라 적절한 드라이버를 다운로드합니다. 몇 달 내로 Windows Update를 통해 드라이버가 배포될 예정이지만, 그 때까지는 직접 설치하는 과정이 필요합니다.

드라이버를 얼리-엑세스로 다운로드하기 위해서는 NVIDIA Developer Program에 가입되어 있어야 합니다. NVIDIA 개발자 블로그(영문)에서 CUDA on WSL에 관련한 기술적 내용을 찾아볼 수 있습니다.

WSL에 Docker 설치

기본적으로 Canonical에서 제공하는 Docker를 설치할 수 있습니다(Docker Hub에서 제공하는 최신 Docker Engine을 설치하기 위해서는 아래 명령어 대신 이 링크의 튜토리얼을 따라하시면 됩니다. 영어입니다.)

sudo apt -y install docker.io
WSL2 Ubuntu에 Canonical 기본 레포지토리 Docker(docker.io 패키지) 설치

sudo 없이 docker 명령어를 이용하기 위해서는, 추가로 아래 명령어를 입력할 수 있습니다(보안상 이슈가 있을 수 있으며, 선택입니다):

sudo adduser $USER docker

NVIDIA Container Toolkit 설치

변수 distribution을 설정하고, NVIDIA 레포지토리 GPG 키를 가져온 뒤, NVIDIA 레포지토리를 Ubuntu의 apt 패키지 매니저에 추가합니다.

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -

curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

curl -s -L https://nvidia.github.io/libnvidia-container/experimental/$distribution/libnvidia-container-experimental.list | sudo tee /etc/apt/sources.list.d/libnvidia-container-experimental.list
Apt 패키지 매니저에 NVIDIA 레포지토리 추가

Ubuntu의 기본 레포지토리를 한국 서버로 변경합니다. apt updateapt upgrade 등의 작업이 훨씬 빨라집니다.

sudo sed -i "s/archive.ubuntu.com/mirror.kakao.com/g" /etc/apt/sources.list

Ubuntu의 apt 레포지토리를 초기화한 뒤, NVIDIA 런타임을 설치합니다.

sudo apt update && sudo apt install -y nvidia-docker2
apt 패키지 매니저를 통한 NVIDIA 컨테이너 런타임 설치 과정

설치 완료 시, 모든 Ubuntu 터미널을 종료하고, Powershell 터미널을 열어 모든 Ubuntu WSL 인스턴스를 종료합니다:

wsl.exe --shutdown Ubuntu
WSL Ubuntu 인스턴스 종료

GPU 컴퓨팅 테스트

새로운 Ubuntu 터미널을 열어, Docker 서비스를 시작합니다.

sudo service docker start

그리고 아래 명령어를 실행합니다:

sudo docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark

모든 과정이 이상없이 진행되었다면, 아래와 같이 GPU의 성능 정보들이 정상적으로 표시됩니다:

CUDA sample 코드 실행 결과

Tensorflow 컨테이너 시작하기

새로운 Ubutnu 터미널을 열어, 아래 명령어를 실행합니다:

docker run -u $(id -u):$(id -g) -it --gpus all -p 8888:8888 tensorflow/tensorflow:latest-gpu-py3-jupyter
Tensorflow 실행 가능한 Jupyter Notebook가 GPU와 함께 구동

또다른 새로운 Ubuntu 터미널을 열어, wslview를 입력 후, 그 뒤에 Jupyter Notebook URL을 입력합니다. 단, 여기서 127.0.0.1localhost로 바꿔 입력합니다!

wslview http://localhost:8888/?token=a83a1ad288a7bf1bd1deb694c8a7f19223c8d0baa7d5fb3c

기본 브라우저에 Jupyter Notebook이 실행되고, 이를 통해 GPU 가속이 가능한 Tensorflow 라이브러리를 사용할 수 있습니다! 이제 Tensorflow, CUDA를 WSL에서 사용할 수 있습니다.

Related blog posts

Additional resources

번역 원본

https://ubuntu.com/blog/getting-started-with-cuda-on-ubuntu-on-wsl-2