GDSC Sookmyung 활동/Speaker Session & Hands on Workshop

[Docker] Docker로 배포하기

DongsunSin 2021. 3. 27. 04:20

이 글은 2021.03.29 에 진행된 코어멤버 동선님의 'Docker로 배포하기' 세션을 바탕으로 작성된 블로그 포스팅입니다.

새 창에서 열기 (발표자 노트를 참고하실 수 있습니다)

 

미리 도커데스크톱을 설치해 오시면 빠른 진행이 가능합니다! (www.docker.com/products/docker-desktop)

1. Docker 

Containers vs Virtual Machines

가상화 : 하이퍼바이저라고 하는 소프트웨어는 리소스가 파티셔닝되어 VM 전용으로 할당될 수 있도록 리소스를 물리 머신에서 분리합니다. 사용자가 물리 환경의 추가 리소스를 요구하는 VM 명령을 발행하면 하이퍼바이저는 이 요청을 물리 시스템으로 전달하고 변경 사항을 캐싱합니다. VM은 물리 서버처럼 보이고 작동하므로 애플리케이션 종속성 및 대규모 OS 설치 공간(단일 애플리케이션이나 마이크로서비스를 실행하는 데는 거의 필요하지 않음)의 단점을 증대시킬 수 있습니다.

컨테이너: 컨테이너는 마이크로서비스 또는 애플리케이션과 이를 실행하는 데 필요한 모든 것이 포함되어 있습니다. 컨테이너에 있는 모든 것은 '이미지'라고 하는 모든 라이브러리와 종속성을 포함하는 코드 기반 파일에 저장됩니다. 이 이미지는 RPM 패키지 및 구성 파일과 함께 제공되므로 이 파일은 Linux 배포 설치로 간주될 수 있습니다. 컨테이너는 너무 작기 때문에 일반적으로 수백 개가 서로 느슨하게 결합되어 있으므로 컨테이너 오케스트레이션 플랫폼을 사용하여 컨테이너를 프로비저닝하고 관리합니다.

Docker 이미지

컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 Docker Image. Docker layer란 적어도 다른 하나의 이미지와 관련된 이미지입니다. 이미지는 parent/child 관계를 유지합니다. 이미지는 다른 이미지와 relationship을 가질 수 있고, 다른 레포지토리의 다른 소유자의 이미지도 포함됩니다.

Dockerfile

Dockerfile은 이미지를 생성하기 위한 스크립트이며, Dockerfile을 빌드하면 도커 이미지가 생성됩니다. 

  • FROM

FROM은 어떠 이미지를 기반으로 이미지를 생성할지 설정합니다. FROM은 반드시 설정해야 합니다.

이미지 이름과 태그를 함께 설정할 수도 있습니다.

  • RUN

RUN은 FROM에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행합니다. 여기서 RUN으로 실행한 결과가 새 이미지로 생성되고, 실행 내역은 이미지의 히스토리에 기록됩니다. 

셸 없이 실행은 RUN ["<실행 파일>", "<매개 변수1>", "<매개 변수2>"] 형식, 

셸로 실행은 RUN <명령> 형식입니다. 

RUN으로 실행한 결과는 캐시되며 다음 빌드 때 재사용합니다. 이를 원치 않으려면 docker build 명령에서 --no-cache 옵션을 사용하세요.

  • CMD

CMD는 컨테이너가 시작되었을 때 스크립트 혹은 명령어를 실행합니다. 즉 docker run 명령으로 컨테이너를 생성하거나 docker start 명령으로 정지된 컨테이너를 시작할 때 실행됩니다. CMD는 Dockerfile에서 한 번만 사용할 수 있습니다.

CMD ["<실행 파일>", "<매개 변수1>", "<매개 변수2>"] 형식으로 사용합니다.

  • ENTRYPOINT를 사용하였을 때

CMD ["<매개 변수1>", "<매개 변수2>"] 형식입니다. ENTRYPOINT에 설정한 명령에 매개 변수를 전달하여 실행합니다. Dockerfile에 ENTRYPOINT가 있으면 CMD는 ENTRYPOINT에 매개 변수만 전달하는 역할을 합니다. 그래서 CMD 독자적으로 파일을 실행할 수 없게 됩니다.

  • ENTRYPOINT

