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도 실행시키고, 뭐도 실행하고, 뭐도 실행하고 하고 싶은데로 다 할 수 있게 되었다.
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간의 통신이 가능하다는것이 중요 포인트다.
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
- Ubuntu image 없으면 public registry인 Docker hub로부터 ubuntu image를 pull 하여 local image registry로 들어온다. (Docker pull ubuntu)
- docker container create. Docker가 이미지를 바탕으로 새로운 container를 생성한다.
- Docker는 Container의 final layer로 read-write system을 할당해준다. 이로써 container가 local filesystem에 접근 가능해졌다.
- Docker가 container에게 network interface를 연결해준다. IP 주소 할당하는것도 포함된다. Default로 container는 host의 네트워크 시스템을 사용해서 외부 네트워크 연결이 가능하다.
- Docker가 container를 시작하도록 하고, /bin/bash를 실행시킨다.
- exit 명령어를 통해 /bin/bash 실행을 중단켜도 container가 멈출 뿐, 제거되지는 않는다.
Reference
[1] https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html