CS

Deep learning 개발자를 위한 Docker [1]

bono. 2021. 6. 18. 01:10

Docker

  • 모델을 개발할때도, 모델을 운영 할 때도 Docker는 그림자처럼 우리를 따라다닌다.
  • 누가 만든것만 잘 가져다 써보려 헀지만 뭔가 잘 안된다.
  • 화는 나는데 Docker를 하나하나 뜯어보기에는 뭔가... 싫고 귀찮다.
  • 하.... 어쩌지....🙃
  • 먼저 도커 공식문서의 설명을 본 후, 우리에게 필요한 개념들을 설명해볼까 한다.

 

Docker overview

  • Docker는 developing, shipping, and running applications을 위한 open platform이다.
  • Docker는 우리의 application을 구성한 infrastructure로 부터 분리시켜줘서 개발을 하는데 있어서의 생산성을 높여준다.
  • 정확히 말하자면 Docker는 컨테이너 기반의 오픈소스 가상화 플랫폼이다.

Contanier

  • Docker를 물어보면 자꾸 container라는것이 따라다닌다.
  • 컨테이너라는 것은 격리된 공간에서 프로세스가 동작하는 기술이다. [1]
  • 일단은 이정도로 알고 자세한것은 밑에 architecute에서 보자

기존 가상화 기술과의 차이

  • 이전 가상화 기술은 VM(virtual machine) 이라고 OS 자체를 가상화했다.
  • 아마 다들 윈도우에서 리눅스 계열의 OS를 VM에서 실행한 경험들이 있을 것이다.
    • 쉽게, 이미 존재하고 있던 OS를 Host, 추가로 설치한 OS를 Guest라 하자.
    • 윈도우(Host OS)라는 우리가 실행하고 있는 OS위에서 VM을 이용하여 새로운 리눅스(Guest OS) OS를 생성하여 실행하게 된다.
    • OS자체를 가상화해버리므로 윈도우 ← → 리눅스 간의 자원의 공유같은건 없다. 완전 새로운 OS를 하나 만들어 버리는것
    • 이를 하드웨어 스택의 가상화라고도 한다.
  • 추가적인 OS를 설치하는 방식(Guest OS의 설치)은 성능 이슈가 있기 때문에 다른 방식의 가상화 방법이 등장하게 된다.
  • OS가 아닌 프로세스를 격리하는 가상화 방식과 컨테이너가 등장하였다. 이를 OS 수준에서 가상화한다고 한다.
    • 컨테이너들은 OS kernel을 공유한다.
    • 즉, 컨테이너들은 Host OS의 자원을 사용 할 수 있다. 물론 Docker에서는 이를 제한 할 수 있다.
  • 이로써 하나의 서버에서 여러 컨테이너를 돌려 여러 독립적인 프로세스를 실행 시킬 수 있게 되었다.
    • 자원만 풍족하다면 서버 하나에서 Jupyter lab도 실행시키고, MLflow도 실행시키고, 뭐도 실행하고, 뭐도 실행하고 하고 싶은데로 다 할 수 있게 되었다.

그림 1. VM과 Container. https://images.contentstack.io/v3/assets/blt300387d93dabf50e/bltb6200bc085503718/5e1f209a63d1b6503160c6d5/containers-vs-virtual-machines.jpg

 

Docker architecture

  • Docker는 server-client architecture로 이루어져 있다.
  • 밑에 그림에서 Docker host가 서버 역할을 하고 있다.
  • Client는 우리가 터미널에서 docker build ~~, docker pull ~~ 과 같이 명령어를 입력하는것. 이 명령어들이 서버로 request를 보내는것이라 생각하면 된다.
  • 아키텍쳐를 보면 client는 docker daemon 이라는 친구와 먼저 통신을 하는 것을 볼 수 있다.
    • Daemon을 간단하게만 설명하자면 백그라운드에서 상주하며 사용자의 요청을 기다리고, 요청이 들어오면 그것을 수행하는 프로세스이다.
  • Docker daemon은 Container를 만들고, 실행하고, 배포하는 작업을 수행한다.
  • Cllient는 같은 system 내에 존재하는 daemon을 호출할수도 있고, 다른 시스템에 존재하는 remote daemon을 호출 할 수도 있다.
    • 이게 가능 한 이유는 clinet와 docker daemon은 REST API, UNIX socket, network interface로 통신하고 있기 때문이다.
    • 여튼 daemon과 client간의 통신이 가능하다는것이 중요 포인트다.

