Cloud/k8s-CKAD

[CKAD] Dockerfile의 모든것

jinkwon.kim 2024. 1. 10. 23:18
728x90
반응형

개요

Dockerfile을 이용하여 할 수 있는 모든 것을 알아보겠습니다. 

Dockerfile이란?

container image를 만들기 위한 명령어들의 나열입니다.

Dockerfile의 구조

Dockerfile은 Docker 이미지를 만들기 위해 사용되는 텍스트 문서로, 이미지를 생성하기 위한 명령어들의 집합을 포함하고 있습니다. 구조는 다음과 같습니다:

필수

FROM

CMD or ENTRYPOINT

모든 설정

#FROM : 베이스 이미지를 지정합니다.
# 예를 들어, `FROM ubuntu:18.04`는 Ubuntu 18.04 이미지를 베이스로 사용하겠다는 것을 의미합니다.
FROM ubuntu:18.04

#LABEL : 이미지에 메타데이터를 추가합니다.
LABEL maintainer="name@example.com"

#ENV : 환경 변수를 설정합니다.
ENV PATH /usr/local/bin:$PATH

#RUN : 쉘 명령을 실행합니다.
RUN apt-get update && apt-get install -y package

#COPY : 파일이나 디렉토리를 이미지로 복사합니다.
COPY . /app

#ADD 파일을 이미지로 추가하고, 필요한 경우 압축을 해제합니다.
ADD archive.tar.gz /usr/src/app

#EXPOSE : 컨테이너가 리스닝할 포트를 지정합니다. 예: `EXPOSE 80`
#문서화 목적으로 사용되며, 실제로 포트를 공개하지는 않습니다.
EXPOSE 80

#VOLUME : 볼륨을 생성하거나 마운트합니다.
VOLUME ["/data"]

#WORKDIR : 작업 디렉토리(현재 디렉토리)를 설정합니다.
WORKDIR /path/to/workdir

#ENTRYPOINT : 컨테이너가 실행될 때 기본적으로 실행되는 명령을 설정합니다.
# docker run 시에 전달된 인자들이 ENTRYPOINT 명령의 인자로 추가되어 실행된다는 것입니다.
# 첫번재 인자는 실행 가능해야 합니다
ENTRYPOINT ["executable", "param1", "param2"]

#CMD : 컨테이너가 시작될 때 실행할 명령을 정의합니다.
#case 1) docker run 명령어를 통해 컨테이너를 시작할 때 제공되지 않은 경우에만 사용됩니다.
#        docker run <image> params 실행시 params는 CMD를 덮어 씁니다.
#case 2) CMD는 ENTRYPOINT 지시문과 함께 사용될 때, ENTRYPOINT에 의해 호출되는 명령에 대한 기본 인자를 제공합니다.
#case 3) docker run <image> param4를 실행하면, CMD에 정의된 pythonm, ./app.py 무시되고 executable param1 param4가 실행됩니다.
CMD ["python", "./app.py"]

#USER : 명령을 실행할 사용자 계정을 지정합니다.
USER myuser

#HEALTHCHECK : 컨테이너의 상태를 체크합니다.
#HEALTHCHECK [OPTIONS] CMD command
# [OPTIONS]
#--interval=DURATION (기본값: 30초) : 체크 사이의 대기 시간입니다.
#--timeout=DURATION (기본값: 30초) : 체크가 멈췄다고 간주하기 전까지의 대기 시간입니다.
#--start-period=DURATION (기본값: 0초) : 체크를 시작하기 전까지의 대기 시간입니다.
#--retries=N : 컨테이너를 비정상으로 간주하기 위해 필요한 연속 실패 횟수입니다.
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1

주의 사항 

container 안에서 실행되는 process는 foreground로 실행되게 해야 합니다. 

Docker container는 단일 process(일반적으로 foreground에서 실행)를 중심으로 설계되었으며, 이 process가 종료되면 container도 종료됩니다.

예제

nginx Dockerfile

# Nginx 공식 이미지를 기반으로 설정
FROM nginx:latest

# 기존의 Nginx 설정 파일을 제거
RUN rm /etc/nginx/conf.d/default.conf

# 로컬의 Nginx 설정 파일을 컨테이너에 복사
COPY custom-nginx.conf /etc/nginx/conf.d/

# 포트 80을 오픈 (Nginx 기본 HTTP 포트)
EXPOSE 80

# Nginx를 실행 (이 부분은 이미 Nginx 이미지에 포함되어 있으므로 생략 가능)
CMD ["nginx", "-g", "daemon off;"]

Data관리 방식

Docker에서 "volume"과 "bind mount"는 데이터를 컨테이너와 호스트 시스템 간에 저장하고 관리하는 두 가지 주요 방법입니다. 각각은 특정한 사용 사례와 장단점을 가지고 있습니다.

