인프런

이미지 빌드

date
Apr 3, 2024
slug
개발자를-위한-쉬운-도커-4
status
Public
tags
개발자를 위한 쉬운 도커
author
summary
[개발자를 위한 쉬운 도커] 강의 정리
type
Post
thumbnail
updatedAt
May 28, 2024 12:34 PM
category
인프런

💻 명령어


  • docker image history 이미지명
  • docker image inspect 이미지명 : 이미지의 메타 데이터 정보
    • → RootFS.Layers값이 이미지 레이어의 ID이다
  • docker run -it --name 컨테이너명 이미지명 bin/bash
    • → 컨테이너 실행과 동시에 터미널 접속
  • docker commit -m 커밋명 실행중인 컨테이너명 생성할 이미지명
  • docker push 레지스트리명/이미지명
  • docker build -t 레지스트리명/이미지명 Dockerfile경로
    • -f :도커파일명( 도커파일명이 Dockerfile이 아닌 경우 선언 )
    • -t : 이미지명
  • docker exec -it 컨테이너명 sh : 실행중인 컨테이너 쉘 접속
 

📝 강의 정리


[1]. 이미지와 레이어


💡 이미지는 왜 레이어드 구조를 가질까?

💡
레이어 방식은 중복 데이터를 최소화하고, 빌드 속도를 높이며, 저장소를 효율적으로 사용할 수 있게 해준다.
이미지의 레이어 구조는 재활용에 유리
  • 건물 설계도에 비유
  • 하나의 건물은 조경, 전기, 토목, 구조와 같은 분류로 나뉜 여러개의 설계도로 구성
    • → 조경 부분에 변경이 있을 경우, 조경 설계도만 수정하면 된다.
      notion image
  • 효율적인 데이터 저장과 전송
  • 이미지에서 한번 저장된 레이어는 변경할 수 없다
    • → 따라서, 변경사항이 있다면 새로운 레이어로 저장한다. ( ex, git push )
 

[1-1]. 이미지 레이어와 컨테이너 레이어

notion image
  • 이미지 레이어
    • → 컨테이너를 실행하기 위한 세이브 포인트 역할
  • 컨테이너 레이어
    • → 실제로 이 이미지를 컨테이너로 실행한 후, 프로세스가 변경한 내역을 기록
    • 복수의 컨테이너가 동일한 이미지를 사용 시, 읽기 전용 레이어를 공유한다.

💡 동일한 이미지 레이어를 사용한다면, 이미지 ID도 같은 것을 확인할 수 있다.

notion image
  • 이미지의 내용이 같더라도, 구성한 순서가 다르다면 다른 이미지 ID 값을 가진다.
 

[1-2]. Cow 전략 ( Copy-on-Write )

  • 다음 레이어에서 이전 레이어의 특정 파일을 수정할 때,
    • → 해당 파일의 복사본을 만들어 변경 사항을 적용한다. ( 컨테이너 레이어 )
       

[1-3]. Immutable Layers( 불변 레이어 )

  • 이미지의 각 레이어는 불변해야 한다.
    • 이미지의 일관성을 유지하고, 여러 컨테이너에서 안전하게 공유
  • 따라서, Cow전략을 통해 원본 이미지의 일관성을 유지한다.
 

[1-4]. Caching( 캐싱 )

  • 레이어를 캐시하여, 이미 빌드된 레이어를 재사용할 수 있다.
    • → 이미지 빌드 시간을 크게 줄여준다.
      → 같은 레이어를 사용하는 여러 이미지에서 효유적으로 작동한다.
 

[2]. 이미지 커밋


이미지 생성 방법
  • 이미지 커밋 : 현재 컨테이너의 상태를 이미지로 저장
  • 이미지 빌드 : Dockerfile을 통해 이미지를 저장
→ 대부분 이미지 빌드 방식을 사용하지만, 빌드 방식 또한 커밋을 기반으로 동작
 

[2-1]. 이미지 커밋

  1. 이미지를 컨테이너로 실행
  1. 컨테이너의 내부 파일 변경
  1. commit을 통해 새로운 이미지로 저장
 
❗️이미지 커밋 방식의 문제점
  • 이미지를 생성할 때마다 컨테이너를 실행해야 하고, 사용자가 명령어를 입력해야 한다.
  • 커밋 하나당 이미지의 레이어가 추가된다. 여러 번의 커밋이 요구됨
→ 휴먼 에러 가능성 ⬆️
 

[2-2]. 이미지 빌드


  • IaC( Infrastructure as Code ) : 인프라 상태를 코드로 관리
    • → 현대 인프라 구성에서 중요한 개념
 

Dockerfile


