[마이크로서비스] 도커의 개념과 프로젝트 적용 (3)

hyeokjin·2022년 8월 13일
0

microservice

목록 보기
3/13
post-thumbnail

도커 알아보기

마이크로서비스에 도커의 개념을 살펴보고 서비스에 적용해보도록 하자.

먼저 도커의 아키택쳐다

  • 도커데몬 : 도커 이미지를 생성하고 관리하는 dockerd라는 서버다

  • 도커 클라이언트 : 도커 사용자는 클라이언트로 도커와 상호작용한다 도커에 명령이 실행되면 데몬에 명령을 보내는 역할을 한다.

  • 도커 레지스트리 : 도커 이미지가 저장되는 곳이다. 공개 또는 사설 레지스트리일 수 있고, 도커 허브는 기본 공개 레지스트리이다.

  • 도커 이미지 : 도커 컨테이너를 생성하는 몇가지 명령이 포함된 읽기 전용 템플릿이다. 또한 Dockerfile을 사용하여 새로운 이미지를 생성할 수 도 있다.

  • 도커 컨테이너 : docker run 명령이 생성되고 수행되면 도커 이미지는 컨테이너를 생성한다. 애플리케이션과 주변환경은 이 컨테이너에서 실행된다.

  • 도커 볼륨 : 도커가 생성하고 컨테이너가 사용한 데이터를 저장하는데 적합한 메커니즘이다.

  • 도커 네트워크 : 도커 네트워크를 사용하면 컨테이너를 가능한 많은 네트워크에 연결할 수 있다. 네트워크를 격리된 컨테이너의 통신 수단으로 생각할 수 있으며 도커에는 bridge, host, overlay, none, macvlan 다섯 가지의 네트워크 드라이버 타입이 있다.

Dockerfile

도커파일은 도커 클라이언트가 이미지를 생성하고 준비하기 위해 호출하는데 필요한 지시어와 명령어 들이 포함된 단순한 테스트 파일이다. 이 파일은 이미지 생성 과정을 자동화 한다.

예시)

명령어 종류

도커 컴포즈

도커 컴포즈는 서비스 설계와 구축이 용이한 스크립트를 작성하여 도커를 더 쉽게 작성하게 한다. 도커 컴포즈를 사용하면 여러 컨테이너를 하나의 서비스로 실행하거나 다른 컨테이너를 동시에 생성할 수 있다.

  • docker-compose.yml로 지정해야한다.
  • docker-compose up 명령을 사용하여 서비스를 시작한다.

컴포즈 명령어

컴포즈 지시어

도커 이미지 만들기

pom.xml 파일에 도커 메이븐 플러그인을 추가해서 도커 이미지를 빌드한다.
이 플러그인을 사용하면 메이븐 pom.xml 파일에서 도커 이미지와 컨테이너를 관리 할 수 있다.

pom.xml

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<!-- This plugin is used to create a docker image and publish the image to docker hub-->
			<plugin> <!-- 여기서 Dockerfile 메이븐 플러그인을 시작한다.-->
				<groupId>com.spotify</groupId>
				<artifactId>dockerfile-maven-plugin</artifactId>
				<version>1.4.13</version>
				<configuration>
					<!-- 리모트 저장소 이름을 설정한다. 플러그인에서 정의된 변수인 docker.image.prefix 와 project.artifactId 를 사용한다.-->
					<repository>${docker.image.prefix}/${project.artifactId}</repository>
	                <tag>${project.version}</tag>
					<buildArgs>
						<!-- buildArgs를 사용하여 JAR파일 위치를 설정한다 이 값은 Dockerfile에서 사용된다.-->
						<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
					</buildArgs>
				</configuration>
				<executions>
					<execution>
						<id>default</id>
						<phase>install</phase>
						<goals>
							<goal>build</goal>
							<goal>push</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
    
    
    
    <properties>
		<java.version>11</java.version>
        <!-- 기존 프로퍼티 선언 부분에 docker-prefix명을 추가한다 ostock으로 만들었다 -->
		<docker.image.prefix>ostock</docker.image.prefix>
	</properties>

그리고 dockerfile에서 스프링 부트 jar 파일을 도커 이미지에 복사한 후 애플리케이션 jar를 실행할 코드를 작성한다.

이 dockerfile에서는 멀티스테이지 빌드를 사용한다
스프링 부트의 경우 도커이미지에 target 디렉터리를 모두 복사하는 대신 스프링 부트 애플리케이션에 실행하는데 필요한것만 복사하여 생성할 도커 이미지를 최적화 한다.

Dockerfile

#stage 1
#Start with a base image containing Java runtime
# 도커 런타임에 사용될 도커 이미지를 지정한다
FROM openjdk:11-slim as build

