Skip to content
Go back

Docker란

Updated:
Edit page

Table of contents

Open Table of contents

도커란?

Go언어로 작성된 리눅스 컨테이너 기반으로하는 오픈소스 가상화 플랫폼이다.
특정한 서비스를 패키징하고 배포하는데 유용한 오픈소스 프로그램이다.
컨테이너에는 라이브러리, 시스템 도구, 코드, 런타임 등 소프트웨어를 실행하는데 필요한 모든 것이 포함되어 있다.
가상 머신에 비해 꼭 필요한 것만 담겨서 구동되기 때문에 이미지를 만들 경우 용량이 대폭 줄어들게 된다.

도커를 사용하는 이유

도커 이미지와 컨테이너란?

Docker Image란 컨테이너를 실행할 수 있는 실행파일, 설정 값들을 가지고 있는 것으로, 더 이상 의존성 파일을 컴파일하거나 이것저것 설치할 필요가 없는 상태의 파일을 의미한다.
Image를 컨테이너에 담고 실행시키면 해당 프로세스가 동작한다.
도커 이미지는 기존 이미지에 추가적인 구성이 필요할 때 다시 다운로드하는 방법이 아닌 기존이미지에 레이어를 추가하여 구성을 올려주는 방식으로 생성된다.
즉, 이미지는 여러 개의 읽기 전용 레이어로 구성되고 파일이 추가되면 새로운 레이어가 생성되어 추가된다.
도커는 여러 개의 레이어를 묶어 하나의 파일시스템으로 사용할 수 있게 해준다.

도커 이미지와 컨테이너의 차이

img1
쉽게말하면 도커이미지는 설계서, 컨테이너는 설계로 만들어진 상품이다.
그리고 이미지가 중간에 바꾸게 되더라도 기존 컨테이너는 더 이상 이미지에 영향을 받지 않는다.

컨테이너의 정의 및 특징

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

Docker와 VM의 차이

기존 가상화(VM)

가상화 이전에 시대에서는 하나의 서버에 하나의 어플리케이션만 구동시켰다고한다.
이렇다보니 하나의 서버에 남는 자원이 많았다. 이런 비효율성을 극복하기 위해 등장한 기술이 가상화 기술이다.
그 중 하이퍼바이저 기반의 가상화가 가장 많이 이용되었다.
하이퍼바이저는 논리적으로 분할된 공간에서 VM이라는 독립된 가상환경을 만들고 호스트 시스템에서 VM에 깔린 게스트OS를 구동 및 모니터링하는 역할을 한다.
논리적으로 구분된 공간에서 독립된 가상의 하드웨어를 할당 받은 VM들은 서로에게 어떤 영향도 미치지 않는다. 즉, 1개의 가상환경에서의 Error가 다른 가상환경에 영향을 미치지 않는다.

도커와의 차이

img2
간단히 말하자면 게스트OS의 유무라고 할 수 있다.
VM에는 위에서 언급한 GeustOS가 깔린다. 하지만 도커의 컨테이너는 그렇지 않다. 컨테이너에는 GuestOS르 설치하지 않는다.
이는 자원의 효율성 측면에서 차이가 난다. VM은 하나씩 늘 때마다 OS를 위한 자원을 할당해주어야하는 반면에 도커는 어플리케이션을 구동하는데 필요한 모든 패키지만 있으면 컨테이너를 구동시킬 수 있다.
img3
Docker는 그 자체로는 VM이기 때문에 하이퍼바이저를 포함하고 있는 실제 환경(PC)과 가상 환경(도커)의 관계에서는 GuestOS이고 도커와 컨테이너의 관계에서는 HostOS인 리눅스가 설치되어 있다.
해당 컨테이너에는 VMHost와는 달리 OS가 설치되어 있지 않다.

Docker 서버와 Docker Hub의 관계

img4
공식 Docker Registry는 Public Registry라고 하며, Public 외에 Private Registry를 만들어 운용하는 것도 가능하다.
이러한 저장소에 저장된 이미지를 docker서버로 다운로드 하는 것을 pulling이라고 하며, 반대로 자신이 만든 이미지를 Registry에 업로드하는 것을 Pushing이라고 한다.

도커 파일

Docker File은 이미지 생성 출발점으로 이미지를 구성하기 위한 명령어들을 작성하여 이미지를 구성할 수 있다.
다시 말해, 만들 이미지에 대한 정보를 기술한 템플릿이라고 보면 된다.
이를 빌드하면 자동으로 이미지가 생성된다. 그러므로 도커 파일을 통해 애플리케이션 빌드 및 배포를 자동화할 수 있다.

도커 파일 주요 명령

FROM

베이스 이미지 지정 명령
Dockerfile에서 반드시 있어야 하는 명령어이다.
도커는 계속해서 층으로 여러겹 이미지를 차곡차곡 쌓는 개념이다. 베이스 이미지란, 그 층 중에서 가장 밑바닥의 기본이 되는 이미지이고, FROM이 이미지를 지정해준다.

FROM pytorch/pytorch:1.12.0-cuda11.3-cudnn8-devel

LABEL

LABEL은 = 형식으로 메타 데이터를 넣을 수 있는 기능이다.
보통 저자, 버전, 설명, 작성일자 등을 각각 key로 정하고 그 오른쪽에 설명값을 넣는다.

