똑같은 일을 하는 2대의 서버가 있다 해도, A 서버는 1년 전에 구성했고 B서버는 이제 막 구
성했다면 운영체제부터 컴파일러, 설치된 패키지까지 완벽하게 같기는 쉽지 않다.
이러한 차이가 문제를 발생시킬 수 있다.
도커는 서버마다 동일한 환경을 구성해주기 때문에 이러한 문제를 해결할 수 있다.
동일한 환경을 구성하기 때문에 auto sacling에 유리하다.
한대의 서버에서 하나의 어플리케이션만 운영하는 전통적인 방식에서 하이퍼 바이저 기반 가상화 등장했다.
하이퍼 바이저는 호스트 OS(윈도우, 리눅스 등)에서 다수의 게스트 OS(가상머신)을 구동할 수 있게 하는 소프트웨어이다. 이는 각 VM 마다 독립적으로 동작이 가능하다.
하이퍼 바이저로 한대의 서버에서 여러대로 돌리는 것이 가능하지만, 게스트 OS를 올리는 것이 무겁다.
컨테이너 가상화 기술은 M보다 훨씬 가볍게 동작하기 때문에 성능에 유리하다.
다만 Hypervisor 기술은 독립성을 더 보장한다. 그러나 컨테이너 가상화 기술은 그냥 속도면으로 깡패이다. 이는 Bin/Library 위에 Application을 올리면 된다. 즉, 게스트 OS를 올리지 않는다.
출처: Kubernetes Docs
이미지란 코드, 런타임, 시스템 도구, 시스템 라이브러리 및 설정과 같은 응용프로그램을 실행 하는데 필요한 모든 것을 포함하는 패키지이다.
컨테이너 가상화 기술이란 도커 이미지를 독립된 공간에서 실행할 수 있게 해주는 기술이다.
Dockerfile이란 도커 이미지를 구성하기 위해 있어야 할 패키지, 의존성, 소스코드 등을 하나의 file로 기록하여 이미지화 시킬 명령 파일 이다.
즉, 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 더 이상 새로운 서버가 추가되면 의존성 파일을 컴파일하고 이것 저것 설치할 필요가 없다!
FROM: 예) FROM openjdk:11 (jdk 11 이 있는 컨테이너 사용한다.)
ARG: 예) ARG JAR_FILE=build/libs/app.jar
COPY: 예) COPY ${JAR_FILE} ./app.jar
ENV: 예) ENV TZ=Asia/Seoul (TimeZone 환경 변수)
ENTRYPOINT: 예) ENTRYPOINT [“java”, “-jar”, “./app.jar”]
FROM openjdk:11
ARG JAR_FILE=build/libs/app.jar
COPY ${JAR_FILE} ./app.jar
ENV TZ=Asia/Seoul
ENTRYPOINT ["java", "-jar", "./app.jar"]
Docker Compose란 멀티 컨테이너 도커 어플리케이션을 정의하고 실행하는 도구이다.
Application, Database, Redis, Nginx 등 각 독립적인 컨테이너로 관리한다고 했을
때 다중 컨테이너 라이프 사이클을 어떻게 관리해야 할까?
도커 컴포즈는 여러개의 도커 컨테이너로 부터 이루어진 서비스를 구축 및 네트워크 연결, 실행 순서를
자동으로 관리한다.
docker-compose.yml 파일을 작성하여 1회 실행하는 것으로 설정된 모든 컨테이너를 실행한다.
version: 도커 컴포즈 버전
services: 실행하려는 컨테이너들을 정의한다.
recommendation-app: 서비스 명(네트워크 호스트명) / 같은 네트워크에 속한 컨테이너끼리 서비스 명으로 접근 가능하다.
container_name: 컨테이너 이름을 명시한다.
build: Dockerfile이 있는 위치이다.
depends_on: 특정 컨테이너에 대한 의존관계를 명시한다.
image: 컨테이너를 생성할 때, 사용할 도커 이미지를 지정한다.
enviroment: 컨테이너가 돌아갈 때 환경변수를 제공한다.
volumes: 호스트 디렉토리 컨테이너 디렉토리 마운트를 지정한다.
mount: 간략하게 설명하면 컨테이너 디렉토리가 호스트 디렉토리를 참조하겠다!
ports: 접근 포트 설정(컨테이너 외부: 컨테이너 내부) / docker run -p 옵션과 같으며 개방할 포트 지정
restart: 컨테이너 실행 실패하는 경우 재시작 여부를 지정한다.
실행: docker-compose -f docker-compose-local.yml up
종료: docker-compose -f docker-compose-local.yml down
version: "3.8"
services:
recommendation-service-redis:
container_name: recommendation-service-redis
build:
dockerfile: Dockerfile
context: ./redis
image: chungjm0711/recommendation-service-redis
ports:
- "6379:6379"
recommendation-service-database:
container_name: recommendation-service-database
build:
dockerfile: Dockerfile
context: ./database
image: chungjm0711/recommendation-service-database
environment:
- MARIADB_DATABASE=recommendation_service
- MARIADB_PASSWORD=${SPRING_DATASOURCE_PASSWORD}
volumes:
- ./database/config:/etc/mysql/conf.d
ports:
- "3306:3306"
Docker compose에서 환경 변수 정보 들을 분리하여 별도의 파일로 구성할 때 간편한 방법은 Compose 파일이 위치한 경로에 .env 파일을 구성한다.
작성한 .env 파일은 별다른 설정 없이 Docker Compose에 바로 반영할 수 있다.
비밀정보가 코드에 노출되지 않도록 .gitignore에 .env 파일 추가한다.
암호화를 통해 더 높은 보안을 제공하는 오픈소스 HashiCorp Vault를 현업에서 많이 사용한다.
$ docker-compose config // .env 파일 자동 반영
$ docker-compose up // 이미지 없을 때 이미지 빌드 후 컨테이너 실행(이미지 존재하는 경우 해당 이미지 사용)
$ docker-compose up --build // 이미지가 있든 없든 재빌드 하여 컨테이너 실행
$ docker-compose up -d // 백그라운드 실행
// .env 파일 (.gitignore에 추가해야한다.)
// docker compose 에서만 사용한다.
// java 환경변수는 따로 주입해야한다.
SPRING_DATASOURCE_USERNAME=root
SPRING_DATASOURCE_PASSWORD=1234