하나의 서버에 여러개의 프로그램을 설치하고 구동을 할 때 라이브러리의 버전이 다르거나 동일한 포트를 사용하는 경우 설치가 까다롭다. 따라서 그냥 물리적으로 서버를 나누는 것이 편한데 이러면 자원낭비가 심해진다. 또 한 서버 환경의 지속적인 변화와 DevOps, MSA로 인한 짧아진 배포 주기와 잘게 쪼개진 서버는 관리를 더 복잡하게 만들었다. 이때 도커가 등장해서 서버 관리 방식이 바뀌게 되었다.
도커는 컨테이너 기반의 오픈소스 가상화 플랫폼이다. 여기서 컨테이너란 다양한 프로그램, 실행환경을 컨테이너로 추상화 하고, 동일한 인터페이스를 제공해 프로그램의 배포와 관리를 단순하게 해주는 것이다. 그때문에 도커의 컨테이너로 추상화를 한다면 어느 환경(조립PC, AWS 등)에서도 실행할 수 있다.
컨테이너는 격리된 공간에서 프로세스가 동작하는 기술이다. 가상화의 한 종류이지만 VMWare같이 운영체제 자체를 가상화하는 방식과는 차이가 있다.
우선 VMware같이 호스트 OS위에 게스트 OS 전체를 가상화하여 사용하는 경우 너무 무겁고 느리기 때문에 운영 환경에서는 사용할 수 없다. 이런 문제점을 개선하기 위핸 CPU의 가상화 기술(HVM)을 이용한 KVM(kernel-based virtual machine)과 반가상화(Paravirtualization)방식의 Xen이 등장한다. 이런 기술들은 게스트 OS가 필요하긴 하지만 전체 OS를 가상화 하는 방식이 아니기 때문에 호스트형 가상화 방식 보다 성능이 좋다.
하지만 이 역시 성능에 문제가 존재 했고 이를 개선하기 위해 프로세스를 격리하는 방식이 등장 한다. 리눅스에서는 이를 리눅스 컨테이너라고 하고 단순히 프로세스를 격리시키는 방식이기 때문에 가볍고 빠르다.
* 도커의 기본 네트워크 모드는 Bridge모드로 약간에 성능 손실이 존재 한다. 네트워크 성능이 중요 하다면 --net-host옵션을 사용해야 한다.
하나의 서버에 여러개의 컨테이너를 실행 하면 서로 영향을 미치지 않는다. 또 한 실행중인 컨테이너에 접속해 명령어로 패키지를 설치할 수 있다. CPU나 메모리 사용량을 제한할 수 도 있고 호스트의 특정 포트와 연결하거나 호스트의 특정 디렉토리를 내부 디렉토리인것 처럼 사용할 수 있다.
사실 도커 등장 이전에도 프로세스를 격리 시키는 방법은 존재 했다. 리눅스에서는 cgroups(control groups), namespace를 이용한 LXC(Linux container)가 존재 했다. 도커는 LXC를 기반으로 시작해 0.9버전에서는 자체적인 libcontainer 기술을 사용했고 추후 runC기술을 합쳤다.
도커에서는 컨테이너와 더불어 이미지라는 개념 역시 중요 하다. 이미지는 컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있는 것 이다. 이미지는 상태값을 가지지 않고 immutable하다. 따라서 컨테이너는 이미지를 실행한 상태이며 추가되거나 변하는 값은 컨테이너에 저장 된다. 같은 이미지를 사용해 여러개의 컨테이너를 만들 수 있고 그런 컨테이너들의 상태가 바뀌거나 삭제되도 이미지는 변하지 않는다.
위에서 언급했듯이 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있다. 따라서 필요한 곳에 미리 만들어 놓은 이미지를 다운 받고 컨테이너를 생성하면 사용할 수 있다. 도커 이미지는 Docker hub 또는 Docker Registry에서 등록하거나 저장소를 만들어 관리할 수 있다.
도커는 overlay network, union file systems등 이미 존재하는 기술을 잘 조합해 사용하기 쉽게 만들었다.
도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 다 가지고 있다. 그때문에 이미지 파일 하나에 보통 용량이 수백 메가 또는 수 기가 정도 한다. 단순히 하나의 이미지 파일을 다운 받는 것은 문제가 없지만 기존 이미지 파일에 파일하나를 추가하기 위해 이런 대용량 파일을 다시 다운 받는건 매우 비효율 적이다.
도커는 이에 대한 해결책으로 layer개념을 도입하고 유니온 파일 시스템을 사용한다. 그때문에 여러개의 레이어를 하나의 파일 시스템으로 사용할 수 있고 이미지는 여러개의 read only레이어로 구성되기 때문에 파일이 추가되거나 수정되면 새로운 레이어가 생긴다.
컨테이너를 생성할 때도 레이어 방식을 사용한다. 기존의 이미지 레이어 위에 일기/쓰기 레이어를 추가해 이미지 레이어를 그대로 사용하면서 컨테이너가 실행중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용한다.
이미지는 url방식을 사용해 관리하며 태그를 붙일 수 있다. ubuntu 14.04 이미지의 경우 docker.io/libaray/ubuntu:14.04 등으로 사용할 수 있다.
도커는 이미지를 만들기 위해 Dockerfile이라는 파일에 자체 DSL(Domain-Specific language)언어를 이용해 이미지 생성 과정을 적는다.
출처 -https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html