도커는 운영체제 가상화를 지원하는 소프트웨어이다.

가상화 란 단일한 물리 하드웨어 시스템을 여러 환경으로 나눠 각각 운영체제와 애플리케이션을 실행할 수 있도록 하는 것이다. 가상화에는 크게 3가지 방식이 있는데,

1. 호스트 가상화

2. 하이퍼바이저 가상화

3. 컨테이너 가상화

1번 호스트 가상화는 호스트 OS 위에 게스트 OS 가 작동하는 방식으로, 가상화 소프트웨어가 이를 지원한다.

2번 하이퍼바이저 가상화는 하이퍼바이저(Hypervisor)라는 프로그램 위에 별도의 OS들이 작동하는 방식이다. 흔히 가상머신(VM) 방식이라고 한다.

 

위 두 방식은 각 가상환경마다 OS 를 구동시킨다는 특징이 있다.

이러한 방식은 안정적으로 가상화 환경을 구성할 수 있다는 장점이 있어 AWS 등 유명 클라우드 컴퓨팅 서비스에서 사용하고 있다. 그러나 이는 높은 사양을 필요로 하여 구성할 수 있는 가상환경에 제한이 있으며 프로비저닝(특정 환경이 실행되기까지 필요한 사전준비 과정) 에 많은 시간이 걸려 가상환경을 이동하는 것에 제한이 있다.

특히 MSA 등 서버 구조가 자주 바뀌는 상황에서 이러한 방식을 사용하는 것은 충분히 비효율적이며 그래서 등장한 것이 컨테이너 가상화이다.

3번 컨테이너 가상화는 단일 OS 위에 관리 SW가 논리적으로 컨테이너를 나누어 사용하는 방식이다.

컨테이너애플리케이션이 독립적으로 실행될 수 있는 환경을 의미하며 각각의 컨테이너는 동일한 OS 위에서 동작하지만, 각 애플리케이션의 독립된 실행을 위하여 Linux kernel의 기능을 사용하여 프로세스를 분리해서 각 애플리케이션이 철저히 격리된 환경에서 실행된다. 

 

일단 기존 가상화 방식(VM)에 비해 컨테이너는 사용하는 메모리가 적고, 가동과 중단이 빨라 효율적이다.

또 새로운 소프트웨어가 개발되었을 때 이를 적용하여 배포하기 쉽고 빠르다. 도커는 애플리케이션의 실행을 위한 정보들을 캡슐화하여 저장하고, 이를 이미지(docker image) 라는 하나의 패키지로 만들어 공유할 수 있어서 

이미지를 통해 컨테이너를 구성하여 실제로 애플리케이션을 실행할 환경을 제공한다.

그리하여 느슨하게 연결된 다수의 구성요소로 애플리케이션을 구성하는 MSA 방식에도 적합하다고 할 수 있다.

 

물론 보안문제나, 가상머신(VM) 만큼 독립된 환경을 제공하지는 않는다는 문제가 있지만,

중요한 건 나에게 필요한가? 이다. 백엔드 개발을 공부하는 입장에서, 해커톤 등 프로젝트를 진행하면서, 도커를 사용해본 결과 느끼게된 장점을 생각해보면

 

1. 굉장히 간편하다.

 사실 이게 가장 큰 장점인 것 같다. 아무래도 백엔드 개발이라면 단순 정적파일(html, image 등)이 아닌 동적 애플리케이션을 배포해야하기에 복잡한 프로비저닝 과정이 필요하다.

java 애플리케이션을 배포하는 경우 도커를 사용하지 않는 다면 과정이 굉장히 복잡하다. java를 버전에 맞게 설치하고... github에서 레포지토리의 코드를 불러오고... 빌드 툴을 통해 실행파일을 만들고.... 그 실행파일을 실행시키고...

그 과정에서 정말 다양한 오류가 나왔던 것 같다.

또 DB를 운영하기 위해 서버에 DB를 설치하고... 사용자를 생성하고... 스키마를 구축하고... 필요한 요소가 있으면 계속해서 새로 설치하고 테스트하는 과정을 반복해야한다.

도커를 사용하면 그럴 필요 없이, 로컬 환경에서 바로 java 애플리케이션 실행파일을 이미지로 저장하고, DockerHub 를 통해 공유한 다음, 서버에 바로 이미지를 내려받아 컨테이너로 실행시키면 끝이다. DB 또한 이미 만들어진 DB 이미지가 있다. mysql, postgre 등등... 그대로 받아와서 컨테이너로 실행을 시켜, 두 컨테이너를 잘 연결시켜주면 끝이다.

 

