4학년 1학기 캡스톤디자인 수업으로 딥러닝 관련 과제를 수행하게 되었습니다. 올해 초에 딥러닝 튜토리얼을 실행해보기 위해 개발환경을 구축해두었다가, 이후 프로젝트에서 쓰는 라이브러리와 충돌이 자꾸 생겨 '에라 모르겠다' 하고 다 지워버렸는데, 다시 설치할 생각을 하니 막막했습니다.

이번 학기에 [데이터센터 프로그래밍] 이라는 수업을 통해 Docker를 배우고 있는데, 도커를 통해 '개발환경을 더 쉽고 빠르게 구축할 수 있지 않을까?' 하고 구글링 해보니 많은 자료들이 있었습니다. 좋은 자료들을 참고해서 개발환경을 구축하고 그 과정을 글로 다시 한 번 정리했습니다. 팀원들과 미래의 저에게 도움이 되었으면 좋겠습니다.

Docker 초간단 소개 및 설치

도커는 컨테이너형 가상화를 통해, 하드웨어 레벨 가상화인 VM에 비해 보다 가볍게 가상화 기술을 제공합니다. 컨테이너에는 운영체제가 포함되지 않기 때문에, VM에 비해 초기 구동도 빠르고 용량도 작습니다.

도커를 사용하면 도커가 설치된 기기에서는 동일한 실행 환경을 만들 수 있기 때문에 개발환경을 만들거나 배포, 운영에 많은 장점을 가지고 있습니다.

도커 설치는 본인의 운영체제에 따라 방법이 다릅니다. 이 부분에 대해서는 여러 운영체제별로 친절하게 설명할 자신이 없어서, 이미 잘 정리되어있는 좋은 글을 링크하겠습니다.

이미지와 컨테이너

도커에는 이미지와 컨테이너라는 두 가지 중요한 개념이 있습니다. 이미지는 도커 컨테이너를 구성할 파일 시스템과 실행할 애플리케이션에 대한 설정을 합친 것입니다. 컨테이너는 도커 이미지를 기반으로 생성된 실행 상태를 말합니다.

  • 이미지 : 파일 시스템 + 실행할 애플리케이션에 대한 설정
  • 컨테이너 : 이미지를 기반으로 실행되는 상태

이미지로 여러 컨테이너를 생성할 수 있습니다. 이미지는 불변성을 가지고 있기 때문에, 컨테이너에서 무언가 설치하더라도 이미지에 변경사항이 저장되지 않습니다. 따라서 컨테이너가 종료되면 모든 변경 내용이 날아가고 파일도 사라집니다.

Tensorflow 개발환경 구축

이제 진짜로 개발환경을 구축해봅니다.

이미지 다운로드

제일 먼저 Tensorflow 개발 환경이 설정되어 있는 공식 이미지를 Docker Hub에서 다운받습니다.

$ docker pull tensorflow/tensorflow

태그를 지정해주지 않으면 기본으로 latest 태그가 붙은 이미지를 다운받습니다. 저는 python3, jupyter notebook을 사용할 것이기 때문에 해당 태그가 붙은 이미지를 다운받기 위해 아래 커맨드를 실행했습니다.

$ docker pull tensorflow/tensorflow:latest-py3-jupyter

이제 다운받은 이미지로 컨테이너를 실행해봅니다.

컨테이너 실행

사실 위의 이미지 다운로드 과정 없이 아래 커맨드를 실행했을 때, 로컬에 해당 이미지가 없으면 알아서 도커 허브에서 가져옵니다. 그냥 이미지 다운로드 명령어도 공유하고 싶었어요.

$ docker run tensorflow/tensorflow:latest-py3-jupyter
To access the notebook, open this file in a browser:
        file:///root/.local/share/jupyter/runtime/nbserver-1-open.html
    Or copy and paste one of these URLs:
        http://(8ad96c74d5fb or 127.0.0.1):8888/?token=3b0c5d2dcd1b633564b69d8f113e7e63265e095a52d8f047