ENTRYPOINT는 컨테이너가 시작되었을 때 스크립트 혹은 명령을 실행합니다. CMD와 실행 조건은 동일합니다. ENTRYPOINT ["<실행 파일>", "<매개 변수1>", "<매개 변수2>"] 형식입니다. 셸을 사용하지 않는 방식입니다. CMD와 ENTRYPOINT는 컨테이너가 생성될 때 명령어가 실행되는 것은 동일하지만, docker run 명령에서 다릅니다. docker run <이미지> <실행할 파일> 형식인데, docker run 명령에서 실행할 파일을 설정하면 CMD는 무시됩니다. ENTRYPOINT는 무시되지 않고, 실행할 파일 설정 자체를 매개 변수로 받아서 처리합니다.

  • EXPOSE

EXPOSE는 호스트와 연결할 포트 번호를 설정합니다.

EXPOSE <포트 번호> 형식

EXPOSE 하나로  포트 번호를 두 개 이상 동시에 설정할 수 있습니다. EXPOSE는 호스트와 연결만 할 뿐 외부에 노출되지 않습니다. 

포트를 외부에 노출하려면 docker run 명령의 -p, -P 옵션을 사용해야 합니다.

  • ENV

 ENV는 환경 변수를 설정합니다. ENV로 설정한 환경 변수는 RUN, CMD, ENTRYPOINT에 적용됩니다.

  • ADD

ADD는 파일을 이미지에 추가합니다. ADD <복사할 파일 경로> <이미지에서 파일이 위치할 경로> 형식입니다.

  • COPY

COPY는 파일을 이미지에 추가합니다. ADD와 달리 COPY는 압축 파일을 추가할 때 압축을 해제하지 않고, 파일 URL도 사용할 수 있습니다.

  • VOLUME

VOLUME은 디렉토리의 내용을 컨테이너에 저장하지 않고 호스트에 저장하도록 설정합니다. 

VOLUME <컨테이너 디렉터리> 또는 VOLUME ["컨테이너 디렉터리 1", "컨테이너 디렉터리2"] 형식입니다.

단, VOLUME으로는 호스트의 특정 디렉토리와 연결할 수는 없습니다. → 그러려면 docker run 명령에서 -v 옵션을 사용하세요.

( -v <호스트 디렉터리>:<컨테이너 디렉터리>)

Docker 알쓸신잡

컨테이너 구현에는 리눅스 namespace, 루트 디렉토리 격리, 컨트롤 그룹, capability, union mount 외에 다양한 리눅스 커널 기능들이 사용됩니다. 한 번 자유롭게 이야기를 나눠볼까요?

리눅스 네임스페이스(Linux namespace): 리눅스 네임스페이스는 특정 프로세스의 리눅스 리소스 접근을 제어하기 위해 사용됩니다. 네임스페이스는 리소스 별로 IPC 네임스페이스, 마운트 네임스페이스, 네트워크 네임스페이스, 프로세스 ID 네임스페이스, 사용자 네임스페이스, UTS 네임스페이스, 컨트롤 그룹 네임스페이스 등으로 나뉩니다.

시스템 상에서 실행되는 프로세스들은 기본적으로 init 프로세스의 네임스페이스를 공유하지만 시스템콜이나 unshare 명령어를 사용해 리소스 별로 네임스페이스를 분리하는 것이 가능합니다.

  • 도커에서 PID 네임스페이스가 어떻게 사용되고 있나요?

루트 디렉토리 격리와 chroot

컨트롤 그룹(cgroups)

리눅스 캐퍼빌리티(Linux capabilities)

유니온 마운트(Union Mount)


2. Dockerizing Spring Boot APP

우리는 Spring Boot를 학습하는 목적이 아니므로 Spring 에서 제공해주는 기본 템플릿을 사용해서 도커 이미지를 생성해봅니다.

참고) DSC Sookmyung 내 깃허브 링크

[docker build -t dsc-docker-practice . ]

[docker images]

Dockerfile로 생성한 이미지를 내 로컬 서버에서 확인할 수 있습니다. 

Dockerfile을 작성할 때 하나의 팁은 jre가 필요한 지, jdk가 필요한 지 구분하는 것 입니다.


3. Deploying Docker Container on GCP

첨부된 PPT를 확인해주세요.

 

 

 

참고자료

www.redhat.com/ko/topics/containers/containers-vs-vms

 

컨테이너와 VM 비교

Linux 컨테이너 및 VM(가상 머신)은 다양한 IT 요소를 결합해 시스템의 나머지 부분으로 부터 격리하는 패키징된 컴퓨팅 환경입니다.

www.redhat.com

도서: Docker in action