Docker 시작하기

스터디원들과 공유하기 위해 여러 문서와 책을 참고하여 작성한 도커 입문서. 나도 아직 잘 모르기 때문에 시간이 되는대로 조금씩 공부해볼 생각.

목차


Docker?

도커란, 리눅스 컨테이너에 여러 기능을 추가하여 컨테이너로 애플리케이션을 쉽게 사용할 수 있도록 만들어진 오픈소스 프로젝트. Go 언어로 작성되어 있으며, 2013년 3월 첫 번째 배포가 시작되었습니다.

http://kimstar.kr/7695/

도커 관련한 프로젝트는 Docker Compose, Docker Machine, Kitematic 등이 있지만 일반적으로 도커라고 하면, Docker Engine 또는 도커 관련 모든 프로젝트를 의미한다고 합니다. 도커의 프로젝트들이 도커 엔진을 더 효율적으로 사용하기 위한 프로젝트이므로 도커 = 도커 엔진이라고 해도 무방할 것 같습니다.


가상머신 vs 도커

left-VM right-Docker

가상머신

가상 머신은 Virtual Box, VM Ware 등이 대표적인데, 이런 가상 머신은 Host OS(운영체제) 위의 하이퍼바이저 위에서 독립적이고 완전한 운영체제(Guest OS)를 설치함으로써 Host OS와는 완전히 독립적인 공간과 시스템 자원을 할당받아 사용할 수 있습니다.

여기서 하이퍼바이저(Hypervisor) 란, 컴퓨터의 운영체제와 애플리케이션을 물리적 HW에서 분리하는 프로세스를 말한다고 합니다. 쉽게 말해 Host 컴퓨터 1대에서 다수의 운영체제를 동시에 실행할 수 있도록 하는 소프트웨어입니다.

따라서 가상 머신의 이미지는 Guest OS를 완전히 실행가능한 라이브러리, 커널 등을 전부 포함하게 되는데 이 때문에 이미지의 크기가 크다는 단점 이 있습니다.


도커

이에 반해 도커 컨테이너는 프로세스 단위의 격리환경을 만들기 때문에 성능 손실이 거의 없다 고 합니다.

또한 가상 머신처럼 독립적이면서 완전한 OS 구축을 위한 많은 자원을 필요로 하지 않고, Host OS의 컴퓨팅 리소스를 공유받기 때문에 이미지 용량이 작습니다. 따라서 이미지를 만들어 배포하는 시간이나 설치 시간이 가상 머신보다 빠르다는 장점이 있습니다.


⭐️도커의 장점!

도커의 장점을 요약해보면, 컨테이너를 이미지로 만들어 배포하는 시간이 가상머신을 통해 배포하는 것보다 빠르고 간편하며, 완전한 OS를 구축하는 것이 아닌 개발환경만을 구축할 수 있기에 팀 단위의 개발환경에서 사용이 용이하다는 장점이 있습니다. 또한 가상화 공간을 사용할 때 성능손실이 거의 없다는 것입니다.


도커의 단점?

굳이 찾자면 보안의 약점을 꼽을 수 있습니다. 하이퍼바이저로 구동되는 가상 머신의 경우, 컴퓨팅 리소스를 완벽히 독립하여 사용하기 때문에 게스트 OS중 하나가 취약해지더라도 나머지 Guest OS는 영향을 받지 않습니다. 그러나 도커를 사용할 경우에는 Host OS의 컴퓨팅 리소스를 도커 엔진을 통해 컨테이너들이 공유하기 때문에 Host OS가 취약해지면, 컨테이너들도 위험에 노출되게 됩니다.


가상 머신과 도커를 비교하면 다음 이미지와 같습니다..ㅎ


그래서 왜 도커?

개발을 하다보면 서로 다른 운영체제 버전, IDE버전, Java 버전 등 각기 다른 개발환경으로 인해 개발환경을 공유하거나 맞추는 일 또한 쉽지 않습니다. 도커는 컨테이너에 필요한 애플리케이션을 설치해서 개발에 필요한 환경을 구축하고, 이 컨테이너를 이미지로 만들어 공유할 수 있습니다. 여기서 이미지는 버전관리 측면에서 볼 때 Commit과 같은 작업으로 봐도 무방할 것 같습니다. 이미지와 컨테이너에 대한 설명은 아래에 추가했습니다.

그리고 이를 도커 헙(Docker Hub)을 통해 공유함으로써 마치 프로젝트를 Github에 올리거나 clone할 수 있는 일을 수행할 수 있습니다.

위의 내용을 정리하면서 이를 알기 쉽게 요약한 영상이 있어 공유합니다.


도커 엔진 종류

2017년 3월부터 도커 엔진은 Docker EE(Enterprise Edition)과 Docker CE(Community Edition)으로 배포되고 있습니다. Docke EE는 기업용 솔루션이며 각종 기술 지원 및 상용 서비스 개발에 필요한 다양한 부가기능을 도커 엔진과 함께 포함하고 있습니다. Docker CE는 무료로 제공되는 도커 엔진이며 별도의 기술지원 서비스를 지원하지는 않지만 도커 엔진의 핵심 기능을 무료로 사용할 수 있는 장점이 있습니다. Docker EE와 Docker CE 모두 3개월마다 stable 버전이 릴리즈 되며, Docker CE는 edge 버전이 한 달 단위로 릴리즈됩니다.


도커 설치

도커가 리눅스 컨테이너 기반 때문인지 도커의 기능을 완전하게 사용하기 위해서는 리눅스에서 사용하는 것이 가장 좋다고 합니다. 윈도우나 맥에서 사용하기 위해서는 각각의 운영체제에서 지원하는 가상화 기술을 통해 도커를 사용할 수 있습니다.

