[F-Lab 모각코 챌린지 44일차] 도커

부추·2023년 7월 14일
0

F-Lab 모각코 챌린지

목록 보기
44/66

TIL

도커



오늘 하루 내내 삽질만 했다.. 강의 내용은 자바8 + maven 이었는데 괜히 자바17 + gradle로 해보겠다고 덤비고.. 강의에서는 CentOS 7 버전이었는데 CentOS 9 써보겠다고 나대다가 털리고.. 그냥 하라는대로 얌전히 할걸.


도커란..?

컨테이너 기반의 가상화 도구이다. (개어렵)

도커가 없는 상황을 먼저 가정해보자. 하나의 서버 컴퓨터에서 여러개의 서버 프로그램을 돌리고 싶을 수 있다. 이 때 VM(Virtual Machine)을 사용한다고 해보자. VM은 원래 컴퓨터의 운영체제인 HostOS 위에 Hypervisor라는 프로그램을 깔고 그 위에 여러 OS를 설치하여 만들 수 있다.
맥북 위에 VM웨어같은 hypervisor 프로그램을 깔고, 그 안에 centos, ubuntu, window os를 이용하는 가상머신 3개를 띄운다고 생각해보자. 위와 같은 구조가 될 것이다.

이렇게 가상 머신을 통한 다수의 서버 프로그램 구축은, 가상 머신마다 분리된 컴퓨터 리소스와 운영체제를 가지고 각각을 운용할 수 있지만 OS 구축을 위해 낭비되는 리소스가 많다는 점, 하드웨어 자원을 이용하기 위해 HostOS - GuestOS간 hypervisor 프로그램을 통한 명령어 번역이 이뤄져야 한다는 점 때문에 상!당!히! 느리다는 단점을 가지고 있다. VM웨어 위에서 우분투 쓰면 그냥 cmd사용하는 것보다 훨씬 느린 것이 체감되는데, 여기다 서버를 띄운다고 생각해보면.... 음.


도커는 이런 식으로 OS를 아예 분리하는 것이 아닌, 프로세스 단위의 격리 환경을 제공한다. 다시, 이번엔 맥북 위에 hypervisor + guestOS가 아닌, 도커 엔진 + 컨테이너를 띄우는 상황을 가정하자.
위와 같은 구조가 된다. 각각의 서버 어플리케이션을 돌리기 위해 각각의 OS를 설치하는 대신, 도커 엔진에는 각 컨테이너 어플리케이션을 실행하기 위한 라이브러리만이 존재한다. 때문에 어플리케이션 실행 환경 "이미지"가 훨씬 가벼워지고, GuestOS를 사용할 때보다 빨리 구동될 수 있는 것이다.

이제 각각을 하나하나 조금만 더 세세히 보자..


컨테이너란..?

도커에서 말하는 컨테이너는 어플리케이션과 그것의 실행을 위한 하나의 종합적인 실행 환경을 포함하는 개념이다. 도커가 제공하는 프로세스 단위의 격리 환경이기도 하다. 바로 위의 설명에서, 어플리케이션과 그 실행 환경 라이브러리를 포함한 lib/bin + app 하나가 컨테이너라고 생각하면 된다. 서버 프로그램을 돌리기 위한 OS 프로그램이 필요가 없으므로 VM을 사용할 때보다 배포 이미지가 작아지고 실행 시간 역시 단축된다.

도커 엔진을 통해 컨테이너가 실행되는데, 컨테이너는 Host OS 위에서 돌아가는 프로세스와 같은 취급을 받게된다. 실행 환경과 프로그램이 하나의 격리된 프로세스로 존재하면 어떤 이점이 있을까? 실행 환경 자체를 옮길 수 있으므로 서버에 로컬 환경에서 개발한 프로그램을 빌드 및 배포할 때 훨씬 간편하다. 이거 진짜 커다란 이점이다.. 로컬 개발 환경과 서버 환경의 OS, 아키텍처, 버전 등등이 달라서 배포시에 삽질을 하게되는 경우가 많은데 도커 컨테이너 하나 띄워놓고 그 안에서 SDK를 포함하여 개발하면 정!말 편할 것 같다. (물론 그만큼 컨테이너 관련해서 공부할 것이 늘어나지만)


