도커(Docker)

1.1 도커(Docker) 란?

Go언어로 작성된 리눅스 컨테이너 기반으로 하는 오픈소스 가상화 플랫폼.다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포/관리를 단순하게 해준다. 백엔드 프로그램, 데이터베이스 서버, 메시지 큐등 어떤 프로그램도 컨테이너로 추상화할 수 있고 조립PC, AWS, Azure, Google cloud등 어디에서든 실행할 수 있다.

1.2 Immutable Infrastructure 패러다임

Immutable Infrastructure는 직역 하자면 불변의 인프라(기반)으로 어떤 서비스를 구축하는 기반이 되는 것들을 변경하지 않는 패러다임을 뜻한다.

마이크로서비스 아키텍처가 등장하면서 거대한 한 덩어리의 서비스를 잘게 쪼개어 여러개의 서비스로 운영하는 환경으로 대세가 바뀌면서 각각의 서비스를 띄우기 위한 서버를 구축해야 했다. 그때마다 각각의 서버(리눅스/유닉스)에는 기본적인 라이브러리를 설치하고 웹서버 또는 WAS 를 설치해야 했으며 초기 설정을 해주는 등의 작업을 반복한다. 물론 쉘 스크립트를 작성하여 설치와 설정 등을 자동화시킬 수도 있지만 쉘 스크립트에는 한계가 존재한다. 쉘 스크립트로는 중앙 관리 기능이나 복잡한 기능의 구현은 힘들기 때문이다.

이때 Immutable Infrastructure 라는 패러다임이 등장했다.

호스트 OS와 서비스 운영 환경(서버 프로그램, 소스코드, 컴파일된 바이너리)를 분리하고 한번 설정한 운영 환경은 변화하지 않는다. 즉, 한 번 구축 및 설정한 서비스 운영 환경을 이미지로 생성한 뒤 서버에 배포하여 실행한다. 이때 서비스가 업데이트 되면 운영 환경(인프라) 자체를 변경하지 않고 이미지를 새로 생성하여 배포하는 것이다.도커는 이러한 Immutable Infrastructure를 구현한 도구이다.

1.3 VMware 와 Docker 의 비교


가상 머신은 하나의 서버를 여러 서버로 전환하는 물리적인 하드웨어의 추상화라고 정의한다.하이퍼바이저(Hypervisor) 기법을 통해 단일 시스템에서는 여러 VM을 실행할 수 있지만, 각 VM에는 운영 체제(Guest OS), 애플리케이션, 필요한 Binary 및 Library의 전체 복사본이 포함되어 있다. 따라서 이 복사본은 수십 GB를 차지하기 때문에 VM의 부팅 속도 또한 느려질 수 있다는 특징이 있다.

반면에 도커(Docker)의 구조를 보면 하나의 Host OS(Host Operating System)위에 Docker 엔진을 설치하여 그 위에 각각의 서비스(Application) 환경들을 설치/운영하는 형태이다. 따라서 Application들은 각각 OS를 설치하는 것이 아니라 하나의 HostOS 위에서 커널을 공유하기 때문에 상대적으로 매우 가벼우며 Docker가 설치된 환경이라면 이미지(Image)가 사용 가능하기 때문에 어디서든 사용 가능하다는 장점이 있다.

하이퍼바이저 (Hypervisor): 게스트 OS에 가상 운영 플랫폼(호스트 하드웨어의 프로세서, 메모리 및 리소스)을 제공하면서 게스트 OS를 관리한다. 다양한 운영 체제의 여러 인스턴스가 가상화된 하드웨어 리소스를 공유할 수 있다.

1.4 Docker 를 사용하는 이유

  1. 구성 단순화

Docker는 하나의 Configuration으로 모든 플랫폼에서 실행할 수 있다. Configuration 파일을 코드에 넣고 환경 변수를 전달하여 다른 환경에 맞출 수 있다. 따라서, 하나의 Docker 이미지를 다른 환경에서 사용할 수 있다.

  1. 코드 관리

Docker는 일관된 환경을 제공하여 개발 및 코딩을 훨씬 편안하게 만들어준다.Docker 이미지는 변경이 불가하기에 개발환경에서 운영 환경까지 애플리케이션 환경이 변경되지 않는 이점이 존재한다.

  1. 개발 생산성 향상

개발 환경을 운영 환경에 최대한 가깝게 복제할 수 있다. Docker를 사용하면 코드가 운영 환경의 컨테이너에서 실행될 수 있으며 VM과 달리 Docker는 오버 헤드 메모리 용량이 적기에 여러 서비스를 실행하는데 도움이 된다. 또한 Docker의 Shared Volume을 사용하여 호스트에서 컨테이너의 어플리케이션 코드를 사용할 수 있도록 할 수 있다. 이를 통해 개발자는 자신의 플랫폼 및 편집기 에서 소스 코드를 편집하고 이는 Docker내에서 실행 중인 환경에 반영된다.

  1. 애플리케이션 격리

Web Server(e.g. Apache, Nginx)와 연결된 API 서버를 격리할 필요가 있는 경우가 있다. 이 경우 다른 컨테이너에서 API를 서버를 실행할 수 있다.

  1. 빠른 배포

컨테이너가 OS를 부팅하지 않고 어플리케이션을 실행하기 때문에 Docker 컨테이너를 매우 빠르게 만들 수 있다.

1.5 Docker Image

이미지는 컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있으며 상태값은 가지지 않는다.컨테이너는 이미지를 실행한 상태라고 볼 수 있고 추가되거나 변하는 값은 컨테이너에 저장한다.