이외에도 AWS의 EC2 인스턴스를 사용해서 클라우드 환경(우분투)에서 도커를 구축할 수 있다고 합니다.


출처 : Introduction to Linux Containers

여기서 잠깐, 리눅스 컨테이너란 리눅스는 운영체제 레벨에서 가상화를 제공한다고 합니다. 그런데 운영체제를 통째로 가상화하는 방식이 아니라 리눅스 커널 레벨에서 제공하는 격리된 공간으로 가상화를 제공한다고 합니다. 운영체제를 설치하지 않았기 때문에 커널 레벨에서 제공하는 이 격리된 공간을 컨테이너라고 부르는 것입니다.

커널(Kernel)이란 컴퓨터의 가장 기본적인 각 장치들을 관리하고 제어하기 위한 소프트웨어라고 합니다. 컴퓨터가 부팅되면서 GRUB과 같은 부트로더에 의해서 메모리로 로딩되어 컴퓨터가 꺼질 때까지 항상 메모리에 상주해서 컴퓨터의 각 장치들을 관리하고 제어하는 역할을 합니다. (출처 : WEBDIR)

리눅스 컨테이너는 격리된 공간만 제공할뿐 서버 운영에 필요한 부가기능이 부족했는데, 도커는 리눅스 컨테이너를 기반으로 편리하게 이미지를 관리하고 배포할 수 있도록 도와주는 것입니다.


도커를 실행한 후 터미널에서 docker version을 입력하면 설치한 도커의 클라이언트/서버 버전을 확인할 수 있습니다.


도커 이미지 그리고 컨테이너 생성

도커 이미지는 컨테이너를 생성하고 실행하기 위해 필요한 요소입니다. MySQL에서 배포한 도커 이미지가 그 예입니다. 해당 이미지를 통해 컨테이너를 생성하면, MySQL를 사용할 수 있는 환경이 구축되는 것입니다. 도커 이미지 하나로 프로젝트에 따라 여러 개의 컨테이너를 생성하여 운영할 수도 있습니다.

1
$ docker search <image:tag>

도커를 실행한 상태에서 터미널에서 위의 명령어를 실행하면 이름에 해당하는 이미지를 찾아서 콘솔에 리스트를 출력합니다. 위의 명령어는 mysql이미지의 최신버전(tag)을 찾는 명령어입니다.

star가 많은 이미지일수록 신뢰가 높은 이미지라고 생각할 수 있습니다.

1
$ docker pull <image:tag>

설치하고 싶은 이미지를 찾았다면 내려받으면 됩니다.

1
$ docker images

내려받은 도커 이미지 리스트를 출력합니다.

1
$ docker rmi <image>

이미지를 삭제하고 싶을 때 사용합니다.

1
$ docker run -i -t --name <container_name>  -p 80:80 <image:tag>

내려받은 이미지를 통해 컨테이너를 생성, 실행합니다. 이 때 --name 키워드를 통해 컨테이너의 이름을 지정할 수 있습니다.

  • --name : 컨테이너의 이름을 지정합니다.
  • -i : interactive, 컨테이너의 입력 및 출력 등 상호작용하겠다는 키워드
  • -t : pseudo-tty로 터미널과 같은 환경을 사용하겠다는 키워드
  • -p : Host의 포트를 컨테이너의 포트로 오픈합니다. (listen)
    • -p <host-port>:<container-port>
    • Host의 포트를 지정하지 않으면 임의의 포트로 할당됩니다.

도커 컨테이너는 이미지와 독립적이므로 이미지를 통해 생성한 컨테이너 A, B, C가 있다고 가정해보도록 하겠습니다. 이 때, 컨테이너 A에서 변경사항이 발생해도 컨테이너 B와 C에서는 컨테이너 A에서의 변경사항이 적용되지 않습니다. 또한 Host OS에도 영향을 주지 않는다고 합니다.

데이터베이스와 웹 서버를 구축할 때 하나의 컨테이너에서 구축할 수도 있지만, 도커는 한 컨테이너에 프로세스 하나만 실행하도록 하는 것이 철학이라고 합니다. 각각의 프로세스 단위로 컨테이너로 구분하는 것이 도커의 방향인 것 같습니다.

혹시 컨테이너의 개념이 헷갈린다면 여기를 다시 읽어보시길 바랍니다!

현재 실행중인 컨테이너 목록을 출력합니다.

1
$ docker ps

생성된 모든 컨테이너 목록을 출력합니다.

1
$ docker ps -a

생성한 컨테이너를 시작하고, 종료하는 명령어입니다.

1
2
$ docker start <container_name>
$ docker stop <container_name>

컨테이너를 삭제합니다.

1
$ docker rm <container_name>

bash모드로 컨테이너 진입하기

1
$ docker exec -it <container_name> bash

컨테이너를 실행(docker start)한 뒤에 위의 명령어를 입력하면, bash shell 모드로 컨테이너 내부로 들어갈 수 있습니다. 이제 여기부터는 리눅스 쉘 명령어(bash)가 필요합니다.

여기서 -it여기서 정리한바 있습니다.

해당 컨테이너의 os 정보를 콘솔에 출력합니다.

1
/# cat /etc/issue

exit 를 입력면 컨테이너에서 빠져나올 수 있습니다.

컨테이너 내부에 들어가지 않고도 컨테이너 외부에서 컨테이너 내부로 명령어를 실행할 수도 있습니다.

1
$ docker exec <container_name> echo "Hello World!"

콘솔창에 Hello World가 출력됨을 확인할 수 있습니다.



참고 문서 및 도서