그림2. Docker architecture [2]

 

The Docker daemon

  • 위에서 daemon에 대해 간략하게 설명했다. 사실 그게 전부다.
    • Daemon을 간단하게만 설명하자면 백그라운드에서 상주하며 사용자의 요청을 기다리고, 요청이 들어오면 그것을 수행하는 프로세스이다.
  • Docker daemon은 background에서 clinet의 Docker API request를 기다리며 상주한다.
  • 또한 docker object들 (image, container, network, volume)을 관리한다.

The Docker client

  • Docker daemon과 통신하기 위해서는 docker clinet를 이용해야만 한다.
  • docker run 같은 명령어를 입력하면, client는 dockerd (docker daemon)에게 명령어를 전달한다.
  • docker clinet는 하나 이상의 docker daemon과 통신 할 수 있다.

Docker registries

  • Docker image를 저장하는 저장소다.
  • Docker를 사용하다보면 Docker Hub 에서 이미지를 다운 받을 텐데, Docker hub는 public registry이다. 그리고 default로 docker hub부터 뒤져봄
  • User만의 private한 registry도 구성 가능하다.

Docker objects

  • Images, contrainer, network , volumne
  • Docker로부터 생성되는 객체들...

Images

  • Docker contrainer를 만들기 위해서 사용되는 read-only template
  • 한 이미지가 다른 이미지를 기반으로 추가적인 설정을 더해 만들어지는 경우가 많다.
    • 예를들어 우분투 이미지를 기반으로 TF를 설치한다던지...
  • Image를 만들기 위해서는 먼저 Dockerfile을 생성해야한다.
    • 문법에 맞춰 단계 별로 (줄별로..?̊̈) 잘 작성하면 된다.
    • 각 단계는 image의 layer가 되어 쌓인다.
  • Dockerfile 내용을 바꿔 image를 rebuild 하면 바뀐 부분에 해당하는 layer만 바뀌어 빌드된다.

Containers

  • Image의 runnable instance이다.
  • Client를 통해 Docker api나 cli를 이용해 생성, 삭제, start, stop 가능
  • Container는 하나 이상의 네트워크와 연결이 가능하다.
  • 기본적으로는 container는 다른 container와 잘 격리되어 있는 상태인데, 어떻게 격리를 시킬지등의 방식을 제어 할 수는 있다.
  • Container는 만들때 줬던 구성 옵션들과 image에 의해 정의된다.
  • 컨테이너 지우면 영구저장소에 저장한거뺴고는 다 지워진다.

Example docker run command

  • 우리가 커멘드를 입력하면 어떻게 동작하는지 말하려 한다.
  • ubuntu image를 사용한다 가정
docker run -i -t ubuntu /bin/bash
  1. Ubuntu image 없으면 public registry인 Docker hub로부터 ubuntu image를 pull 하여 local image registry로 들어온다. (Docker pull ubuntu)
  2. docker container create. Docker가 이미지를 바탕으로 새로운 container를 생성한다.
  3. Docker는 Container의 final layer로 read-write system을 할당해준다. 이로써 container가 local filesystem에 접근 가능해졌다.
  4. Docker가 container에게 network interface를 연결해준다. IP 주소 할당하는것도 포함된다. Default로 container는 host의 네트워크 시스템을 사용해서 외부 네트워크 연결이 가능하다.
  5. Docker가 container를 시작하도록 하고, /bin/bash를 실행시킨다.
  6. exit 명령어를 통해 /bin/bash 실행을 중단켜도 container가 멈출 뿐, 제거되지는 않는다.

Reference

[1] https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html

[2] https://docs.docker.com/get-started/overview/