티스토리 뷰

반응형

Docker 컨테이너내에 구성요소들이 적용될수있는 이유는?

Dockerfile을 통해 구성요소들을 설정해 준다.

 

* Dockerfile 내용

FROM adptopenjdk:8-jdk-hotspot AS builder #베이스이미지+별칭
COPY gradlew . #gradlew 복사
COPY gradle gradle #gradle 복사
COPY build.grade . #build.gradle 복사
COPY settings.gradle #settings.gradle 복사
COPY src src #웹 어플리케이션 소스 복사
RUN chmod +x ./gradlew #gradlew 실행권한 부여
RUN ./gradlew bootJar #gradlew를 사용하여 실행 가능한 jar 파일 생성

FROM adoptopenjdk:8-jdk-hotspot #베이스 이미지
COPY --from=builder build/libs/*/jar app.jar #builder 이미지에서 build/libs/*.jar 파일을 app.jar로 복사

EXPOSE 8080 #컨테이너 Port 노출
ENTRYPOINT ["java","-jar","/app.jar"] #jar 파일 실행

 

 

질문 1. gradlew이란?

gradle wrapper의 줄임말로 프로젝트에 gradle을 설치할 필요없이 어디서나 동일한 버전의 gradle을 사용하게 해준다.

gradlew를 사용하면 gradle이 사전에 설치되어있지 않아도 된다. gradlew 스크립트가 필요한 gradle버전을 자동으로 다운로드/실행한다. 

 

질문 1-1. 왜 RUN chmod +x ./gradlew를 해주는가?

- 리눅스 or macOS에서 스크립트 파일을 실행하려면, 해당 파일의 실행권한이 필요함.

- 소스코드를 Docker 컨테이너로 복사시 파일 권한이 유지되지 않을 수 있어 Dockerfile에 명시적으로 실행 권한 부여

 

질문2. 이 코드는 멀티-스테이지 이다. 어떻게 알아볼수있는가?

- FROM 명령어가 두번 사용됨 (첫번째 FROM : 빌드과정에 사용될 베이스 이미지 정하고 builder라는 별명 붙임, 두번째 FROM : 최종이미지에 사용될 베이스 이미지를 지정-> application을 실행하는데 필요한 환경만을 포함)

# Use multi-stage builds
# syntax=docker/dockerfile:1
FROM golang:1.21
WORKDIR /src
COPY <<EOF ./main.go
package main

import "fmt"

func main() {
  fmt.Println("hello, world")
}
EOF
RUN go build -o /bin/hello ./main.go

FROM scratch
COPY --from=0 /bin/hello /bin/hello
CMD ["/bin/hello"]

 

- "COPY --from=builder build/libs/*/jar app.jar"를 통해 첫번째 스테이지('builder')에서 생성된 파일(JAR 파일)을 두번째 스테이지로 복사함을 통해 알 수 있다.

 

질문 2-1. 멀티-스테이지 빌드의 장점은?

- Generated images are smaller : 최종 이미지가 일반적으로 일반 빌드에서 생성된 이미지보다 훨씬 작다. (결과 이미지에는 application에 필요한 내용만 포함되지 때문)

- Faster deployment: 이미지가 작을수록 전송시간, CI/CD 빌드 속도가 빨라지고, 배포시간이 빨라지며 성능이 향상된다.

 

질문 2-1-1. 그렇게 좋다면 멀티-스테이지 빌드를 모든 dockerfile에서 사용해야 하는거 아닌가?

- 멀티-스테이지 빌드를 사용 O

  • 대규모 또는 복잡한 어플리케이션 : 컴파일이 필요한 언어(Java,C++,Go)를 사용하는 대규모 어플리케이션의 경우 빌드 도구와 런타임 환경을 분리하는것이 좋다.
  • 최적화된 이미지 크기 : 빌드 과정에서 생성되는 임시 파일,도구를 최종이미지에 제거하여 이미지 크기르르 줄이고 싶을때 유용하다. 
  • 기본 이미지 빌드 후 이미지 크기 확인하여 예상보다 클경우 멀티-스테이지 빌드 적용을 고민한다.

 

- 멀티-스테이지 빌드를 사용 X

  • 단순한 어플리케이션, 작은 규모의 이미지 : 사용하는 언어나 프레임 워크가 이미 최소화된 이미지 크기를 제공시

