Docker 정리

유호빈·2024년 4월 13일
0

1. Docker 란

도커는 컨테이너 가상화 환경 기술에 애플리케이션 관리, 실행과 같은 여러 기능들을 추가한 오픈 소스 플랫폼으로, 프로그램을 외부 환경과 격리시켜 구동할 수 있게 해주는 소프트웨어입니다.

1.1 가상화

가상화란 하나의 물리적 서버 호스트에서 여러 개의 가상 머신을 만드는 프로세스로, 하드웨어를 효율적으로 활용할 수 있도록 도와줍니다.

이러한 가상화의 종류에는 호스트 가상화, 하이퍼바이저 가상화, 컨테이너 가상화가 있습니다.

1) 호스트 가상화

호스트 가상화는 하드웨어 위에 베이스인 호스트 OS가 있고, 그 위에 가상화 SW를 설치해 게스트 OS를 작동시키는 기술입니다.
호스트 OS에서 게스트 OS가 동작하므로 CPU 리소스, 디스크, 메모리 사용량 등이 크다는 단점을 갖고 있습니다.

2) 하이퍼바이저 가상화

호스트 OS를 필요로 하지 않고, 하드웨어 위에 하이퍼바이저를 설치해 가상화를 구성하는 방법입니다.
호스트 OS 없이 하이퍼바이저가 OS 들에게 자원을 나눠주어 각 가상머신이 독립적인 호스트처럼 행동합니다.

3) 컨테이너 가상화

호스트 OS 위에 컨테이너 엔진을 설치해 애플리케이션이 작동하는데 필요한 요소(라이브러리, 실행 파일 등)을 모아 각자가 별도의 서버처럼 동작합니다.
위의 두 가상화처럼 여러 OS를 구동시키지 않고 애플리케이션 작동에 필요한 요소만으로 컨테이너를 구성하기 때문에 오버헤드가 적습니다.

1.2 특징과 기능

특징

  1. Docker는 실행 환경을 컨테이너에 담습니다. 따라서 Docker가 설치되어 있다면 컨테이너의 이미지를 기반으로 컨테이너를 실행시켜 같은 환경으로 동작시킬 수 있습니다.

  2. 각기 다른 서비스를 컨테이너라는 표준으로 배포하기 때문에 모든 서비스들의 배포 방식이 동일하게 됩니다.

기능

Docker의 주요한 기능은 빌드, 공유, 실행 세 가지로 분류할 수 있습니다.

1. 빌드

Docker 에서 빌드란 애플리케이션 실행에 필요한 프로그램, 라이브러리, 설정 등을 하나로 모아 패키징해 이미지를 생성하는 것을 의미합니다.

이미지의 중요한 특징은 바로 레이어 형태를 갖는다는 것입니다. 레이어는 도커 엔진의 캐시에 물리적으로 저장된 파일로, 따라서 여러 이미지가 컨테이너에서 공유됩니다.

위의 그림과 같이 레이어가 캐시되기 때문에 기존 이미지에 다른 파일을 추가하면 기존 이미지에 파일을 추가하는 개념입니다.

예를 들어, ubuntu 이미지가 A-B-C 레이어로 되어있다면 이를 기반으로 만든 nginx 이미지는 A-B-C-nginx의 레이어로 구성됩니다.
위의 그림의 web app 또한 마찬가지의 레이어로 구성이 됩니다. 이러한 특징 덕분에 web app source가 수정되었을 때, 기존 레이어는 제외하고 수정된 레이어만을 새로 다운받아 효율적으로 이미지를 관리합니다.

따라서 Dockerfile로 이미지를 생성 시 스크립트 내에서 자주 변하지 않는 부분은 레이어 초기에 두고 자주 변하는 부분은 나중에 두어 수정되기 이전 부분의 레이어는 캐시에서 재사용하며 Dockerfile을 최적화 할 수 있습니다.

2. 공유

빌드된 도커 이미지는 도커 레지스트리에서 통합적으로 공유, 관리할 수 있습니다.

이러한 도커 레지스트리의 예로 Docker Hub인 공식 레지스트리가 있고, 자주 사용하는 Github 등에서 소스를 관리하듯이 Docker Hub에서 이미지 버전을 관리할 수 있습니다.

또한, ubuntu와 같은 베이스 이미지가 배포되어 있어 이를 다운 받아 그위에 애플리케이션을 올려 새로운 이미지를 만들어 공유할 수 있습니다.

3. 실행

Docker 는 이미지를 기반으로 컨테이너 단위 서버를 실행시킵니다.

이러한 컨테이너의 실행, 정지, 파기는 도커 커맨드를 통해 이루어집니다. 커맨드를 입력했을 때의 플로우를 살펴보면 다음과 같습니다.

사용자가 도커 명령어를 입력하면 Docker Engine에 명령어를 보냅니다. 이를 전달받은 도커 클라이언트 (CLI)는 /var/run/dokcer.socket에 위치한 유닉스 소켓을 통해 도커 데몬의 API를 호출합니다. 도커 데몬은 명령어에 해당하는 작업을 수행하고 결과를 도커 클라이언트에 반환해 사용자에게 결과를 출력해줍니다.