LABEL maintainer="test@gamil.com"
LABEL version="1.0.0"
LABEL description="A Example of dockerfile"

CMD

해당 dockerfile로 만든 이미지를 기반으로 컨테이너를 만들었을 때, 해당 컨테이너가 실행될 때 가장 먼저 실행될 프로그램을 기술
CMD를 기술하는 방식은 크게 세가지이다.

  CMD ["python", "test.py", "-c"]
CMD python test.py -c 

CMD는 하나의 Dockerfile에서 한 가지만 설정되며, 만약 CMD 설정이 여러개일 경우, 맨 마지막에 설정된 CMD 설정만 적용됨.

COPY

호스트 PC의 파일들을 컨테이너로 복사를 할 수 있다.
왼쪽에 파일명 혹은 디렉토리명을 쓰거나 .을 쓰면 모든 파일을 의미하게 된다.
오른쪽에 옮겨질 컨테이너 내 디렉토리명이나 파일명을 써주면 된다.

COPY . /data

RUN

이 항목의 기능을 알기 위해서는 docker이미지의 구성방식을 알아야 한다.
RUN 명령은 이미지 생성 시, 일종의 layer를 만들 수 있는 단계로, 보통 베이스 이미지에 패키지(프로그램)을 추가로 설치하여 새로운 이미지를 만들 때 사용한다.
이렇게 한다면 특정 단계를 변경 할 때, 전체 이미지를 다시 다운로드 받는 번거로움을 해결할 수 있다.

RUN apt-get update
RUN python -m pip install --upgrade pip && \
    apt-get -y install libglib2.0-0 && \
    apt-get -y install libgl1-mesa-glx

ENTRYPOINT

만약 Dockerfile로 이미지를 만든 다음 컨테이너를 docker run으로 생성/실행하면서 명령문을 같이 적으며 실행한다면, 기존 이미지에 있던 CMD 명령이 터미널 명령으로 덮어씌워진다.
하지만, 이미지에 Entrypoint 항목이 있다면, docker run으로 명령을 실행 하더라도 Entrypoint의 명령에 영향을 끼치지 못하고, Entrypoint의 명령 뒤에 쭉 인자로 나열을 하게 된다.

ENTRYPOINT "/bin/sh"

EXPOSE

docker 컨테이너의 특정 포트를 외부에 오픈하는 설정이다.
docker run -p옵션과 유사하다. 차이점은 -p옵션은 컨테이너의 특정 포트를 외부에 오픈하고, 해당 포트를 호스트 PC의 특정 포트와 매핑시키는 것까지 알아서 해주지만, EXPOSE는 그냥 단순히 포트를 열어주기만 한다는 것이다.
결국 도커파일에 EXPOSE로 포트를 열어주었더라도, docker run을 할 때, p옵션을 쓰게된다.

ENV

컨테이너 내의 환경변수 설정
설정한 환경변수는 RUN, CMD, ENTRYPOINT 명령에도 적용된다.

ENV MYSQL_ROOT_PASSWORD=password # mysql 슈퍼관리자인 root ID에 대한 password란에 패스워드 설정하기
ENV MYSQL_DATABASE=dbname # DB 지정해주기
ENV MYSQL_USER=user
ENV MYSQL_PASSWORD=pw #mysql 추가 사용자 ID, 패스워드 설정

WORKDIR

이미지 내에서 특정 폴더로 이동하기 위해서 쓰는 명령

WORKDIR /data

작성한 dockerfile로 이미지 만들기

docker build --tag <이미지명> .

도커 주요 명령어

도커 run의 옵션

주요 옵션

옵션설명
-i —interactive컨테이너의 표준 입련(stdin)을 활성화. (주로 -it함께 사용)
-t -ttytty(가상 터미널)을 할당. 리눅스에 키보드를 통해 표준 입력(stdin)을 전달할 수 있게한다.(주로 -it함께 사용)
—name컨테이너 이름을 지정
-d —detach컨테이너를 백그라운드로 실행
—rmdocker run 명령어가 끝나면, 컨테이너 자동 삭제
-p —publish호스트와 컨테이너의 포트를 연결(포트포워딩) -p 호스트 포트:컨테이너 포트
-v —volume호스트와 컨테이너의 디렉토리 연결(마운트) -v 호스트 절대경로:컨테이너 절대경로
—restart컨테이너 종료 시, 재시작 정책 설정(—rm옵션과 같이 사용 불가능) —restart=“always”: 항상 재시작 —restart=“on-failure”: 종료 스테이터스가 0이 아닐 때 재시작
—privileged컨테이너 안에서 호스트의 리눅스 커널 기능을 모두 사용
-c —cpu-shares해당 컨테이너에 CPU자원 분배 설정. 기본값은 1024로 각 값은 상대적으로 적용
-m —memory컨테이너의 메모리 한계 설정. b, k, m, g단위 사용. (바이트 ,키로, 메가, 기가)
—gpus컨테이너가 호스트의 NVIDIA GPU를 사용할 수 있도록 설정. —gpus all: 호스트의 GPU모두 사용 —gpus “device=0,1”: 특정 GPU사용

Edit page
Share this post on:

Previous Post
wsl2와 도커 환경 구성하기
Next Post
소실점 검출 실험환경 재현하기