야무지게 그려놓은 Tensorflow 글자와 함께, localhost의 8888 포트로 접근하라고 토큰값과 함께 알려줍니다. 그리고 브라우저를 켜서 8888 포트로 접속하면

omg

안됩니다. 역시 한번에 잘될리가..

포트 연결하기

이유는 열려있는 8888 포트는 컨테이너 내부의 포트입니다. 호스트(도커를 실행한 내 컴퓨터)의 8888 포트는 자기가 뭘 해야하는지 아직 아무것도 모릅니다. ctrl + c로 실행한 컨테이너를 종료하고 아래 커맨드로 다시 실행해봅니다.

$ docker run -p 8888:8888 tensorflow/tensorflow:latest-py3-jupyter

그리고 다시 브라우저에서 8888 포트로 접속하면 jupyter의 로그인 화면이 뜹니다.

login page

여기에 아까 실행화면에서 포트정보와 함께 보여줬던 토큰값을 입력하고 로그인하면 파일들을 확인할 수 있습니다.

1234번 포트를 쓰고싶다면 -p 1234:8888로 연결하면 됩니다.

호스트와 파일 공유

이제 여기에서 신나게 작업을 하다가 컨테이너를 종료하는 순간 망합니다. 컨테이너는 휘발성이기 때문이죠.

omg2

컨테이너가 종료되면 컨테이너의 파일시스템도 날아가기 때문에, 저장되어야 할 파일은 다른 곳에 두어야합니다. 호스트에 위치시켜야 해요.

도커는 데이터 볼륨을 통해 파일을 컨테이너가 아닌 호스트에 저장할 수 있게 해줍니다. 생성되는 파일을 볼륨에 저장하고, 볼륨의 데이터를 로드하기 때문에 호스트에서 컨테이너로 데이터를 쉽게 전달해 줄 수도 있습니다.

$ docker -v ${Home}/[HomeDir]:/[ContainerDir] [ImageName]

-v 옵션으로 호스트와 컨테이너의 디렉토리를 연결해 줄 수 있습니다. 저는 Home에 Tensorflow 라는 디렉토리를 만들어서 사용하기로 했습니다.

$ docker -p 8888:8888 -v ${Home}/Tensorflow:/tf tensorflow/tensorflow:latest-py3-jupyter

실행된 jupyter 노트북에서 로드하는 폴더가 tf였기 때문에 tf로 정해주었습니다. 이제 컨테이너를 종료해도 파일이 남아있고, 호스트에서 Tensorflow 폴더에 파일을 추가하면 컨테이너에서도 볼 수 있습니다.

새로운 패키지 설치

파일은 이렇게 공유했지만, 컨테이너가 휘발성이라면 우리가 추가한 패키지는 무사할까요? 당연히 사라집니다. commit 명령어를 통해 현재 컨테이너의 상태를 저장할 수 있습니다.

$ docker commit [container id] [image name]:[image tag]

실행중인 컨테이너의 터미널 접속하기

실행하고 있는 컨테이너의 폴더나 파일 등을 보거나 기타 자원 상태를 확인하기 위해서는 터미널 접속이 필요합니다. 도커에서는 exec 명령어를 통해 실행중인 컨테이너에 접근 할 수 있도록 해줍니다.

$ docker exec -it [container id] /bin/bash

/bin/bash를 통해 bash를 열고, 필요한 명령어를 실행할 수 있습니다.

글을 맺으며

이제 개발환경 구축이 끝났으니 본격적으로 프로젝트를 하러 가야겠습니다. 수업으로 배운 도커를 활용할 수 있어서 좋았고, 내 컴퓨터에 환경변수 설정, 버전문제, 프로젝트별 충돌 문제 등을 걱정하지 않고 편하게 작업한 다음 쉽게 삭제할 수 있어서 시간을 들이길 잘했다는 생각이 듭니다.