Connecting
Docker란 무엇인가? 도커에 대해 알아보기 본문
Hello Docker
가상화 기술과 컨테이너
컴퓨터 성능이 비약적으로 향상되면서 가상화라는 단어는 일반적인 단어가 되었다.
가상 머신을 구성하기 위해서 우리는 VMWare, VirtualBox, KVM, Hyper-V 기술을 사용했으나, 최근에는 Docker로 대표되는 LXC(Linux Container)와 같은 컨테이너형 가상화로 옮겨지고 있는 추세이다.
컨테이너형 가상화 기술은 기존의 가상화 기술보다 가벼워 지고, 이식성이 뛰어난 특징을 가지고 있다.
기존의 가상머신
가상 머신 자체는 완전한 컴퓨터라고 할 수 있다.
OS를 자체적으로 가지고 있기 때문에 OS를 가상머신 이미지에 포함해야 하고, 배포이미지의 용량이 커지게 된다는 단점이 있다.
가상화 기술의 개발이 활발해 지면서 기존의 하이퍼바이저와 다른 베어메탈 하이퍼바이저가 공개되면서 성능 문제는 많이 해결되었다.
하지만 Type-1 방식의 경우 게스트 OS 커널의 수정이 불가함에 따라 다양한 OS를 지원하는데 한계점이 있다는 문제점이 꾸준이 지적되었다.
Xen를 활용하여 서비스를 운영하는 AWS 경우에는 기술개발의 향상에 따라 Type-1과 Type-2의 퍼포먼스 향상의 차이가 크게 나지 않게 되면서 새로운 인스턴스 타입은 전부 HVM 즉 Type-2 방식으로 전환이 완료되었다.
하지만 전가상화, 반가상화 게스트OS를 설치하여 운영하는 방식에는 하드웨어 성능을 100% 뽑아내기 어렵다든 단점을 가지고 있기 때문에 성능개선 문제가 꾸준히 대두 되었고 이를 해결하기 위한 프로세스 격리 방식이 나오게 되었다.
컨테이너 기술
리눅스에서는 리눅스 컨테이너라고 불리우는 곳에 프로세스를 격리시키는데, 좀더 자세히 살펴보자면 OS의 내부에는 물리적 자원을 관리하는 커널공간과 사용자 프로세스를 실행하는 사용자 공간으로 나뉘어진다.
컨테이너 가상화는 사용자 공간을 여러 개로 나누어 각각의 사용자 프로레세스에서 보이는 리소스를 제한하여 CPU나 메모리는 프로세스가 필요한 만큼만 추가적으로 사용하고 성능적으로 손실이 거의 없다는 것이 특징이다.
기존의 가상화 기술에서는 가상 머신이 실제 물리 하드웨어를 에뮬레이트하기 때문에 OS가 반드시 필요하다.
LXC는 모든 프로세스는 호스트 OS에서 바로 시작하며, 일반적인 프로세스와 다른점은 그 과정의 일부를 그룹화하고 다른 그룹과 그룹에 속하지 않는 프로세스에서 단절된 공간으로 동작한다는 것이다.
이러한 방식의 차이점 때문에 가상화 오버헤드가 거의 발생하지 않고 가상 머신의 부팅 및 종료라는 개념이 존재하지 않는다.
OS가 사용하는 자원을 분리하여 여러 환경을 만들 수 있고, 가상 화경의 시작과 종료를 빠르게 실행할 수 있다.
컨테이너 방식은 OS에서 관리하기 때문에 "OS 레벨 가상화"라고 불리기도 한다.
컨테이너의 장점과 단점
빠른 시작과 종료 속도
LXC를 사용하다 보면 다른 가상화 기술머신보다 시작과 종료가 빠르다는 것을 알 수 있다. 컨테이너를 생성한다는 것은 OS 입장에서 단순히 프로세스를 시작하는 것이기 때문에 일반적인 프로세스가 시작하는 것과 별반 차이가 없다.
가상환경이 커널에서 공유되기 때문에 새로운 커널을 시작할 필요가 없고, 하드웨어 초기화 등의 작업이 필요없다.
높은 집적도
컨테이너는 커널이 직접 프로세스를 조작하여 분리된 공간을 구성하기 때문에 PC상에서 동작하는 OS는 하나이다.
여러 개의 컨테이너를 만들어 실행 중이라고 해도 OS는 하나이기 때문에, 가상머신에 비해 고밀도가 가능하다.
컨테이너에서는 실행되는 프로세스를 위한 메모리만 필요하기 때문에 낮은 사양의 환경에서도 동작이 가능하다.
낮은 오버해드
가상화를 위한 하으웨어 에뮬레이트 단계없이, 분리된 공간을 만들기 때문에 오버해드가 줄어든다.
애플리이케이션 컨테이너 지원
컨테이너는 가상머신과 달리 init을 먼저 시작하거나 각종 데몬들을 실행할 필요가 없다.
컨테이너는 목적에 맞는 프로세스만 존재하는 환경을 만들 수 있다. 예를 들어 웹서버용 컨테이너라면 Apache Httpd 프로세스만 존재하는 컨테이너를 만들 수 있다.
이러한 환경을 애플리케이션 컨테이너라고 하며, init를 처음 시작하여 보통의 OS가 시작하는 것과 같은 환경을 만들 수 있는데 이를 시스템 컨테이너라고 부른다.
컨테이너의 단점
HOST OS에 종속적
Linux 컨테이너는 OS에서 Linux Kernel이 관리하기 때문에 Linux 이외의 다른 OS에서는 동작하지 않으며, 컨테이너 환경에서도 다른 OS를 설치할 수 없다.
컨테이너의 Linux 모든 배포판을 설치할 수 있지만, 실행중인 커널은 하나이기에 컨테이너는 호스트 OS의 커널을 사용하게 된다. 예를 들어 Ubuntu Host OS 컨테이너의 CentOS를 설치한다고 해도 실행중인 커널은 Ubuntu 커널이다.
컨테이너별 커널구성이 불가능
커널의 관련된 작업은 가능하지만 컨테이너마다 다른 커널 작업을 수행할 수 없다. 커널의 기능으로 구성되는 환경이기 때문에 전체 컨테이너에서 보이는 커널은 동일하기 때문에 컨테이너에서 보이는 장치나 로드되는 커널 모듈은 모두 동일하다.
Docker
2013년 3월 산타클라라에서 열린 Pycon Conference에서 dotCloud의 창업자인 Solomon Hykes가 The future of Linux Containers 라는 세션을 발표하면서 처음 세상에 알려졌다.
이 발표 이후 도커가 인기를 얻으면서 2013년 10월 아예 회사이름을 도커(Docker Inc.)로 바꾸고 2014년 6월 도커 1.0을 발표한다.
2016년 설문조사에서 90%가 개발에 사용중이고 80%가 DevOps에 사용할 예정이며 58%가 운영환경에서 사용중이라고 한다.
2014년 도커 서울 밋업을 시작할 때만 해도 대부분의 사람들이 도커를 잘 모르고 개념도 이해하지 못했는데 이제는 거의 모르는 사람이 없을 정도로 널리 쓰이고 있다.
도커역시 앞에서 말했던 컨테이너 기술을 사용한다. 프로세스를 격리시켜서 사용하는 방식이기 때문에 가볍고 빠른 동작이 가능하며, 하나의 서버의 여러개의 컨테이너를 실행하면 서로 영향을 미치지 않고 독립적으로 실행되어 가벼운 VM을 사용하는 느낌을 준다.
실행중인 컨테이너에 접속하여 명령어를 입력할 수 있고
apt-get
이나yum
으로 패키지를 설치할 수 있으며 사용자도 추가하고 여러개의 프로세스를 백그라운드로 실행할 수도 있습니다. CPU나 메모리 사용량을 제한할 수 있고 호스트의 특정 포트와 연결하거나 호스트의 특정 디렉토리를 내부 디렉토리인 것처럼 사용할 수도 있다.새로운 컨터이너를 만드는데 걸리는 시간은 겨우 1-2초로 가상머신과 비교도 할 수 없이 빠르다.
Docker의 기본 네트워크 모드인 Bridge 모드로 약간의 성능 손실이 있기 때문에 네트워크 성능이 중요한 프로그램인 경우에는 --net=host 옵션을 고려해야 한다.
컨테이너 기술은 앞서 말했듯이 기존에도 있었기 때문에 Docker만의 장점이라고 할 수 없으며, Docker가 처음 만들었다고 할 수 없다. 새로운 기술이 아니지만 이렇게 많은 인기를 가질 수 있었던 이유는 이미 있는 기술을 잘 포장했기 때문이다.
Docker Image
도커에서 가장 중요한 개념은 컨테이너와 함께 이미지 개념이다.
이미지는 컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것으로 상태값을 가지지 않고 변하지 않는다.
컨테이너를 이미지를 실행한 상태라고 볼 수 있고, 추가되고 변하는 값은 컨테이너에 저장된다.
같은 이미지를 여러개의 컨테이너에서 생성할 수 있고 컨테이너의 상태가 변경되거나, 삭제되어도 이미지는 변하지 않고 그대로 남아있다.
Ubuntu이미지는 ubuntu를 실행하기 위한 모든 파일을 가지고 있고 MySQL이미지는 debian을 기반으로 MySQL을 실행하는데 필요한 파일과 실행 명령어, 포트 정보등을 가지고 있습니다. 좀 더 복잡한 예로 Gitlab 이미지는 centos를 기반으로 ruby, go, database, redis, gitlab source, nginx등을 가지고 있다.
컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 의존성 파일을 컴파일하고 이것저것 설치할 필요성이 사라진다.
새로운 서버가 추가되면 미리 만들어 놓은 이미지를 다운받고 컨테이너를 생성하면 된다.
도커 이미지는 Docker hub에 등록하거나 Docker Registry 저장소를 직접 만들어 관리할 수 있습니다. 현재 공개된 도커 이미지는 50만개가 넘고 Docker hub의 이미지 다운로드 수는 80억회이다. 누구나 쉽게 이미지를 만들고 배포할 수 있다.
레이어 저장방식
도커 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 보통 용량이 수백MB이다.
처음 이미지를 다운받으면 크게 부담이 되지 않지만 기존 이미지에 파일이 하나 추가되었다고 다시 다운받는 것은 비효휼적일 수 밖에 없다.
이런 문제를 해결하기 위해서 도커는 레이어라는 개념을 도입하여, 유니온 파일 시스템을 이용하여 여러개의 레이어를 하나의 파일 시스템으로 사용할 수 있게 해준다.
예를 들어 ubuntu 이미지가
A
+B
+C
의 집합이라면, ubuntu 이미지를 베이스로 만든 nginx 이미지는A
+B
+C
+nginx
가 된다. webapp 이미지를 nginx 이미지 기반으로 만들었다면 예상대로A
+B
+C
+nginx
+source
레이어로 구성된다. webapp 소스를 수정하면A
,B
,C
,nginx
레이어를 제외한 새로운source(v2)
레이어만 다운받으면 되기 때문에 굉장히 효율적으로 이미지를 관리할 수 있다.컨테이너를 생성할 때도 레이어 방식을 사용하는데 기존의 이미지 레이어 위에 읽기/쓰기read-write 레이어를 추가한다. 이미지 레이어를 그대로 사용하면서 컨테이너가 실행중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 레이어에 저장되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용한다.
이미지 경로
이미지는 url 방식으로 관리하며 태그를 붙일 수 있다. ubuntu 14.04 이미지는
docker.io/library/ubuntu:14.04
또는docker.io/library/ubuntu:trusty
이고docker.io/library
는 생략가능하여ubuntu:14.04
로 사용할 수 있다.이러한 방식은 이해하기 쉽고 편리하게 사용할 수 있으며 태그 기능을 잘 이용하면 테스트나 롤백도 쉽게 할 수 있다.
Dockerfile
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
도커는 이미지를 만들기 위해 Dockerfile 이라는 파일에 자체 DSL(Domain-Specific Language) 언어를 사용하여 이미지 생산 과정을 적는다.
서버에 어떤 프로그램을 설치하기 위해서 의존성 패키지를 설치하고 설정파일을 만들지 않고 Dockerfile로 관리하면 된다.
'Container' 카테고리의 다른 글
Docker, Stacks (0) | 2018.06.19 |
---|---|
Docker Swarms (4) | 2018.06.13 |
Docker 컨테이너와 서비스 (0) | 2018.06.05 |
도커와 친해지기 - 도커 명령어와 간단한 어플리케이션 만들기 (0) | 2018.06.03 |
Hello 도커(Docker), 도커 설치기와 입문 (0) | 2018.03.18 |