Docker 의 개념 및 핵심 설명

좐쓰 ㅣ 2024. 6. 13. 19:26

반응형

docker 의 상징 고래

Docker 란 Go 언어로 작성된 Linux 컨테이너 기반의 오픈소스 가상화 플랫폼이다.

 

 

컨테이너란?

컨테이너는 가상화 기술 중 하나로 대표적인 컨테이너는 Linux Container (이하 LXC) 가 있다. 

기존 OS 가상화와는 달리 컨테이너는 OS 레벨의 가상화로 프로세스를 격리시켜 동작하는 방식 으로 이루어진다.

한 서버의 여러 OS 를 가상화 하는 것과 컨테이너 방식으로 프로세스를 격리시켜 동작하는 방법은 어떠한 차이점이 있을까?

 

컨테이너와 VM (가상머신) 의 차이

 

좌) VM 방식 우) 컨테이너 방식

 

기존에 우리에게 익숙한 VM 같은 경우엔 Host OS(운영체제) 위에 가상화를 시키기 위한 Hypervisor 엔진 그리고 그 위에 Guest OS 를 올려 사용한다. 이는 가상화된 하드웨어 위에 OS가 올라가는 형태로 거의 완벽하게 Host 와 분리된다고 봐도 무방하다. 반면에 컨테이너 기반 가상화는 Docker 엔진 위에 Application 실행에 필요한 바이너리가 올라가게 된다. OS 가상화를 보면 Host OS 와 완전히 분리되는 장점은 있찌만 OS 위에 OS 를 올리기 때문에 무겁고 느릴 수 밖에 없다. 하지만 컨테이너 기반 가상화는 Host OS 그리고 Docker 엔진 위에서 바로 동작하며 Host 의 커널(운영체제의 핵)을 공유한다. 

커널을 공유하게 되면 io 처리가 쉽게 되어 성능의 효율을 높일 수 있다.

컨테이너를 사용하는 것은 가상 머신을 생성하는 것이 아니라 HOST OS가 사용하는 자원을 분리하여 여러 환경을 만들 수 있도록 하는 것이다.

 

그러면 다들 컨테이너기반 가상화를 쓰지 VM 은 왜씀...?

위에서 정리한 내용 대로면 컨테이너기반이 OS 가상화보다 뛰어나다라고 말하는 것 같지만 실제로 그렇지만은 않다.

단지 이 포스팅이 Docker 를 소개하는 글이다 보니 컨테이너 기반 가상화의 장점을 강조하여 Docker 를 왜 사용해야하는지에 대해 설명을 한 것 뿐이다.

 

VM 을 이용한 OS 가상화는 컨테이너기반 가상화보다 더 높은 격리 레벨을 지원한다. (하드웨어를 다른 걸 쓰는 거랑 같은 원리니 어찌보면 당연하다) 이는 자연스레 보안적인 측면에서 더욱 유리하게 작용한다.

또한 커널을 공유하지 않는 것이 장점으로 작용한다. 커널을 공유하지 않는 만큼 멀티 OS가 가능하다는 것이다. 커널을 공유하지 않아 멀티 OS 가 가능하다는 것이다. 

그럼에도 Docker 를 쓰는 이유는 '성능향상', '뛰어난 이식성', '손쉽게 Scale Out 이 가능한 유연성' 

 

 

Docker Image

 

Docker Image 란 컨테이너를 실행할 수 있는 실행파일, 설정 값 들을 가지고 있는 것이라고 생각하면 된다.

그림과 같이 Image 를 컨테이너에 담고 실행을 시킨다면 해당 프로세스가 동작을 하게 되는 것이다.

그럼 어떻게 이미지가 만들어지는가?

 

 

ubuntu 이미지를 만들기 위해 Layer A,B,C 가 들어간다.

그럼 nginx 이미지를 만든다고 생각했을땐 어떻게 될까?

 

이미  Layer A,B,C 로 만들어진 ubuntu 이미지를 베이스 이미지로 사용하여 베이스 이미지에 nginx 만 더하게 된다.

그렇다면 실질적으로 Layer A,B,C + nginx 가 더해진 것이지만 과정은 ubuntu + nginx 가 더해진 것이다.

 

그렇다면 web app 이미지를 만들려고 할 때는??

ubuntu 이미지에 nginx 를 올리고 web app 을 올리는게 아닌 이미 만들어진 nginx 베이스 이미지에 web app 을 올려 이미지를 만든다. 

 

Docker  파일