# 베이스 이미지를 지정 FROM 이미지명 # 빌드컨텍스트의 파일을 레이어에 복사 # + (cp) 새로운 레이어 추가 COPY 빌드컨텍스트경로 레이어경로 # 명령어 실행 # + 새로운 레이어 추가 RUN 명령어 # 컨테이너 실행 시 명령어 지정 # 해당 명령어는 메타데이터의 cmd 필드에 저장됨. CMD ["명령어"] ======================================== 시스템 관련 지시어 # 작업 디렉터리를 지정 # + 새로운 레이어 추가 WORKDIR 폴더명 # 명령을 실행할 사용자 변경 # + 새로운 레이어 추가 USER 유저명 # 컨테이너가 사용할 포트를 명시 EXPOSE 포트번호 ======================================== # 이미지 빌드 시점의 환경 변수 설정 # docker build --build-arg 변수명=변수값으로 빌드 시 덮어쓰여짐 ARG 변수명 변수값 # 이미지 빌드 및 컨테이너 실행 시점의 환경 변수 설정 # docker build -e 변수명=변수값으로 덮어쓰여짐 # + 새로운 레이어 추가 ENV 변수명 변수값 ======================================== # 고정된 명령어를 지정 ENTRYPOINT ["명령어"] # 컨테이너 실행 시 실행 명령어 지정 # docker run ~~~ 명령어2로 할시 명령어2로 덮어 쓰여짐 CMD ["명령어"]
  • 레이어가 추가되는 경우
    • 파일 시스템의 내용을 변경하는 경우
  • 레이어가 추가되지 않는 경우
    • 메타데이터에만 영향을 주는 경우

[3]. 빌드 컨텍스트 ( Build Context )


💡
빌드 시 사용되는 디렉터리
docker build -t 생성할 이미지명 빌드 컨텍스트 동작 과정
  1. 빌드 명령 시, 도커 데몬에 빌드 컨텍스트 전달
  1. 빌드 컨텍스트의 Dockerfile로 빌드 시작
    1. FROM 지시어의 베이스 이미지로 임시 컨테이너 생성
  1. COPY 지시어를 통해 빌드 컨텍스트 내의 파일을 빌드 컨테이너의 경로로 복사 → 빌드 컨텍스트에 있는 파일만 COPY 가능

    .dockerignore

    • .dockerignore 파일을 통해 빌드 컨텍스트의 파일을 관리할 수 있다.
      • → 해당 파일 내의 파일은 도커데몬에게 전달되지 않는다.
        notion image
     

    [4]. Dockerfile 지시어


    [4-1]. 시스템 관련 지시어


    USER 유저명
    • 도커 컨테이너가 실행될 때 기본적으로 ROOT 권한을 가진다.
      • → 따라서, 컨테이너가 필요 이상의 권한을 가지지 않도록 하자.
     
    EXPOSE 포트번호
    • EXPOSE 지시어 없이도 컨테이너가 모든 포트를 사용할 수 있지만,
      • EXPOSE를 선언해주면 다른 작업자가 해당 애플리케이션이 사용하는 포트를 한눈에 볼 수 있게 해준다.
     
    WORKDIR 폴더명
    • cd와 비슷한 지시어
    • 지시어의 기본 위치가 WORKDIR로 설정한 위치에서 실행
    • 이후에 지시어에 영향을 끼치므로 가능한 FROM 지시어 다음에 사용하는 것이 좋다.
     
    WORKDIR 지정하지 않은 경우
    notion image
    • 루트 디렉터리(’/’)에 빌드 컨텍스트 내 파일들이 복사된 것을 확인
     
    WORKDIR /app 지정한 경우
    notion image
    notion image
    • 루트 디렉터리에 app 디렉터리가 생기고, 그 안에 빌드 컨텍스트 파일들이 복사된 것을 확인
     

    [4-2]. 환경 변수 지시어


    ✅ 특수한 경우를 제외하고는 ENV 를 사용하면 됨. (상황에 맞게)
    ARG 변수명=변수값
    💡
    ARG는 빌드에만 사용할 환경 변수 지정시 사용
    • ARG로 적용된 값을 컨테이너로 실행할 때는 적용 되지 않기 떄문에 애플리케이션의 기본 값인 초록색이 적용
      • notion image
     
    ENV 변수명=변수값
    💡
    애플리케이션 실행 시 참고할 용도로 사용
    • ENV로 적용된 값은 애플리케이션 실행 시 ENV값이 참고되므로 빨간색이 적용된 것을 확인
      • notion image

    [4-3]. 프로세스 실행 지시어


    ENTRYPOINT [”명령어”]
    • 컨테이너 실행 시 기본적으로 붙여줄 명령어를 지정해줄 수 있다
      • → ENTRYPOINT [”npm”] 을 설정하게 되면, 실행시 npm이 자동적으로 설정됨
     
    CMD [”명령어”]
    • 컨테이너 실행 시 실행할 명령어 지정
      • → docker run 시 cmd가 없을 때 기본값, 있다면 덮어 쓰여짐
         
     

    [5]. 멀티 스테이지 빌드( Multi-Stage build )


    💡
    도커 파일에서 두 개의 베이스 이미지를 활용하는 방법
    • 빌드에 사용하는 이미지와 실행에 사용되는 이미지로 나누는 방법
      • 애플리케이션 빌드 과정에서 만들어지는 파일이 용량을 많이 차지
        • → 따라서 애플리케이션이 실행되는 이미지의 크기를 줄일 수 있다
     

    [5-1]. single stage build

    • 실행단계에 불필요한 소스코드, 라이브러리, 실행파일 등이 포함되어 있어
      • 이미지가 무거워진다.
         
    • 빌드시간
      • notion image
         
        notion image
         
        notion image

    📎 출처