같은 이미지에서 여러개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 삭제되어도 이미지는 변하지 않는다.

예를 들어 Apache Server 이미지는 Apache Server를 실행하기 위한 모든 파일을 가지고 있으며, MySQL 이미지는 MySQL을 실행하는데 필요한 파일과 실행 명령어, port 정보 등을 모두 가지고 있다.

1.5.1 이미지와 레이어(Layer)- 레이어(Layer) 란?

기존 이미지에 추가적인 파일이 필요할 때 다시 다운로드받는 방법이 아닌 해당 파일을 추가하기 위한 개념이다. 이미지는 여러 개의 읽기 전용(read only) Layer로 구성되고, 파일이 추가되면 새로운 Layer가 생성된다.그리고 도커는 여러 개의 Layer를 묶어서 하나의 파일시스템으로 사용할 수 있게 해준다. 추가적으로 DockerHub 및 개인 저장소에서 이미지를 공유할 때는 바뀐 부분(Layer = image)만 주고받기 가능하다.

ubuntu 이미지가 A + B + C의 집합이고 ubuntu 이미지를 베이스로 만든 nginx 이미지는 A + B + C + nginx가 된다. webapp 이미지를 nginx 이미지 기반으로 만들었다면 예상대로 A + B + C + nginx + source Layer로 구성된다. webapp 소스를 수정하면 A, B, C, nginx Layer를 제외한 새로운 source(v2) Layer만 다운받으면 되기 때문에 굉장히 효율적으로 이미지를 관리할 수 있다.

컨테이너를 생성할 때도 Layer 방식을 사용하며 기존의 이미지 레이어 위에 읽기/쓰기(read-write) Layer를 추가한다.이미지 Layer를 그대로 사용하면서 컨테이너가 실행중에 생성하는 파일이나 변경된 내용은 읽기/쓰기 Layer 에 저장 되므로 여러개의 컨테이너를 생성해도 최소한의 용량만 사용한다.

이와 같은 도커 이미지의 Layer 개념을 기반으로 계층 캐싱 / 멀티 스테이지 방식을 사용하면 용량을 줄여 더 효율적으로 성능이 좋은 컨테이너를 생성한다.

  • 이미지 빌드 모범 사례 ( 계층 캐싱 / 멀티 스테이지 )

https://docs.microsoft.com/ko-kr/visualstudio/docker/tutorials/image-building-best-practices

1.6 Docker Container

이미지(Image)를 실행한 상태. 응용프로그램의 종속성과 함께 응용프로그램 자체를 패키징, 캡슐화하여 격리된 공간에서 프로세스를 동작시키는 기술이다.

  • 특징

컨테이너는 이미지 Layer에 읽기/쓰기(read-write) Layer를 추가하는 것으로 생성/실행된다. 따라서 여러 개의 컨테이너를 생성해도 최소한의 용량만 사용되며 바뀐 부분을 읽기/쓰기 Layer 에 적용된다.

컨테이너는 종료 되었다고 메모리에서 삭제 되지않고 남아있다. 삭제 하려면 명시적으로 삭제해야 한다. 즉, 종료가 되어도 컨테이너 & 읽기/쓰기 Layer 또한 그대로 존재하기 때문에 다시 시작할 수 있다.

한 서버는 여러 개의 컨테이너를 가져도 당연히 상관없으며, 컨테이너는 각각 독립적으로 실행된다.

컨테이너는 커널 공간과 호스트OS 자원(시스템 콜)을 공유한다.

1.7 Docker File

이미지 생성 출발점으로 이미지를 구성하기 위한 명령어들을 작성하여 이미지를 구성하는 파일이다.Docker File을 읽을 수만 있다면 해당 이미지가 어떻게 구성되어 있는지도 알 수 있다.

FROM jdk8:latest
    
WORKDIR /app

RUN mkdir /app/nexus-2.14.9-01
RUN mkdir /app/sonatype-work
RUN yum -y install httpd

ENV JAVA_HOME /usr/local/jdk1.8.0_181
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.

EXPOSE 3411 
ADD run.sh /app/
           
CMD ["/app/run.sh"]
  • 도커파일 명령어 참고

http://longbe00.blogspot.com/2015/03/dockerfile.html

1.8 Docker Hub & Docker Registry

Docker Hub에서는 이미지를 저장하고 관리해준다. (https://hub.docker.com/search?q=&type=image)위에서도 많은 회사들이 Docker로 소프트웨어를 배포하기 시작했고 공개이미지들을 공유할 수 있다. Docker Hub를 이용하면 손쉽게 이미지를 pull 받아 컨테이너에 적용 시킬 수 있다. (GitHub와 비슷.)

그렇다면 Docker Registry는 무엇일까?

Docker Hub처럼 공개된 방식이 아닌 비공개적으로 구축한 격리된 저장소이다.

Docker 이미지를 pull받기 위한 url 이다. 그림과 같이 앞에있는 url을 적지 않으면 default로 Docker Hub에서 Image를 pull 받게되고 url을 적어준다면 사설 저장소에서 이미지를 받을 수 있다.

  • 문서 참고

https://docs.docker.com/get-started/overview/

https://medium.com/dtevangelist/docker-%EA%B8%B0%EB%B3%B8-1-8-hello-docker-5165abd00a3d

https://cultivo-hy.github.io/docker/image/usage/2019/03/14/Docker정리/

좋은 웹페이지 즐겨찾기