Docker Image 들을 저장하고 배포하는 Docker Hub 는 정말 잘 활성화가 되어있다.

이미 여러 회사들은 SW 를 Docker Hub 를 통해 배포하기 시작했고 우린 Docker Hub 에서 image 를 pull 하여 간단하게 컨테이너에 넣어 사용할 수 있다.

 

만약 배포판이 없거나 보완하고 싶다면? Docker File 을 사용한다.

Docker File 은 이미지 생성 출발점으로 이미지를 구성하기 위한 명령어들을 작성하여  image 를 구성할 수 있다. 그 뜻은 Docker File 을 읽을 수만 있다면 해당 image 가 어떻게 구성되어 있는지도 알 수 있다는 의미이다.

 

FROM openjdk:8-jdk-alpine 
ARG JAR_FILE=example-0.0.1-SNAPSHOT.jar
EXPOSE 60431
COPY ${JAR_FILE} myboot.jar
WORKDIR /opt
ENTRYPOINT ["java","-jar","/myboot.jar"]

 

각 명령어를 뜯어서 본다면

  1. FROM : 생성할 image 의 베이스 이미지를 지정해준다.
  2. ARG : 변수를 선언한다. 
  3. EXPOSE : 생성된 image 로 컨테이너를 구동할 때 어떤포트로 사용하는지 알려준다. EXPOSE 를 사용한다고 해서 컨테이너를 구동할 때 자동으로 해당 포트를 호스트 포트와 연결하지 않는다. 외부와 연결하려면 지정한 포트를 호스트 포트와 연결해야한다는 정보를 제공할 뿐이다. 
  4. COPY : 호스트에서 새로 생성하는 컨테이너 image 로 필요한 파일을 복사한다.
  5. WORKDIR : 현재 작업 위치를 opt 디렉토리로 변경한다.
  6. ENTRYPOINT : ["명령어","옵션" ,"옵션" ..."옵션" ] 의 형식이다. 컨테이너 구동 시 ENTRYPOINT 뒤에 나오는 대괄호 안에 든 명령을 실행한다. 첫번째 문자열은 명령어이고 두번째 문자열부터 명령어를 실행할 때 추가하는 옵션이다.  

 

이 과정까지 끝나고 docker build 를 하게 되면 image 가 생성이 된다. 여기서 캐시를 비활성화 하려면 --no-cache 를 추가하면 된다. 

 

docker-compose.yml

지난번 포스팅 했던 yml 파일로 docker 의 컨테이너를 통합하여 관리한다.

docker-compose.yml 파일을 이용하면 컨테이너를 쉡게 생성할 수 있다. 

다른 블로거분이 스프린트 간 사용했던 예제를 통해 간단하게 구조를 파악해보자

version: "3.0"

service:
	frontend:
    	build: frontend
        image: liveloper/client
        ports:
        	-target: 80
             publishes: 80
             x-aws-protocol: http
        depends_on:
        	-backend
            
    backend:
    	build: backend
        image: liveloper/server
        ports:
        	-target: 3333
             publishes: 3333
             x-aws-protocol: http

 

 

위 과정이 모두 끝나면 아래의 두 명령어를 실행하면 빌드 및 컨테이너 생성이 완료된다.

// docker image build
sudo docker-compose build

// compose up
sudo docker-compose up

 

 

참고 블로그 : 일상을 개발하는, liveloper jay / CV DOODLE 님의 블로그

https://liveloper-jay.tistory.com/92

 

[Docker] Dockerfile을 이용한 이미지 빌드 예제 (+ docker-compose)

Summary Docker 이미지 생성은 다음과 같이 할 수 있습니다.(제가 모르는 방법이 있다면 댓글로 알려주시면 감사하겠습니다!) 1. pull을 이용하여 docker hub로부터 이미지 다운로드 // 이미지 pull sudo docke

liveloper-jay.tistory.com

https://mvje.tistory.com/170

 

개념과 예제만으로 주루룩 갈기다 보니 막연했던 docker 에 대해서 어느 정도 개념은 잡히는 듯 했다.

 

하지만 체술형 개발자인 나는 아마 실제로 코드를 적용해보면서 배우는게 더 많을거 같다.

당분간 git 이던 app 이던 잠시 쉬어가며 docker 고래사냥을 떠나봐야겠다.

 

가자~!!

 

 

반응형

'DevOps > Docker' 카테고리의 다른 글

Docker 컨테이너 전부 삭제 명령어  (0) 2024.09.10