- 이 내용은
컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커
책을 ref 합니다
[ 개요 ]
- 이 포스팅에서는 SpringBoot 애플리케이션을
컨테이너 이미지
로 만들고 실행
하는 과정까지 정리
- 직접 만든 애플리케이션을 이미지(
Docker Image
)로 만들기 위한 5가지 방법이 존재
- 기본 방법
- 컨테이너 용량 줄인 방법
- 컨테이너 내부에서 빌드하는 방법
- 멀티 스테이지 빌드(
Multi-Stage Build
)
- (추가)
docker 계층화
방법
[ 기본 방법 ]
순서
- 동작 순서
- 호스트에서 SpringBoot 빌드를 위한 Java 설치 (OpenJDK)
- Maven(빌드 툴)을 이용해서 실행 가능한 JAR 생성
- Dockerfile 실행
- 만든 Docker Image 실행
1. 호스트에 Java 설치
$ yum install java-1.8.0-openjdk-devel -y
2. 실행 가능한 JAR 생성
$ chmod 700 mvnw
$ ./mvnw clean package
3. Dockerfile 실행
- Dockerfile 실행
- docker build의 -t 옵션 :
<저장소 이름>/<이미지 이름>:<태그>
형태로 태그를 지정할 수 있는 옵션
- 추가적으로,
같은 이미지
로 만들 경우 하나의 공간
을 사용
하기 때문에 용량
이 모두 같다
- 그리고 Docker는
캐시(Cache)
시스템이 있어서 변경사항이 아닌 부분
은 Cache
되어 빠르게 빌드
$ docker build -t basic-img:1.0 .
FROM openjdk:8
LABEL description="Echo IP Java Application"
EXPOSE 60431
COPY ./target/app-in-host.jar /opt/app-in-image.jar
WORKDIR /opt
ENTRYPOINT [ "java", "-jar", "app-in-image.jar" ]
4. Docker Image 실행
$ docker run -d -p 60431:80 --name basic-run --restart always basic-img
- docker run 옵션
- -d : 데몬으로 실행. 즉, 백그라운드로 실행
- -p : 호스트의 60431 포트를 컨테이너의 80번 포트로 포트포워딩
- --name : 컨테이너의 이름 지정
- --restart : 컨테이너의 문제로 인해 재시작 되는 방법 지정
[ 컨테이너 용량 줄인 방법 ]
순서
- 동작 순서
- 호스트에서 SpringBoot 빌드를 위한 Java 설치 (OpenJDK)
- Maven(빌드 툴)을 이용해서 실행 가능한 JAR 생성
- Dockerfile 실행
gcr.io/distroless/java:8
설치 - Java 실행을 위한 가벼운 이미지
- JAR 실행
- 만든 Docker Image 실행
기본 방법과 차이점
Dockerfile 내용
의 일부분 빼고는 기본 방법
과 동일
Dockerfile
의 FROM
에서 openjdk8
대신 경량화 Java 이미지
가져오기
FROM gcr.io/distroless/java:8
LABEL description="Echo IP Java Application"
EXPOSE 60431
COPY ./target/app-in-host.jar /opt/app-in-image.jar
WORKDIR /opt
ENTRYPOINT [ "java", "-jar", "app-in-image.jar" ]
[ 컨테이너 내부에서 빌드하는 방법 ]
순서
- 핵심
호스트에서 java를 설치
& 실행 가능한 JAR를 만드는 과정
=> 컨테이너 내부에서 실행
- 동작 순서
- Dockerfile 실행
- openjdk8 설치
- git에서 springboot 소스 가져오기
- 실행 가능한 JAR 생성
- JAR 실행
- 만든 Docker Image 실행
1. Dockerfile 실행
FROM openjdk:8
LABEL description="Echo IP Java Application"
EXPOSE 60433
RUN git clone https://github.com/iac-source/inbuilder.git
WORKDIR inbuilder
RUN chmod 700 mvnw
RUN ./mvnw clean package
RUN mv target/app-in-host.jar /opt/app-in-image.jar
WORKDIR /opt
ENTRYPOINT [ "java", "-jar", "app-in-image.jar" ]
- 결과
컨테이너 내부
에서 프로젝트 빌드 실행
-> 앞선 방법보다 매우 편해졌다. 하지만, 용량이 크다
-> 왜냐하면, 프로젝트 빌드 과정중에 나온 중간 파일
들 모두 최종 이미지에 포함
되기 때문!
=> 멀티 스테이지 빌드
방법으로 이 단점을 개선 가능!
- 이미지 크기 증가
2. Docker Image 실행
$ docker run -d -p 60431:80 --name basic-run --restart always basic-img
[ 멀티 스테이지 빌드 ]
순서
- 동작 순서
- Dockerfile 실행
[image 1]
- openjdk8 설치
- git에서 springboot 소스 가져오기
- 실행 가능한 JAR 생성
[image 2]
gcr.io/distroless/java:8
설치 - Java 실행을 위한 가벼운 이미지
- 실행 가능한 JAR 파일을 최종
/opt
아래에 app-in-image.jar
로 저장
- JAR 실행
- 만든 Docker Image 실행
- 핵심
실행 가능한 JAR
로 만드는 프로젝트 빌드 과정
을 별도의 이미지
에서 수행
생성된 실행 가능한 JAR 파일
을 실제 컨테이너 이미지
에 포함
(기존 프로젝트 빌더용 이미지
는 삭제
해 주어야 한다)
1. Dockerfile 실행
FROM openjdk:8 AS int-build
LABEL description="Java Application builder"
RUN git clone https://github.com/iac-source/inbuilder.git
WORKDIR inbuilder
RUN chmod 700 mvnw
RUN ./mvnw clean package
FROM gcr.io/distroless/java:8
LABEL description="Echo IP Java Application"
EXPOSE 60434
COPY --from=int-build inbuilder/target/app-in-host.jar /opt/app-in-image.jar
WORKDIR /opt
ENTRYPOINT [ "java", "-jar", "app-in-image.jar" ]
- 결과
프로젝트 빌드용 이미지
에서 만든 JAR파일을 실제 사용할 경량화 이미지
에 복사
-> 결국 최종 이미지
는 크기가 작다
- 추가
- 프로젝트 빌드 목적으로 사용한 Docker Image은 댕글링 이미지로 생성된다
(댕글링 이미지 : 이름이 없는 이미지, 이름이 <none>
으로 표시)
- 댕글링 이미지 삭제
$ docker rmi $(docker images -f dangling=true -q)
2. Docker Image 실행
$ docker run -d -p 60431:80 --name basic-run --restart always basic-img
[ Docker 계층화 ]
- 아마, 대부분 앞에
multi-state build
형식을 많이 사용할 것이다
Docker의 계층화
& 캐시
특징으로 변경된 계층만 빌드
하는 효율적인 방법이 있다
- 빌드 툴(
gradlw
, maven
) 을 통한 계층형 JAR
생성
Docker Cache
를 통해서 변경된 부분
만 build