Docker Volume

Docker가 관리하는 호스트 파일 시스템의 일부입니다. 이는 Docker가 직접 관리하며, 일반적으로 호스트 시스템의 특정 위치보다는 논리적인 개념으로 취급됩니다.

용도

데이터 지속성과 공유를 위해 사용됩니다. 컨테이너가 삭제되더라도 볼륨에 저장된 데이터는 보존됩니다.

장점

이식성: 볼륨은 Docker에 의해 관리되므로, 다른 시스템에서 Docker 컨테이너를 쉽게 이동할 수 있습니다.

보안 : 볼륨은 호스트 파일 시스템과 분리되어 있어 컨테이너와 호스트 간의 직접적인 파일 시스템 액세스를 제한합니다.

백업과 마이그레이션 : Docker 볼륨은 백업 및 마이그레이션을 위해 쉽게 복사하거나 이동할 수 있습니다.

단점

호스트 파일 시스템의 특정 디렉토리나 파일에 직접 액세스 하는 것보다 관리가 복잡할 수 있습니다.

Bind Mount

호스트 시스템의 특정 파일이나 디렉토리를 컨테이너 내부에 직접 마운트 합니다. 이는 호스트 시스템의 파일 시스템 구조를 활용합니다.

용도

개발 환경에서 코드나 데이터를 컨테이너에 실시간으로 반영하기 위해 주로 사용됩니다.

장점

유연성 : 호스트 시스템의 특정 파일이나 디렉토리에 직접 액세스 할 수 있습니다.

실시간 업데이트: 호스트 시스템에서 파일을 변경하면 이 변경사항이 바로 컨테이너에 반영됩니다.

단점

이식성 문제: Bind mount는 호스트 시스템의 특정 경로에 의존하기 때문에 다른 호스트에서 동일한 경로 구조가 필요합니다.

보안 위험: 컨테이너가 호스트 시스템의 파일에 직접 액세스할 수 있어 보안상의 위험이 있을 수 있습니다.

결론

Volume은 데이터 지속성과 이식성을 위해, bind mount는 개발 과정에서의 편의성과 실시간 데이터 반영을 위해 사용됩니다. 사용 사례에 따라 적절한 방법을 선택하는 것이 중요합니다.

Data 공유 방식 

container간의 데이터를 공유하는 방식을 알아보겠습니다. 

절차

docker volume 생성

docker volume create shared_volume

container 실행 시 volume 할당

미리 만들어둔 shared_volume를 사용하여 container 간 volume을 공유합니다.

 

docker run -d --name container1 -v shared_volume:/path/in/container my_image
docker run -d --name container2 -v shared_volume:/path/in/container my_image

 

share_volume 대신 host의 경로를 사용하면 bind mount가 됩니다. 단 동일한 파일을 동시에 수정하면 데이터 충돌이 발생함으로 이를 유의해야 합니다.

Dockerfile 헷갈리는 사항 정리

CMD와 ENTRYPOINT 의 동작 차이

CMD

  • 기본 명령어 설정: CMD는 컨테이너가 실행될 때 기본적으로 실행할 명령어를 지정합니다.
  • 덮어쓰기 가능: 컨테이너를 실행할 때 추가적인 명령을 제공하면 CMD에서 설정한 명령은 무시되고 덮어씌워집니다.
  • 형식: CMD ["executable", "param1", "param2"] (exec 형식) 또는 CMD command param1 param2 (쉘 형식).
  •  
# CMD 예시
CMD ["echo", "Hello, World!"]
 

위의 예시에서 컨테이너가 실행되면 echo Hello, World!가 실행됩니다. 다만 docker run 시 다른 명령을 전달하면 그 명령이 실행됩니다.

ENTRYPOINT

  • 기본 실행 프로그램 지정: ENTRYPOINT는 컨테이너가 항상 실행할 프로그램을 설정합니다.
  • 덮어쓰기 어려움: ENTRYPOINT로 설정한 명령어는 쉽게 덮어쓸 수 없습니다. 다만, 추가 인자를 제공해 명령의 인수로 전달할 수 있습니다.
  • 형식: ENTRYPOINT ["executable", "param1", "param2"] (exec 형식) 또는 ENTRYPOINT command param1 param2 (쉘 형식).
 

CMD와 ENTRYPOINT 같이 있을때

ENTRYPOINT가 우선적으로 실행되고, CMD는 ENTRYPOINT의 인수로 전달됩니다.

 

정리

dockerfile은 container image를 만드는 파일입니다.

container의 데이터를 저장 및 contaner 간 데이터 공유 위해서는 volume 또는 bind mount를 사용합니다.

 

728x90
반응형