2. 이미 잘 만들어진 다른 서버를 구축하기 쉽다.

 도커의 이미지들은 도커 허브(docker hub)라는 원격 저장소를 통해 공유되는데 그렇기 때문에 남이 잘 만들어놓은 이미지들을 필요에 따라 별도의 준비과정 필요없이 고대로 갖다 쓸 수 있기에 능률이 확실히 오른다.

 

3. CI/CD 파이프라인을 구축하기 용이하다.

CI (Continuous Integration)는 지속적 통합을 의미하며, 소프트웨어의 변동사항이 지속적으로 반영되어 통합되는 것을 의미한다.

CD(Continuous Deployment)는 지속적 배포를 의미하며, 소프트웨어에 변동사항이 생겼을 때 이를 지속적으로 반영하여 서비스 환경을 중단하지 않고 바로 배포하는 것을 의미한다.

대표적인 CI/CD 툴로는 gitHubAction, Jenkins 등이 있는데, 코드 저장소에 변동이 일어날 때마다 그걸 반영하여 도커 이미지를 만들고, 서버에서 새롭게 만들어진 이미지를 내려받아 컨테이너로 실행하는 모든 과정을 자동화 해준다.

이 도구들은 도커를 필수로 사용하기 때문에 마찬가지로 큰 장점이다.

실제로 프로젝트를 진행하다보면 이제 더 이상 수정할 게 없겠지? 싶어도 변동사항이 계속해서 생기기 마련이다. 심지어 운영 과정에서도 변동사항은 꾸준히 생긴다. 그럴 때 CI/CD 파이프라인의 중요성을 몸소 느꼈고, 도커는 서버 개발자라면 꼭 한 번쯤 사용해 봐야하지 않나 싶다.

 

 

Reference

https://www.samsungsds.com/kr/insights/docker_container.html

'인프라 > Docker' 카테고리의 다른 글

EC2 인스턴스에 Docker 설치하기  (0) 2024.07.22
SpringBoot 프로젝트 Docker 로 EC2에 배포하기  (0) 2024.07.22

AWS EC2에 Docker 를 설치하는 과정을 기록하고자 한다.

환경은

Ubuntu Server 24.04 LTS 기준

 

먼저 도커를 설치하는 과정이다.

sudo apt-get update

sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io

 

1. https 통신을 통해 외부 데이터 및 패키지에 접근할 수 있는 기능들을 설치한다.

2. curl 명령어를 통해 설치관리자(apt)의 identify key 값을 통해서 서버에 Docker 저장소를 설치한다.

3. 설치관리자에다 Docker Repository 경로를 추가하고

4.install 명령어를 통해 도커를 설치한다.

 

sudo 명령어는 관리자 권한을 부여하는 명령어로, putty 와 같은 프로그램으로 SSH 연결을 통해 작업을 한다면, 꼭 붙여줘야 Permisson Denied 오류가 뜨지 않기에 주의해서 꼭 붙여줘야한다.

AWS 웹 콘솔로 접속 하게되면 웬만해선 필요없을 수 있다. 그래도 Permisson Denied 가 뜨면 한번 붙여보자

 

설치한 도커를 확인하는 과정이다. 

sudo systemctl status docker

해당 명령어를 통해 설치되어있는 docker 정보를 확인할 수 있다.

 

 

도커 허브를 통해 실행하고자 하는 서버 이미지를 pull 즉 해당 환경에 불러오는 과정이다.

sudo docker search 이미지 이름

sudo docker pull 이미지 이름[:버전]

search 명령어를 통해 찾고자하는 이미지가 있는지 찾고, pull 명령어를 통해 해당 이미지를 서버에 다운받는다.

버전 같은 경우 따로 명시하지 않으면 latest 버전을 받게 된다.

 

 

불러온 이미지를 이용하여 새롭게 컨테이너를 만들어 실행하는 과정이다.

sudo docker run -p [호스트 포트]:[컨테이너 포트] -d -it --name {컨테이너 이름} {이미지 이름} sleep infinity

run 명령어를 통해 다양한 옵션을 부여하여 컨테이너를 실행시킬 수 있다.

 

-p : 포트를 바인딩해주는 옵션이다. (필수)

[외부에서 접속하는 포트] : [컨테이너 내부에서 사용할 포트] 이렇게 포트를 지정해주어야한다.