여기서 도커 데몬은 컨테이너 관리 주체로, 컨테이너를 생성하고 실행, 이미지 관리의 역할을 합니다. 그리고 Docker Engine을 통해 사용자가 컨테이너를 관리할 수 있습니다.

2. Docker Container

2.1 컨테이너 구조

도커의 컨테이너는 컨테이너 레이어와 이미지 레이어로 구성됩니다.

컨테이어 레이어는 읽기/쓰기가 모두 가능한 계층으로 최상단 레이어에 추가되고, 컨테이너를 실행하고 변경되는 사항은 이 계층에 저장됩니다.

이미지 레이어는 읽기 전용 계층으로 다른 컨테이너와 공유할 수 있습니다. 따라서 공유된 이미지 레이어 계층 만큼 용량 확보를 할 수 있습니다.

2.2 Docker 명령어

Docker 명령어 구성은 위와 같습니다.

대상은 container, image, volume, network 등을 갖고 있습니다.

커맨드는 각 대상마다 다르며 docker container의 주요 커맨드는 다음과 같습니다.

옵션은 각 커맨드에 사용되는 옵션으로 컨테이너 생성 시의 옵션은 다음과 같은 옵션이 존재합니다.

3. Docker Container 통신

컨테이너는 기본적으로 독립적인 환경에서 실행되기 때문에 컨테이너 밖에서 접근할 수 없습니다.

따라서 컨테이너와 통신을 위해 가동 시 ‘p’ 옵션을 사용해 호스트의 포트와 컨테이너의 포트를 설정해야 합니다.

예를 들어 -p 8080:80으로 세팅하면 호스트의 포트는 8080, 컨테이너의 포트는 80으로 세팅해 네트워크를 설정합니다.

이때, 호스트에서 사용 중인 포트와 겹치지 않아야 합니다.

  • 컨테이너 간 통신은 뒤에 Docker Compose 부분에서 설명합니다.

4. Dockerfile

Dockerfile은 도커 이미지를 생성하기 위한 스크립트 파일로 도커의 인프라 구성을 관리할 수 있습니다.

docker build 커맨드를 통해 Dockerfile에 저장된 정보를 이미지로 생성하며 이미지 생성 시에 레이어 구조로 하나씩 계층적으로 쌓이면서 빌드가 됩니다.

Dockerfile에서 사용되는 주요 인스트럭션은 다음과 같습니다.

FROM

base가 되는 이미지를 지정하는 것으로, 주로 OS 이미지나 런타임 이미지를 지정합니다.

docker 이미지는 layer 형태이기 때문에 이 base를 기반으로 새로운 이미지를 중첩합니다. 따라서 보통 dockerfile의 최상단에 위치합니다.

RUN

이미지를 빌드 과정에서 이미지를 빌드하는 순간에 사용할 커맨드를 설정합니다. 따라서 라이브러리 설치 등에 주로 활용됩니다.

ADD

이미지에 호스트의 파일이나 폴더를 추가하기 위해 사용됩니다.

COPY

호스트 환경의 폴더나 파일을 docker 이미지의 파일 시스템으로 복사하기 위해 사용됩니다.

ADD와 동일하게 동작하지만 ADD는 url을 지정하거나 압축 파일을 자동으로 풀어주지만, COPY는 이러한 행동을 하지 않습니다.

EXPOSE

이미지가 통신에 사용할 포트를 지정할 때 사용합니다.

ENV

환경변수를 지정할 때 사용하고, $name, ${name}의 형태로 사용합니다.

CMD

도커 컨테이너가 실행될 때 실행할 커맨드를 지정합니다.

RUN은 이미지 빌드 시, CMD는 컨테이너를 생성해 최초 실행 시 수행되는 명령입니다.

ENTRYPOINT

도커 이미지가 실행될 때 사용되는 기본 커맨드를 강제합니다.

ENTRYPOINT는 항상 실행되지만, CMD는 docker run 명령 실행 시 COMMAND에 들어가는 값이 바뀌면 변경된다는 차이가 있습니다.

WORKDIR

작업할 디렉토리를 지정하는 옵션으로 이후 실행되는 명령은 이 디렉토리를 기준으로 실행됩니다.

VOLUME

퍼시스턴스 데이터를 저장할 경로를 지정해 호스트의 디렉토리를 도커 컨테이너와 연결합니다.

주로 휘발성으로 사용하면 안되는 데이터를 저장할 때 사용합니다.

Dockerfile로 이미지 빌드

이미지로 빌드 시 dockerfile이 위치한 directory를 지정해 줍니다.

-f 옵션을 통해 디렉토리 내의 dockerfile을 선택할 수 있습니다.

5. Docker Compose

Docker Compose는 여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너를 일괄로 관리할 수 있는 관리 도구입니다.

