본문 바로가기

DevOps/도커(Docker)

도커 컨테이너 이미지 만들기 1 - 기본 방법으로 빌드하기

직접 컨테이너 이미지를 만들어 쿠버네티스에서 사용하는 방법

컨테이너 인프라 환경을 구성할 때 이미 제공된 이미지를 사용하는 경우도 있지만, 직접 만든 애플리캐이션으로 컨테이너를 만들 수 있다. 책에서 제공하는 소스코드로 자바 실행파일을 빌드하고 이를 다시 도커빌드를 사용해 컨테이너 이미지를 만든다.

 

기본적인 빌드 > 용량 줄이기 > 컨테이너 내부 빌드 > 멀티 스테이지

 

# 기본 방법으로 빌드하기

컨테이너 이미지를 만드는 방법은 다양하지만, 가장 간단한 방법부터 살펴보자. 스프링 부트(Spring Boot)를 이용해 만든 자바 소스 코드로 이미지를 빌드한다. 해당 소스 코드는 요청을 전달하면 출발지와 목적지를 반환하는 간단한 기능만 제공한다.

 

# 컨테이너 이미지 빌드 과정
자바 소스 빌드 > 도커파일 작성 > 도커파일 빌드 > 빌드 완료

 

1. 자바 개발 도구 설치

# 자바 개발도구 설치
$ sudo apt install openjdk-8-jdk

# 자바 버전 확인
$ java -version

소스코드가 자바로 작성돼 있으므로 실행 가능한 바이너리(JAR, Java Archive)로 만들려면 현재 시스템에 자바 개발 도구(JDK, Java Development Kit)를 설치해야한다.

 

 

 

2. 메이븐 실행

$ chmod 700 mvnw
$ ./mvnw clean package

자바를 빌드할 때 메이븐(Maven)을 사용한다. 메이븐은 빌드를 위한 의존성과 여러가지 설정을 자동화 하는 도구이다. 메이븐은 mvnw clean package 명령으로 실행한다. 이 명령은 빌드를 진행할 디렉터리를 비우고(clean) JAR(package)를 생성하라는 의미이다.

 

 

 

3. JAR 파일 확인

$ ls target

자바 빌드가 끝나면 생성된 JAR파일(app-in-host.jar)을 확인한다. JAR 파일은 target 디렉터리에 있다. app-in-host.jar.original은 JAR 파일 생성 단계에서 나오는 임시파일이다.

 

 

 

4. 컨테이너 이미지 빌드

$ docker build -t basic-img .

doker build 명령으로 컨터이너 이미지를 빌드한다. 여기서 사용된 -t(tag)는 만들어질 이미지를 의미하고, 점(.)은 이미지에 원하는 내용을 추가하거나 변경하는 데 필요한 작업공간을 현재 디렉토리로 지정한다는 의미이다.

 

 

도커파일 뜯어보기!

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" ]

빌드 내용을 이해하려면 도커 빌드에 사용된 Dockerfile은 빌드용 DSL(Domain-Specific Languages, 도메인 특화 언어)로 작성된 파일이다.

 