스프링 부트 서버라면, 컨테이너 내부에서 스프링 부트 애플리케이션이 주로 8080 포트로 열리고, 또 일반적으로 로 스프링부트 서버는 8080 포트를 이용하기 때문에 외부에서 접속할 포트 또한 8080 으로 해주는 것이 적절하다. 고로 스프링부트 서버를 실행시킬 예정이라면 8080:8080 옵션을 보통 부여해주는 것이 좋고 만약 안된다면 오른쪽 포트가 스프링 부트가 실행중인 포트와 정확히 일치하는지를 꼭 확인해봐야한다.

 

-d : daemon으로 실행, 즉 백그라운드(background)로 실행하도록 지정해주는 옵션이다. (필수)

스프링부트 서버는  요청이 들어올 때마다 적절한 응답을 반환해야하기에 포어그라운드(foreground)에서 사용자의 입출력과 상관없이 항상 실행되어야 하기 때문에 백그라운드 방식으로 실행되어야하기에 이 옵션을 꼭 붙여주어야한다.

 

-it : 이 옵션은 컨테이너 외부 터미널에서 해당 컨테이너에 사용자의 입력과 출력을 전달하기 위한 옵션이다.

컨테이너 내부에 접속하여 쉘 등의 CLI 도구를 통해 작업을 해야할 경우에 필요한데, 웬만하면 필요한 경우가 많으니 꼭 붙여주자.

 

-v : docker 볼륨을 지정하는 옵션이다.

--rm : 컨테이너 실행이 종료되면 컨테이너가 자동으로 삭제되도록 하는 옵션이다. 

--name : 컨테이너의 이름을 설정하도록 하는 옵션이다. (필수)

--net : docker 네트워크를 지정하는 옵션이다.

 

sleep infinity : -d 옵션을 통해 백그라운드로 실행을 했다고 하더라도, entrypoint 나 cmd가 설정되어 있지 않은 이미지 일경우 컨테이너가 바로 종료되는데, 이를 방지해줄 수 있는 옵션이다. (필수)

웬만하면 우리가 직접 개발한 스프링 프로젝트를 통해 이미지를 만들텐데, 그때 entrypoint 나 cmd 를 지정하지 않을 경우가 많을 것이기 때문에 거의 필수적으로 필요한 옵션이다.

 

그 외 기타 명령어들이다.

sudo docker ps -a

sudo docker restart [컨테이너 명]

sudo docker stop [컨테이너 명]

sudo docker start [컨테이너 명]

sudo docker rm [컨테이너 명]

sudo docker rmi [이미지 명]

 

 

ps 명령어를 통해 지금 실행중인 컨테이너를 확인할 수 있고 -a 옵션을 통해서 정지된 컨테이너 까지 확인할 수 있다.

 

restart 명령어를 통해서 실행중인 컨테이너를 중지했다가 다시 실행시킬 수 있다.

 

stop, start 명령어를 통해서 실행을 중지하거나 실행할 수 있다.

 

rm, rmi 를 통해 컨테이너와 이미지를 삭제할 수 있다.

'인프라 > Docker' 카테고리의 다른 글

Docker 란?  (0) 2024.07.25
SpringBoot 프로젝트 Docker 로 EC2에 배포하기  (0) 2024.07.22

열심히 개발한 SpringBoot 프로젝트를 Docker 를 사용하여 EC2 배포 서버에 배포해보자!

Why Docker?

docker 를 사용하는 데에는 정말 다양한 이점이 있다. 이에 관해서 포스팅한 내용이 있다.

https://himodu-tech.tistory.com/12

 

직접 개발한 스프링부트 프로젝트를 도커를 통해 배포하기 위해선 다음과 같은 과정이 필요하다.

0. 로컬 환경에 Docker 를 설치한다. (잘 나와있는 자료들이 많아서 생략)

1. 프로젝트 내에 jar 실행파일을 만든다.

2. 프로젝트 내에 Dockerfile 을 만들어 Docker 가 해당 jar 파일을 찾을 수 있도록 한다.

3. 프로젝트에서 터미널을 열어 Docker 명령어를 통해 이미지를 build 한다.

4. build 한 이미지를 Docker Hub 에 공유한다. 

5. 준비된 서버에서 Docker Hub 에 공유된 이미지를 다운(pull)받는다. (서버에는 도커가 설치되어야함)

6. 다운받은 이미지를 가지고 컨테이너를 실행한다.

 

과정이 조금 길다. 차례차례 살펴보도록 하자

 

1. 프로젝트 내에 jar 실행파일 만들기