# Add Maintainer Info
LABEL maintainer="Illary Huaylupo <illaryhs@gmail.com>"

# The application's jar file
# docker-maven-plugin에 설정된 JAR_FILE 변수를 정의한다.
ARG JAR_FILE

# Add the application's jar to the container
# JAR 파일을 이미지의 파일 시스템에 app.jar로 복사한다.
COPY ${JAR_FILE} app.jar

#unpackage jar file
# 앞서 빌드 이미지의 파일 시스템에 복사한 app.jar의 압축을 푼다
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf /app.jar)

# excute the apllication
# 컨테이너가 생성될 떼 이미지의 라이선싱 서비스 애플리케이션을 실행 대상으로 지정한다.
# 여기서는 멀티스테지 빌드를 사용하므로 이 부분은 사용하지않는다.
#ENTRYPOINT ["java", "-jar", "/app.jar"]

#stage 2
#Same Java runtime
# 새로운 이미지는 스프링 부트 앱에 대한 통짜 JAR 파일 대신 여러 레이어로 구성된다.
FROM openjdk:11-slim

#Add volume pointing to /tmp
VOLUME /tmp

#Copy unpackaged application to new container
# stage1에서 build라고 명명된 첫 이미지에서 여러 레이어를 복사한다.
ARG DEPENDENCY=/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app

#execute the application
# 컨테이너가 생성될 떼 이미지의 라이선싱 서비스 애플리케이션을 실행 대상으로 지정한다.
ENTRYPOINT ["java","-cp","app:app/lib/*","com.optimagrowth.license.LicenseServiceApplication"]

Dockerfile은 전체 애플이케이션 JAR 대신 이들 레이어만 포함된 또 다른 이미지를 생성한다. 두번째 스테이지에서 Dockerfile은 여러 레이어를 새 이미지에 복사한다.


이제 pom.xml 파일이 있는 루트 폴더에서 다음 메이븐 명령을 수행한다.

터미널에서 다음 명령어를 통해 JAR 파일을 추출한다

mvn clean package

그리고 도커이미지를 빌드 하려면 아래 명령을 실행한다.

mvn package dockerfile:build

docker images 명령어를 통해 이미지 목록에서 이미지를 볼 수 있다.

도커의 이미지가 있다면 docker run -d ostock/licensing-service:0.0.1-SNAPSHOT 명령을 통해 컨테이너를 백그라운드에서 실행할 수 있다.

docker ps, docker ps -a를 통해 컨테이너 상태를 볼 수 있다.
컨테이너를 중지하려면 docker stop <container_id> 를 통해 중지할 수 있다.

도커 컴포즈로 서비스 실행하기

도커 컴포즈는 서비스를 그룹으로 정의한 후 단일 단위로 시작할 수 있는 서비스 오케스트레이션 도구다. 도커 컴포즈는 서비스별 환경 변수를 정의하는 기능도 있다.

구조를 살펴보자

docker-compose.yml

version: '3'

services:
  # 시작한 서비스에 레이블을 적용한다. 이 서비스 이름은 도커 인스턴스가 시작할 때 이에 대한 DNS 엔트리가 되며, 다른 서비스가 엑세스하는 데 사용된다.
  licensingservice:
    # 도커 컴포즈는 먼저 로컬 도커 저장소에서 시작할 대상 이미지를 찾으려고 시도한다. 찾을 수 없다면 도커 허브에서 확인한다
    image: ostock/licensing-service:0.0.1-SNAPSHOT
    # 시작한 도커 컨테이너의 포트 번호를 정의한다 이 포트 번호는 외부에 노출된다
    ports:
      - "8080:8080"
    # 시작하는 도커 이미지에 환경 변수를 전달한다  이 경우 SPRING_PROFILES_ACTIVE 환경번수를 지정한다.
    environment:
       - "SPRING_PROFILES_ACTIVE=dev"
    networks:
      backend:
        aliases:
          # 네트워크상의 서비스에 대한 대체 호스트 이름을 지정한다.
          - "licenseservice"
networks:
  backend:
    # 디폴트 타입은 bridge이며 backend라고 명명된 커스텀 네트워크를 실행한다.
    driver: bridge

해당 파일이 위치한 디렉터리에서 docker-compose up 명령으로 서비스를 시작할 수 있다.

아래 링크는 도커에 대한 더 자세한 내용 설명한다.

도커 기초 알아보기


🧨 다음 챕터는 Spring cloud config 통해 각 서비스의 구성정보를 별도 보관하는 서비스를 만들어 보겠다.

profile
노옵스를향해

0개의 댓글