질문 2-1-2. 컴파일이 필요한 언어의 경우 멀티-스테이지 빌드를 사용 O라고 했는데 파이썬은은 그럼 멀티-스테이지 빌드를 사용 X인가?

- 파이썬은 인터프리터 언어(컴파일 과정없이 실행 시간에 직접 해석되어 실행)

- 파이썬은 간단한 빌드과정 즉 소스코드가 직접 실행되므로 복잡한 빌드과정이 필요하지 않아 대부분 소스코드와 필요한 외부 라이브러리를 이미지에 복사하는 것만으로 충분하다.

예외) 파이썬 프로젝트에서 C/C++로 작성된 네이티브 확장 모듈을 컴파일해야 하는 경우

 

크기,상황 에 따라 다른것 같음(구글링시에 찬반의견보단 어떻게 python을 multi-staging build하냐 라는 글들만 있음)

사용 예시 : https://blog.annotation-ai.com/python-docker-img-optimization/

FROM python:3.8-alpine AS builder

RUN apk update && apk add --no-cache make && apk add --no-cache libpq-dev g++

WORKDIR /app
COPY requirements* ./
RUN pip install --no-cache-dir -r requirements-prod.txt
COPY Makefile . 
COPY src ./src


FROM python:3.8-alpine AS deployer
COPY --from=builder /usr/local/lib/python3.8/site-packages /usr/local/lib/python3.8/site-packages
COPY --from=builder /app /app
RUN apk update && apk add --no-cache make
WORKDIR /app

CMD ["make", "run-server"]

 

 

 

 

질문 2-2. 위의 java dockerfile의 경우 왜 멀티-스테이지를 사용하는가? 각 필요파일을 복사해서 jar파일 만들고 그걸 다시 복사하는건데.

- 불필요한 파일 제거

첫번째 스테이지에서 최종 실행 이미지에 필요없는 것들이 만들어진다. 

ex. 소스코드 : 빌드를 위해 필요하지만, 실행파일이 생성되면 필요없음

      빌드파일 : gradlew,gradle 등 빌드과정을 자동화하는 스크립트,설정파일은 빌드후에는 필요없음

      중간 생성파일: 컴파일 과정에서 생성되는 클래스,로그 파일등은 필요없음

 

질문 2-2-1. 그럼 'adoptopenjdk:8-jdk-hotspot'를 왜 또하는가?

java application을 실행하는데 필요한 최소한의 java 라이브러리와 도구들이 포함된다.

 

 

* Dockerfile build

docker build -t deploy-test:0.0.1

 

 

 

 

* Dockerfile 실행

docker run -d -p 8080:8080 deploy-test:0.0.1

 

-python 위의 코드의 경우 (my-running-app : Docker 컨테이너의 이름)

docker run -d --name my-running-app deploy-test:0.0.1

 

 

참고자료

https://docs.docker.com/guides/walkthroughs/what-is-a-container/#what-is-a-container

https://docs.docker.com/config/containers/runmetrics/

https://www.netapp.com/devops-solutions/what-are-containers/

https://www.linkedin.com/pulse/cgroups-docker-pavan-shukla/

https://inma.tistory.com/148

https://docs.docker.com/build/building/multi-stage/

https://www.cherryservers.com/blog/docker-multistage-build

https://blog.annotation-ai.com/python-docker-img-optimization/

https://www.vantage-ai.com/vantage101/chapter-9-docker

https://kimjingo.tistory.com/38

https://medium.com/echo-devblog/%EB%8F%84%EC%BB%A4%EB%A5%BC-%EB%8F%84%EC%9E%85%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0-1-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EA%B8%B0%EC%88%A0-%EC%9B%90%EB%A6%AC-90a28c14024e

https://stackoverflow.com/questions/51765555/what-namespaces-are-shared-among-containers-in-a-kubernetes-pod

https://platform.sh/blog/the-container-is-a-lie/

반응형

'DOCKER' 카테고리의 다른 글

[DOCKER] Docker Compose  (0) 2024.01.08
[Docker] Docker Volume  (2) 2024.01.02
[Docker] Docker 최적화  (0) 2023.12.28
[Docker] Docker Image  (0) 2023.12.26
[Docker] Docker Container1 - 기본 개념  (0) 2023.12.21
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함