jar 실행파일이란 java 애플리케이션 실행을 위한 모든 파일들을 압축해놓은 하나의 실행가능한 파일로써

흔히 '자르' 라고 부른다.   (교수님들도 그렇게 부르시더라... '자~ㄹ' 파일이라고 부르면 좀 어색해보인다.)

jar 실행파일을 만드는 방법은 gradle 을 사용한다면 매우 간단하다. 

먼저 인텔리제이 우측상단에 코끼리 모양  gradle 아이콘을 누른 다음 tasks -> build -> bootJar 를 선택

그럼 밑에 콘솔 창에서 실행결과를 확인할 수 있고

프로젝트 내에 build/lib 하위 경로에 실행파일이 생성된다.

 

2. 프로젝트 내 Dockerfile 생성

프로젝트 최상단에 새로운 파일을 만들고 이름을 'Dockerfile' 이라고 지어준다. 토씨 하나도 틀려선 안된다.

 (최상단이 아니어도 좋지만, 이러한 경우 build 시에 경로를 따로 명시해줘야하기 때문에 귀찮다.)

Dockerfile 의 내용은 아래와 같다.

FROM openjdk:17-jdk-alpine

ARG JAR_FILE=build/libs/*.jar

COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

Dockerfile 이 하는 일은 Docker 가 이미지를 빌드할 때의 정보를 제공해주는 것이다.

위에서 부터

만들 이미지의 기초가 될 java 이미지를 선택하고, (버전을 꼭 맞춰줘야한다.)

jar 파일의 위치를 매개변수로 저장하고

app.jar 라는 이름의 jar 파일로 이를 복사한 다음

'java -jar /app.jar' 라는 명령어를 해당 이미지의 ENTRY POINT 로 설정한다.

ENTRY POINT란 이 이미지를 바탕으로 컨테이너를 실행하는 그 순간 초기에 실행할 명령어를 의미한다.

 

3. 터미널을 열어 docker 명령어를 통해 이미지를 빌드한다.

docker build -t {도커허브 이름}/{이미지 이름} .

프로젝트 최상단 경로에서 터미널을 열고, 위와 같은 명령어를 입력한다.

여기서 중요한 것은!

이미지의 이름을 정해줄 때 DockerHub에서 사용하는 이름을 앞에, 해당 이미지의 이름을 뒤에 적어줘야 한다는 것이다.

해당 이미지의 이름은 얼마든지 겹칠 수 있으니 이를 식별하기 위해서 앞에 자신의 DockerHub 이름을 붙여주는것이다.

그리고 중요한 것은 마지막에 '.' 이걸 꼭 찍어주자. 이 점이 의미하는 것은 해석할 Dockerfile 이 있는 위치이다.

우리는 방금 최상단에 Dockerfile 을 만들었기 때문에 현재 위치('.')에서 찾을 수 있지만, 만약 다른 곳에 있다면 여기에 도커파일이 있는 파일경로를 적어줘야한다.

 

4. build 한 이미지 DockerHub에 업로드

Docker를 설치했다면, DockerDesktop 또한 설치되었을 것이다. GUI 로써 도커를 훨씬 편히 이용할 수 있으니 사용하는 것을 추천한다. 그리고 DockerHub 에 꼭 로그인 해주자.

하단에 'Not connected to Hub' 이라고 뜬다면

우측상단에 Sign In 버튼을 눌러 로그인할 수 있다. 소셜 로그인을 지원하기 때문에 어렵지 않을 것이다.

하여튼 성공적으로 이미지가 빌드됐다면, DockerDesktopimages/Local에 이미지가 보일 것이다.

배포할 이미지의 좌측에 세로 점 3개 버튼을 누르고 'push to Hub' 를 선택하면, Docker Hub에 업로드 되며, DockerDesktop 에 'images/Hub ' 에서 확인할 수 있다.

 

5 ~ 6 과정은

서버에 도커를 설치하고, Hub에 올라간 이미지를 다운받아 그대로 컨테이너를 실행하는 과정이고

따로 포스팅한 내용이 있다. 아래 링크를 참고하면 된다.

https://himodu-tech.tistory.com/10

 

 

아래 영상은 전 과정을 영상으로 기록한 내용이다. (영상이 안뜬다면? = https://www.youtube.com/watch?v=X6Fb6pT11eo)

'인프라 > Docker' 카테고리의 다른 글

Docker 란?  (0) 2024.07.25
EC2 인스턴스에 Docker 설치하기  (0) 2024.07.22

+ Recent posts