도커 파일 내용 배시 명령으로 유사 해석
FROM openjdk:8 import openjdk:8 image
LABEL description=”Echo IP Java Application” Label_desc=”Echo IP Java Application” # 컨테이너 이미지 설명
EXPOSE 60431 EXPOSE=60431 # 60431 포트를 사용해 오픈하도록 설명을 넣음
COPY ./target/app-in-host.jar /opt/app-in-image.jar scp <HOST>/target/app-in-host.jar
<IMAGE>/opt/app-in-image.jar
WORKDIR /opt scp <HOST>/target/app-in-host.jar <IMAGE>/opt/app-in-image.jar
ENTRYPOINT [ “java”, “-jar”, “app-in-image.jar” ] ./java -jar app-in-image.jar
  • FROM <이미지 이름>:[태그] 형식으로 이미지를 가져온다. 가져온 이미지 내부에서 컨테이너 이미지를 빌드한다. 누군가가 만들어 놓은 이미지에 필요한 부분을 추가한다고 보면 된다. 여기서는 openjdk를 기초 이미지로 사용한다. 기초 이미지로 어떤것을 선택하냐에 따라 다양한 환경의 컨테이너를 빌드할 수 있다.
  • LABEL <레이블 이름> = <값> 형식으로 이미지에 부가적인 설명을 위한 레이블을 추가할 때 사용한다.
  • EXPOSE <숫자>의 형식으로 생성된 이미지로 컨테이너를 구동할 때 어떤포트로 사용하는지 알려준다. EXPOSE를 사용한다고 해서 컨테이너를 구동할 때 자동으로 해당 포트를 호스트 포트와 연결하지 않는다. 외부와 연결하려면 지정한 포트를 호스트 포트와 연결해야 한다는 정보를 제공할 뿐이다. 실제로 외부에서 접속하려면 docker run 으로 이미지를 컨테이너로 빌드할 때 반드시 -p 옵션을 넣어 포트를 연결해야한다.
  • COPY <호스트 경로> <컨테이너 경로>의 형식으로 호스트에서 새로 생성하는 컨테이너 이미지로 필요한 파일을 복사한다. 메이븐을 통해 생성한 app-in-host.jar파일을 /opt/app-in-image.jar로 복사한다.
  • WORKDIR 현재 작업 위치를 opt 로 변경한다.
  • ENTRYPOINT [”명령어", “옵션”, “옵션”, .. “옵션”] 의 형식이다. 컨테이너 구동 시 ENTRYPOINT 뒤에 나오는 대괄호 안에 든 명령을 실행한다. 첫번째 문자열은 명령어이고 두번째 문자열부터 명령어를 실행할 때 추가하는 옵션이다. java -jar app-in-image.jar이 실행된다는 의미이다. ENTRYPOINT로 실행하는 명령어는 컨테이너를 구동할 때 첫번째로 실행된다. 이 명령어로 실행된 프로세스는 컨테이너 내부에서 첫번째로 실행됐다는 의미로 PID는 1이 된다.

 

 

 

5. 생성한 이미지 확인

$ docker images basic-img

 

 

 

6. 1.0태그, 2.0태그 이미지 생성

$ sudo docker build -t basic-img=1.0 -t basic-img:2.0 .

docker build 에 태그옵션(-t)를 추가해 1.0과 2.0 태그의 이미지를 생성해보았다. 캐시(cache)가 사용돼 매우 빠르게 빌드된다.

 

 

 

7. 생성된 이미지 확인

$ docker images basic-img

생성된 이미지를 확인한다. 이미지가 모두 ID(291fcf4dca9b)와 용량이 같은 것을 볼 수 있다. 즉, 이미지들은 태그 정보만 다를 뿐 모두 같은 이미지이며, 한 공간을 사용한다. 리눅스의 소프트링크와 비슷하다.

 

 

 

8. Dockerfile 변경 후 빌드

# 도커파일 내용 변경
$ sudo sed -i 's/Application/Development/' Dockerfile

# 3.0 태그로 빌드
$ docker build -t basic-img:3.0 .

Dockerfile 내용중에서 일부만 변경하면 어떻게 되는지 확인해보자. sed를 사용해 Dockerfile 의 2번째 줄에 있는 Application 부분을 Development로 변경하고 다시 빌드해보자. 버전이 중복되지 않게 3.0 태그를 사용한다.

 

 

 

9. 생성된 이미지 확인

$ docker images basic-img

완전히 다른 ID의 이미지가 생성되었다. 즉, 이름은 같지만 실제로는 다른 컨테이너 이미지이다.

 

 

 

10. 생성한 컨테이너 이미지가 작동하는지 확인

# 컨테이너 실행
$ docker run -d -p 60431:80 --name basic-run --restart always basic-img

# 컨테이너 상태 출력
$ docker ps -f name=basic-run

 

 

 

11. 컨테이너가 정상적으로 외부 요청에 응답하는지 확인

$ curl 127.0.0.1:60431

 

 

12. 컨테이너와 이미지 삭제

# 컨테이너 삭제
$ docker rm -f basic-run

# 컨테이너 이미지 삭제
$ docker rmi -f $(docker images -q basic-img)

 

 

 

13. 다음 실습과 용량 비교를 위해 빌드

# 이미지 빌드
$ docker build -t basic-img .

# 이미지 확인
$ docker images basic-img

 

 

 

 

 


https://dodo-devops.tistory.com/21

 

도커 컨테이너 이미지 만들기 2 - 컨테이너 용량 줄여 빌드하기

# 컨테이너 용량 줄여 빌드하기 불필요한 공간을 점유하는 건 비용 낭비이기도 하지만, 성능에 영향을 미칠 수 있다. 이번에는 컨테이너 이미지의 용량을 줄여 빌드하는 방법을 알아보자. # 컨테

dodo-devops.tistory.com

 

 

 

출처:

"컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커 - 조훈,심근우,문성주 지음/길벗출판사" 책을 기반으로 실습한 내용입니다.