Post

도커 이미지와 Dockerfile 작성 방법

도커 이미지의 구조, Dockerfile 인스트럭션, 이미지 빌드와 레이어 캐시 관리

도커 이미지와 Dockerfile 작성 방법

1. 도커 허브와 이미지

  • 이미지를 내려받는 과정을 도커에 전적으로 맡길 수도 있지만, 도커 CLI를 통해 명시적으로 원하는 이미지를 내려받을 수도 있다
    1
    
    docker image pull diamol/ch03-web-ping
    
  • 이미지를 제공하는 저장소는 레지스트리(registry)라고 한다
  • 도커 허브는 무료로 제공되는 공개 레지스트리로 도커가 이미지를 찾기 위해 가장 먼저 접근하는 저장소이다
  • 이미지 레이어
    • 도커 이미지는 물리적으로는 여러 개의 작은 파일로 구성돼 있다
    • 도커는 이들 파일을 조립해 컨테이너의 내부 파일 시스템을 만든다
    • 모든 레이어를 내려받고 나면 전체 이미지를 사용할 수 있다
  • 컨테이너 실행 시 이름 지정
    1
    
    docker container run -d --name web-ping diamol/ch03-web-ping
    
    • -d 플래그는 –detach의 축약형으로 백그라운드 실행
    • –name 플래그는 컨테이너에 원하는 이름을 지정할 수 있는 플래그
  • 컨테이너 실행 시 환경 변수 지정
    1
    
    docker container run --env TARGET=google.com diamol/ch03-web-ping
    
    • –env 플래그로 환경 변수를 지정할 수 있다
    • 위 컨테이너는 –detach를 적용하지 않았으므로 애플리케이션의 출력 내용이 콘솔에 나타난다
    • 호스트 컴퓨터에도 고유의 환경 변수가 있다. 그러나 호스트 컴퓨터의 환경 변수를 컨테이너와는 별개다. 컨테이너는 도커가 부여한 환경 변수만을 갖는다



2. Dockerfile

  • Dockerfile은 애플리케이션을 패키징하기 위한 스크립트
  • Dockerfile은 일련의 인스트럭션으로 구성돼 있는데, 인스트럭션을 실행한 결과로 도커 이미지가 만들어진다
  • 표준 셸 문법도 사용 가능하다
  • 인스트럭션 (대/소문자 구분 없음)
    • FROM: 시작점이 되는 이미지 지정
    • ENV: 환경 변수 값을 지정하기 위한 인스트럭션. 값을 지정하기 위해 key="[value]" 형식을 따른다
    • WORKDIR: 컨테이너 이미지 파일 시스템에 디렉터리를 만들고, 해당 디렉터리를 작업 디렉터리로 지정하는 인스트럭션이다. 리눅스와 윈도우 컨테이너 모두 구분자로 슬래시를 사용한다
    • COPY: 로컬 파일 시스템의 파일 혹은 디렉터리를 컨테이너 이미지로 복사하는 인스트럭션이다. [원본 경로] [복사 경로] 형식으로 지정하면 된다
      1
      
      COPY app.js .
      
      • 로컬 파일 시스템이 있는 app.js 파일을 이미지의 작업 디렉터리로 복사
    • CMD: 도커가 이미지로부터 컨테이너를 실행했을 때 실행할 명령을 지정하는 인스트럭션



3. 컨테이너 이미지 빌드

  • 이미지를 빌드하기 위해선 Dockerfile 스크립트 외에 이미지의 이름, 패키징에 필요한 파일 경로를 추가로 지정해줘야 한다
  • Dockerfile 스크립트로 이미지 빌드
    1
    
    docker image build --tag web-ping .
    
    • --tag web-ping
      • 이미지의 이름을 web-ping으로 지정
    • .
      • 디렉터리 컨텍스트로 Dockerfile 및 이미지에 포함시킬 파일이 위치한 경로
      • .은 현재 작업 디렉터리를 의미
  • ‘w’로 시작하는 태그명을 가진 이미지 목록 확인
    1
    
    docker image ls 'w*'
    



4. 도커 이미지와 이미지 레이어 이해

  • 도커 이미지에는 패키징에 포함시킨 모든 파일이 들어 있다. 이들 파일은 나중에 컨테이너의 파일 시스템을 형성
  • 도커 이미지에는 자신에 대한 여러 메타데이터 정보도 들어 있다. 이 정보 중에는 이미지가 어떻게 빌드됐는지에 대한 간단한 이력도 포함된다. 이 정보를 이용하면 이미지를 구성하는 각 레이어는 무엇이고 이들 레이어가 어떤 명령으로 빌드됐는지 알 수 있다.
  • 이미지 히스토리 확인하기
    1
    
    docker image history web-ping
    
    • web-ping 이미지의 히스토리 확인
    • 위 명령을 입력하면 한 줄마다 한 레이어에 대한 정보가 출력된다
    • 이미지 히스토리 중 CREATED BY 항목은 해당 레이어를 구성한 Dockerfile 스크립트의 인스트럭션이다
    • Dockerfile 인스트럭션과 이미지 레이어는 1:1 관계를 갖는다
  • 도커 이미지는 이미지 레이어가 모인 논리적 대상이다. 레이어는 도커 엔진의 캐시에 물리적으로 저장된 파일이다
  • 이미지 레이어는 여러 이미지와 컨테이너에서 공유된다. 만약 Node.js 애플리케이션이 실행되는 컨테이너를 여러 개 실행한다면 이들 컨테이너는 모두 Node.js 런타임이 들어 있는 이미지 레이어를 공유한다
  • 이미지 목록에서 각 이미지의 용량 확인하기
    1
    
    docker image ls
    
    • 이미지 목록에 SIZE 항목에 나오는 수치는 이미지의 논리적 용량이지 해당 이미지가 실제로 차지하는 디스크 용량을 나타내는 것이 아니다
    • 다른 이미지와 레이어를 공유하면 조회 시 나온 수치보다 디스크 용량을 훨씬 덜 차지한다
  • 이미지 저장에 실제 사용된 디스크 용량 조회
    1
    
    docker system df
    
  • 이미지 레이어 관리
    • 이미지 레이어 수정이 다른 이미지에 영향을 미치는 것을 방지하기 위해 이미지 레이어는 읽기 전용으로 관리
  • 이미지 레이어 캐시
    • Dockerfile 스크립트의 인스트럭션은 각각 하나의 이미지 레이어와 1:1로 연결
    • 인스트럭션의 결과가 이전 빌드와 같다면, 이전에 캐시된 레이어를 재사용
    • 도커는 캐시에 일치하는 레이어가 있는지 확인하기 위해 해시값을 이용
    • 해시값은 Dockerfile 스크립트의 인스트럭션과 인스트럭션에 의해 복사되는 파일의 내용으로부터 계산
    • 기존 이미지 레이어에 해시값이 일치하는 것이 없다면 캐시 미스가 발생하고 해당 인스트럭션이 실행
    • 한번 인스트럭션이 실행되면 그다음에 오는 인스트럭션은 수정된 것이 없더라도 모두 실행
  • Dockerfile 스크립트의 인스트럭션은 잘 수정하지 않는 인스트럭션이 앞으로 오고 자주 수정되는 인스트럭션이 뒤에 오도록 배치해야 캐시에 저장된 이미지 레이어를 되도록 많이 재사용할 수 있다.
This post is licensed under CC BY 4.0 by the author.