[Docker] Docker란 ?
- -
Docker 에 대해 학습하고 직접 실행하며 배우고 느낀 것들에 대해 정리하고 공유하고자 글을 작성한다 📖
Docker
- 컨테이너를 사용하여 응용프로그램을 더 쉽게 만들고, 배포하고 실행할 수 있도록 설계된 도구이며 컨테이너 기반의 오픈 소스 가상화 플랫폼
- 일반 컨테이너 개념에서 물건을 손쉽게 운송해주는 것처럼 어플리케이션 환경에 구애받지 않고 손쉽게 배포 관리를 할 수 있게 해준다.
- 컨테이너 기반 배포 방식은 구글을 비롯해 대부분 서비스 회사가 컨테이너로 서비스 운영 중
- 따라서 AWS, Azure, GC 등 어디서든 실행이 가능하다.
Docker 를 왜 사용해야 할까?
- 똑같은 일을 하는 2대의 서버가 있다 해도, A 서버는 1년 전에 구성했고 B 서버는 이제 막 구성했다면 운영체제부터 컴파일러, 설치된 패키지까지 완벽하게 동일하기는 쉽지 않다. 이러한 차이는 문제를 발생시킬 수 있다.
- 도커는 서버마다 동일한 환경을 구성해주기 때문에 이러한 문제를 해결할 수 있다.
- 동일한 환경을 구성하기 때문에 auto scaling에 유리하다
⭐️ Auto Scaling의 주요 기능과 이점- 성능 유지: 애플리케이션에 대한 요청이 증가할 때, 추가적인 컴퓨팅 자원을 자동으로 배치하여 처리 능력을 증가시킨다. 이는 사용자 경험을 저하시키지 않으면서 서비스의 가용성과 성능을 유지할 수 있게 한다.
- 비용 절감: 자동 확장은 실제 필요한 만큼의 자원만을 사용하도록 조정하기 때문에, 사용하지 않는 자원에 대한 비용을 절약할 수 있다. 특히, 트래픽이 낮은 시간대에 자원을 자동으로 축소함으로써 비용을 절감할 수 있다.
- 유연성 및 반응성: 애플리케이션의 트래픽 패턴이 예측하기 어려울 때, 자동 확장 기능은 시스템이 이러한 변화에 신속하게 대응할 수 있게 한다. 이는 예기치 않은 트래픽 증가나 감소에 효과적으로 대응할 수 있게 해준다.
- 자동화: 자동 확장은 정해진 규칙이나 정책에 따라 작동하므로, 인프라 관리에 드는 수동 작업을 줄여주고 IT 팀의 작업 부담을 경감시킨다.
- 트리거: 특정 메트릭(예: CPU 사용률, 메모리 사용량, 네트워크 트래픽 등)이 정의된 임계값에 도달하면, 자동 확장 시스템이 트리거된다.
- 확장 정책: 확장(자원 추가) 또는 축소(자원 제거) 작업은 미리 정의된 확장 정책에 따라 실행된다. 이 정책은 특정 메트릭의 임계값, 확장 시 추가할 자원의 수, 축소 시 제거할 자원의 수 등을 포함할 수 있다.
- 자원 할당 및 제거: 시스템은 정책에 따라 필요한 자원을 자동으로 할당하거나 제거하여, 애플리케이션의 성능을 최적화하고 비용을 관리한다.
- Auto scaling, 즉 자동 확장은 클라우드 컴퓨팅 환경에서 애플리케이션의 부하(traffic)에 따라 컴퓨팅 자원(예: 서버의 수)을 자동으로 조정하는 기술이다. 이 기능은 시스템의 부하가 증가하거나 감소함에 따라 자원을 동적으로 추가하거나 제거하여, 애플리케이션의 성능을 최적화하고 비용 효율성을 극대화한다.
도커와 기존 가상화 기술(VM)의 차이
- 한대의 서버에서 하나의 어플리케이션만 운영하는 전통적인 방식에서 하이퍼 바이저 기반 가상화 기술이 등장했다.
- 하이퍼 바이저는 호스트 시스템(Linux, Window 등) 에서 다수의 게스트 OS(가상머신)을 구동할 수 있게 하는 소프트웨어다.
- 각 VM 마다 독립적으로 동작한다.
- 도커는 하이퍼 바이저 구조 토대로 등장했으며, VM 보다 훨씬 가볍게 동작하기 때문에 성능에 유리하다.
- 논리적으로 구분이 되어 있기 때문에 하나의 어플리케이션에서 장애가 발생을 해도 다른 어플레키에션에 전혀 영향을 받지 않는 구조이다.
이미지란 ?
- 이미지란 코드, 런타임, 시스템 도구, 시스템 라이브러리 설정과 같은 응용프로그램을 실행하는데 필요한 모든 것을 포함하는 패키지이다.
- 이미지는 Github 와 유사한 서비스인 https://hub.docker.com/ 을 통해 버전 관리가 가능하다.
컨테이너란?
- 도커 이미지를 독립된 공간에서 실행할 수 있게 해주는 기술이다.
⭐️ 즉, 도커 이미지는 프로그램을 실행하는데 필요한 설정이나 종속성들을 가지고 있고, 도커 컨테이너는 이미지 인스턴스이며 프로그램을 실행한다. 또한 하나의 도커 이미지는 여러 컨테이너를 실행할 수 있다.
Dockerfile이란 ?
- Dockerfile이란 도커 이미지를 구성하기 위해 있어야할 패키지, 의존성, 소스코드 등을 하나의 file 로 기록하여 이미지화 시킬 명령 파일이다.
- 즉, 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 더 이상 새로운 서버가 추가되면 의존성 파일을 컴파일하고 추가적인 설치가 불필요해진다.
[FROM]
새로운 이미지를 생성할 때 기반으로 사용할 이미지 지정(이미지 이름:태그)
jdk 11 이 있는 컨테이너 사용
[ARG]
이미지 빌드 시점에서 사용할 변수 지정
[COPY]
호스트에 있는 파일이나 디렉토리를 Docker 이미지의 파일 시스템으로 복사
[ENV]
컨테이너에서 사용할 환경 변수 지정
TimeZone 환경 변수
[ENTRYPOINT]
컨테이너가 실행되었을 때 항상 실행되어야 하는 커맨드 지정
// base Image
FROM openjdk:11
// 어떤 변수를 사용할 것인지
ARG JAR_FILE=build/libs/app.jar
// 컨테이너의 어떤 부분을 카피할 것인지
COPY ${JAR_FILE} ./app.jar
COPY pharmacy.csv ./
// 어떤 타임존을 사용할 것인지
ENV TZ=Asiz/Seoul
// 컨테이너가 실행될 때 어떤 명령어를 입력할 건지
ENTRYPOINT ["java", "-jar", "./app.jar"]
Docker Compose란 ?
- Docker Compose란 멀티 컨테이너 도커 어플리케이션을 정의하고 실행하는 도구이다.
- 멀티 컨테이너 환경, 예를 들어 Application, Database, Redis, Nginx 등을 각각 독립적인 컨테이너로 관리한다고 했을 때 멀티 컨테이너 라이프 사이클을 자동으로 관리해준다.
- 즉, 여러개의 도커 컨테이너로 부터 이루어진 서비스를 구축 및 네트워크 연결, 실행 순서를 자동으로 관리해준다.
- docker-compose.yml 파일을 작성하여 1회 실행하는 것으로 설정된 모든 컨테이너를 실행할 수 있다.
📚 Spring boot에서 Docker 연동
1. Docker 설치하기
https://docs.docker.com/desktop/install/mac-install/
해당 페이지에서 OS에 맞게 설치한다. Linux 의 경우엔 docker-compose 를 추가로 설치해 주어야 한다.
설치가 완료됐으면 아래의 명령어를 통해 버전을 확인하여 설치를 확인!
docker -v
docker-compose -v
2. Spring Boot 에서 Docker 실행하기
도커 설치가 모두 완료되었으면 이제 Spring Boot 에서 직접 Docker 를 실행시켜 보자!
2-1. jar 파일을 생성
우선 gradle wrapper 를 이용하여 jar 파일을 생성해 주어야 한다. build.gradle 에서 생성되는 jar 파일의 이름을 변경해 줄 수도 있다! (기본 경로는 프로젝트의 build/libs/*.jar)
// build.gradle, jar 파일 네이밍 설정
boojJar {
archiveFileName = `app.jar`
}
// 터미널에 아래의 명령어를 통해 build (Linux, OS)
./gradlew build
위의 과정을 모두 진행하면 build/libs 경로에 app.jar 파일이 정상적으로 생성된 것을 확인할 수 있다.
2-2. Dockerfile 파일을 생성
이제 이 jar 파일을 기반으로 도커 이미지를 생성한다. 먼저 루트 디렉토리에 Dockerfile 을 채워준다. 자세한 내용은 위에서 설명했기에 생략!
FROM openjdk:11
ARG JAR_FILE=build/libs/app.jar
#app.jar 이라는 네임으로 카피
COPY ${JAR_FILE} ./app.jar
ENV TZ=Asia/Seoul
ENTRYPOINT ["java", "-jar", "./app.jar"]
2-3. Dockerfile 파일을 이미지로 Build
모두 작성했으면 Docker file 을 이미지로 build 해보자. 아래의 명령어를 통해 Build!
[MANUAL]
docker build -t {도커 Hub ID}/{도커 image Name} {DockerFile 이 있는 경로}
[EX]
docker build -t userid/application-test-app .
실행한 결과를 확인하기 위해 docker images 명령어를 사용한다.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
userid/application-test-app latest 25173000d985 About a minute ago 663MB
2-3. Docker 실행하기
복잡한 과정은 모두 끝났다. 이제 Docker run 명령어를 통해 컨테이너 생성 및 실행 !
[MANUAL]
docker run {docker Hub Id}/{docker image} -p {host port}:{docker Container port}
[EX]
docker run userid/application-test-app -p 8080:8080
💡 port 옵션을 사용하여 포트를 지정하는 이유
도커 컨테이너는 독립된 공간에서 실행되기 때문에 호스트와 컨테이너 간의 port 포워딩 처리가 필요하다.
(호스트로 온 Request 요청을 도커 컨테이너로 포워딩을 해줘야 하는 경우가 발생)
위와 같은 과정을 통해 Spring boot 가 실행되는 것을 확인할 수 있다! 또한 이름은 지정하지 않았기 때문에 임의로 지정된 모습을 확인할 수 있다.
$ docker run userid/application-test-app -p 8080:8080
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.7)
2024-02-11 10:29:59.180 INFO 1 --- [ main] c.example.pharmacy.PharmacyApplication : Starting PharmacyApplication using Java 11.0.16 on ca5ac2e75d9f with PID 1 (/app.jar started by root in /)
2024-02-11 10:29:59.182 INFO 1 --- [ main] c.example.pharmacy.PharmacyApplication : No active profile set, falling back to 1 default profile: "default"
2024-02-11 10:29:59.709 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2024-02-11 10:29:59.718 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-02-11 10:29:59.718 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.62]
2024-02-11 10:29:59.775 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-02-11 10:29:59.775 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 552 ms
2024-02-11 10:29:59.963 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2024-02-11 10:29:59.970 INFO 1 --- [ main] c.example.pharmacy.PharmacyApplication : Started PharmacyApplication in 1.063 seconds (JVM running for 1.379)
실행되고 있는 도커 리스트 조회
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca5ac2e75d9f userid/application-project-test "java -jar ./app.jar…" 25 seconds ago Up 24 seconds hungry_archimedes
도커를 싱글 컨테이너 환경에서 실행하는 것까지 모두 진행했다. 더 길어지는 내용은 다음 포스트에서 설명하겠다 : )
'Server' 카테고리의 다른 글
[Docker] 다중 컨테이너 한번에 구현하기 (0) | 2024.02.12 |
---|
소중한 공감 감사합니다