또한 Docker Compose 설정 시 network 이름을 지정해서 관리할 여러 컨테이너의 network를 간단하게 연결해 각 컨테이너 간의 통신이 가능하게 해줍니다.

기본적으로 default 네트워크를 생성해 모든 컨테이너를 연결시켜 줍니다.

docker-compose.yml 파일의 예시입니다.

여기서 services를 살펴보면 생성할 여러 컨테이너를 정의할 때 사용되며 컨테이너 하위 옵션은 다음과 같습니다.

services 외에도 volumes (도커 볼륨 설정), environment (환경 변수 설정), networks (네트워크 설정) 등의 설정을 하여 컨테이너들을 생성할 수 있습니다.

Docker Compose 실행

작성된 docker-compose.yml 파일은 docker-compose up 커맨드를 사용해 실행되며 현재 디렉토리의 docker-compose.yml 파일을 읽어 자동으로 컨테이너들을 생성합니다.

추가적으로 -f 옵션을 사용하면 실행시킬 docker-compose.yml 파일의 이름을 지정할 수 있습니다.

6. Docker 이미지 생성 및 저장

1) 이미지 생성

  1. 컨테이너로 이미지 생성

같은 설정을 사용하는 컨테이너를 가동할 경우 이미지로 생성해 사용할 수 있습니다.

이미지를 생성하는 경우는 다음과 같이 두 가지 경우가 있습니다.

  • 특정 이미지에 자주 사용하는 설정을 추가하는 경우

  • 개발한 애플리케이션을 이미지로 생성하는 경우


생성하는 방법의 첫 번째는 컨테이너가 있는 상황에서 커맨드를 입력합니다.

container_name : 이미지로 만들고자 하는 컨테이너의 이름

image_name : 생성할 이미지 이름



두 번째 생성 방법은 위의 dockerfile을 이용해 빌드하여 이미지로 만듭니다.

2) 이미지를 파일로 저장

생성된 이미지를 파일로 저장하는 방법은 save/load , export/import 커맨드를 사용하여 파일로 저장할 수 있습니다.

save/load

save를 이용한 이미지 저장은 원본 이미지와 레이어를 동일하게 가져가는 형식으로 동작합니다.

export/import

원본 이미지와 다르게 하나의 레이어로 통합되어 추출되므로 다시 컨테이너로 가동 시 별도의 작업이 필요합니다.

import 할 때 --change ‘CMD [”/bin/bash”]’ 와 같이 CMD 값을 넣어줘야 컨테이너로 실행 가능합니다.

7. 컨테이너 환경에서의 JVM 메모리 설정

컨테이너 환경에서 Heap Memory 설정

Heap Memory란 프로그램에서 동적으로 할당된 메모리를 관리하는 데 사용되는 영역으로 컨테이너 실행 시 Heap Memory를 설정할 수 있습니다.

  • initialRamPercentage

자바 애플리케이션의 초기 힙사이즈 설정

default 1.5625%


  • MinRamPercentage

적은 메모리 사이즈에서 운영되는 애플리케이션의 최대 힙 사이즈 설정

메모리 256mb 이하

default : 50%


  • MaxRamPercentage

충분한 양의 메모리 운영되는 애플리케이션의 최대 힙 사이즈 설정

메모리 512mb 이상

default : 25%

8. 도커 스토리지

도커의 컨테이너는 무상태의 애플리케이션에서 최적의 실행 환경이 됩니다. 따라서 사용량이 증가하면 컨테이너 수를 증가시켜 모든 요청을 똑같이 신뢰성 있게 처리할 수 있습니다.

이처럼 같은 이미지로 만들어진 컨테이너들은 기본적인 이미지 레이어는 공유하지만 기록 가능 레이어는 각 컨테이너마다 다릅니다. 따라서 다른 값을 저장하고 기록합니다.

이 기록 가능 레이어는 컨테이너의 생명 주기와 같은 생명주기를 갖게 되어 컨테이너 삭제 시 같이 삭제됩니다. 따라서 DB와 같이 지속되어야 할 데이터를 저장하기 위해 Docker의 두 가지 옵션인 Docker Volume과 Bind Mount를 사용합니다.

1) Docker Volume

Docker Volume은 도커 엔진이 관리하는 호스트 머신의 폴더로 도커에서 스토리지를 다루는 단위입니다.

볼륨은 호스트 디렉토리의 /var/lib/docker/volumes의 경로에 저장되어 컨테이너와 독립적으로 존재하기 때문에 별도의 생애주기를 갖게 됩니다.

2) Bind Mount

볼륨과 비슷한 개념이지만 Bind Mount는 호스트 OS의 디렉토리에 직접적으로 연결합니다.

호스트와 디렉토리를 공유하므로 컨테이너에서 호스트 파일을 수정 가능하고, 반대의 경우도 가능합니다.


둘의 가장 큰 차이점은 Docker 가 해당 포인트를 관리하는지 여부입니다.
profile
시작하자

0개의 댓글