도커 엔진이란..?

간단하게 말하면, 컨테이너를 쉽게 관리할 수 있게 해주는 주체이다.

컨테이너의 라이프사이클을 관리하고, 컨테이너 생성을 위한 이미지를 관리하고, 컨테이너 실행을 위한 커널(네트워크 포함)을 관리하기도 한다. VM을 활용한 프로그램 격리에서 hypervisor 역할을 하는 놈이니 .. 컨테이너 관련한 웬만한 일은 다 처리하는 고마운 녀석 정도라고 이해하자.


도커를 사용한 초간단 이미지 빌드

도커를 사용해서 어떻게 서버에 컨테이너가 생성되는지 과정을 설명하겠다!

  1. 개발 환경의 Dockerfile에 실행 환경, 엔트리 포인트 설정 등의 configuration을 진행한다.
  2. docker build를 통해 컨테이너 생성을 위한 이미지 파일을 만든다.
  3. docker hub에 해당 이미지 파일을 push한다.
  4. 서버에서 방금 push한 이미지 파일을 pull한다.
  5. docker run을 통해 이미지 파일을 실행하여, 컨테이너 내부의 프로그램을 실행한다.

진행중인 스프링부트 프로젝트의 루트폴더에 Dockerfile파일을 추가하고 아래 코드를 추가했다.

FROM openjdk:17-jdk-alpine
VOLUME /tmp
COPY build/libs/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
  • 베이스 이미지로 openjdk를 사용했다.
  • gradle을 사용할 경우, build/libs 하위에 jar파일이 생성되는데, COPY명령어를 통해 해당 jar파일을 컨테이너의 app.jar 파일로 복사한다.
  • ENTRYPOINT에 컨테이너 시작시 실행될 명령어를 지정했다. docker run 명령어를 통해 $ java -jar /app.jar 커맨드가 실행될 것이다.

그리고 프로젝트 폴더에서 다음 명령어를 실행시켰다.

$ docker build . -t bootapp --platform linux/amd64

--platform linux/amd64는 내 로컬환경이 m2칩이라서.. 따로 지정하지 않으면 오류가 뜬다 ㅜㅜ

도커 빌드가 잘 되면 이제 run을 할 차례다!

$ docker run -p 80:8080 bootapp

-p옵션은 {host 포트번호:container 포트번호}를 연결해주기 위함이다. 서버 컴퓨터 위에 스프링의 톰캣 서버가 올라가있는 상황이라고 생각해보자. 톰캣은 8080포트에 열려있고, 서버 컴퓨터는 HTTP 요청을 받기 위해 80포트가 열려있다. 80포트의 요청을 컨테이너의 8080포트로 포워딩 할 필요가 있다. 그렇기 때문에 -p 80:8080 옵션을 추가한 것이다.

이 뒤 localhost:80에 접속하면, 도커 컨테이너를 통해 띄운 스프링 서버 프로그램이 동작하는 것을 확인할 수 있다.



REFERENCE

https://www.youtube.com/watch?v=IiNI6XAYtrs&t=430s
https://ttl-blog.tistory.com/761#%EC%99%9C%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20%EB%AA%BB%20%EC%B0%BE%EB%8A%94%EB%8B%A4%EB%8A%94%20%EC%98%A4%EB%A5%98%EA%B0%80%20%EB%B0%9C%EC%83%9D%ED%95%98%EB%82%98%EC%9A%94%3F%20%F0%9F%A7%90-1
https://class101.net/classic/classes/5fc4a3b3fc231b000d856415/lectures/5fc5531a36e19200137fc100

profile
부추튀김인지 부추전일지 모를 정도로 빠싹한 부추전을 먹을래

0개의 댓글