[도커] 가상머신과 도커 컨테이너

youngseo·2022년 12월 23일
0

AWS

목록 보기
3/4

Docker

1. 가상머신

가상머신을 사용하게 되면 하나의 컴퓨터(또는 서버)에서 여러 os를 사용을 할 수 있습니다.

hypervisor가 가상머신을 생성하고 구동하는 소프트웨어가 됩니다. 대표적인 hypervisor로는 버츄얼박스(virtualBox)와 브이엠웨어(VMware)가 있습니다.

하지만 이 hypervisor을 통해 서비스(앱)을 올릴때는 Guest OS라는 것이 필요합니다. 이 Guest OS가 존재하지 않고서는 그 위에 커널이 존재를 할 수가 없습니다.

그렇지만 이런 경우 이미지를 만들기 위한 용량이 너무 커져, 어플리케이션의 무게도 무거워지고 수정도 어려워지게 됩니다.

2. Docker

하지만 도커를 사용하게 되면, 도커가 이 hypervisor자리에 들어가게 되며 더이상 Guest OS가 존재를 하지 않게 됩니다.

또한 도커엔진은 리눅스의 자체 엔진을 사용해 프로세스 단위의 격리환경을 만들게 됩니다.
(기존의 hypervisor가 컴퓨팅 자원을 기존의 독립된 공간마다 잘라서 사용을 했다면, 도커의 경우 프로세스 단위로 잘라서 사용을 하게 되어 성능 손실이 거의 발생하지 않습니다.)

그리고 각각의 컨테이너에서 필요한 커널을 호스트의 커널과 공유하여 사용을 하기 때문에, 컨테이너 이미지 용량이 작아지며 성능손실이 줄어들게 됩니다.

커널이란
os에서 가장 핵심이 되는, 프로그램. 커널이 컴퓨터의 모든 것을 통제할 수 있는 프로그램이기 때문에 커널이 없으면 동작을 할 수가 없습니다. 즉, 최상위 프로그램이라고 할 수 있습니다.

컴퓨터의 cpu, 메모리, 디바이스(플로피디스크, 마우스 입력장치, 키보드 등)에 다 에세스 할 수 있으며 관리를 할 수 있습니다.

즉, 커널은 시스템을 보호하기도 하며 프로세스가 처리되는 순서를 정하기도 하며 하드웨어에 접근하는 것을 관리하기 위해서 하드웨어 위에서 추상화가 진행된 형태로 처리를 해줍니다.

결론적으로 커널이란 os에 굉장히 필요한 프로그램입니다. 도커를 사용하게 되면 이 커널을 공유를 하기 때문에 전체 이미지 하나하나가 작아지게 됩니다.

아울러 웹 에플리케이션을 올릴 때 vm을 사용하는 경우 os자체가 업데이트 되어야 해 배포 속도가 다소 걸렸다면 도커는 배포속도가 매우 빠릅니다.

도커의 장점

  1. 컨테이너 이미지의 용량이 적다.
  2. 배포 속도가 빠르다.
  3. 가상화된 공간을 사용할 때 성능손실이 적다.

하지만 이 세개의 강점은 hypervisor을 사용할 때와 비교했을 때의 상대적인 강점입니다.

그렇다면 웹어플리케이션 관점에서의 강점은 어떤 것이 있을 지를 살펴보도록 하겠습니다.

3. 웹어플리케이션 관점에서의 Docker의 강점

먼저, 마이크로서비스 구조를 구축할 수 있기 때문에 독립성과 확장성을 가지게 됩니다.

위와 같이 하나의 컨테이너에는 웹서버들이 존재하고 다른 하나에는 db데이터 들이 존재하는 두개의 컨테이너가 있다고 가정을 해봅시다.

로드가 발생을 하는 경우 웹서버가 스케일 아웃을 통해 n번째 서버까지 확장을 하게 될 것입니다.(데이터베이스도 마찬가지)

이를 도커를 구현하게 되면 각각의 컨테이너에 딱 한종류의 최적화된 서버만 올릴 수 있게 됩니다.
(즉, 컨테이너 A에는 node.js로만 돌아가는 웹서버를 그리고 컨테이너B에는 MySQL만 깔려있게 됩니다.)

이런 경우 두개의 컨테이너가 서로 영향을 주지 않게 된다는 장점이 있지만, 하나의 서버에 합쳐에 합쳐서 올리게 되면 굉장히 복잡하게 됩니다.

도커에서는 컨테이너별로 분리되고 독립적으로 관리하는 구조를 제공하고 있기 때문에 이러한 이슈들을 도커를 사용하게 되면 굉장히 깔끔하게 독립적으로 사용을 할 수 있게 됩니다.

또한 Docker swarm, Kubernetes과 같은 컨테이너 오케스트레이션 플랫폼을 사용하면 마이크로서비스 구조를 구현하는것이 매우 간편해지게 됩니다.

4. 도커설치

4-1 확인할 부분

  1. 최신 버전 커널 확인

커널 버전 3.10 이상인지 확인을 합니다.

$ uname -r
  1. 일부 리눅스는 업데이트 지원이 없을 수 있다.
  2. 64비트 리눅스
  3. 루트권한이나 수도 명령을 할 수 있어야 한다.

4-2 설치하기

4-3 이미지란?

npm i를 통해 패키지를 설치하는 것과 같이 도커 역시 도커허브라는 중앙저장소에서 이미지를 다운로드 받아옵니다.

즉, 도커 엔진에서 docker pulldocker push를 통해 코드를 공유할 수 있습니다.

예시로 docker search ubuntu를 통해 도커허브에 있는 이미지를 검색해보면,

위와 같이 수많은 검색 결과를 확인할 수 있습니다. 즉 OFFICIAL이 아닌 수많은 이미지들이 있습니다.

따라서 가져올 때 OFFICIAL인지, 정확한 이름도 확인해봐야합니다.

또한 이미지란 개발환경 그 자체로 코드 실행환경이 통일되기 때문에 로컬 개발환경과 실제환경이 달라서 생기는 문제를 상당수 예방할 수 있습니다.

단, 이미지만 맞춰서 이 문제(버전 차이 등으로)를 모두 방지하기는 어려울 수 있는데, 도커 파일을 통햏 소프트웨어 버전까지도 맞춰줄 수 있습니다.

4-4 도커파일

앞서 안내드린 것과 같이 이미지만으로는 충분하지 않기 때문에 도커파일을 통해 세부설정들까지(소프트웨어 버전, 어떤 명령을 내릴건지 등등)까지 동일하게 맞춰줄 수 있습니다.

즉, 도커파일이란 이미지를 빌들하는데 필요한 모든 명령을 순서대로 포함하는 텍스트 파일입니다.

# syntax=docker/dockerfile:1

FROM UBUNTU:18.04
COPY ./app
RUN make /app
CMD python /app/app.py
  • FROM: 도커이미지에서 레이어를 만드는 명령어
  • COPY: 클라이언트의 현대 디렉토리에 파일을 추가하는 명령어
  • RUN: 위 예시의 경우 make라는 명령어를 함께 써 앱을 빌드하는 명령어
  • CMD: 위 예시의 경우 파이썬으로 어떤 코드를 실행한다. 즉, 커멘드 명령어

4-5 도커 컨테이너

컨테이너 하나하나는 모두 독립된 공간으로 시스템 자원도 구분되어서 있어 서로 영향을 받지 않습니다.

만약, 컨테이너 안에 아파치 또는 엔진엔스 웹서버를 넣어둔 상태에서 사용자가 너무 많아 성능이 잘 안나오는 경우, 도커 안에서 웹서버 컨테이너를 복사해 늘려줄 수도 있습니다.

또한 컨테이너 안에서 일어나는 행위는 다른 컴퓨터에 영향을 주지 않습니다. 설령 컨테이너 한개가 멈췄다고 해 다른 컨테이너가 영향을 받거나 하지 않습니다.

즉, 컨테이너의 경우 어플리케이션이 올라가는 공간이며 컨테이너끼리는 모두 독립된 공간입니다.


5. 컨테이너 사용해보기

5-1 컨테이너 생성

docker run -i -t [이미지]

(만약 이미지가 없는 경우 도커 허브에 있는 이미지를 가지고 옵니다.)

//i의 경우 상호작용을 의미, t의 경우 tqi를 열어주는 것을 뜻합니다(bashshell을 쓸 수 있는 것).
$ docker run -i -t ubuntu:14.04

-> 이제 우분트와 똑같은 환경이 만들어졌습니다.
-> 나가는 방법 - ctrl + p,q (이경우 터미널 상태는 유지하면서, 터미널만 빠져나감) - exit (명령을 아예 끌 수 있습니다.)

5-2 명령어 정리

$ docker run -i -t [이미지]

// 로컬에 어떤 이미지들이 있는지를 확인
$ docker images

$ docker search [이미지]

$ docker stop [이미지]

//제거
$ docker rm [이미지]

5-3 실습

//wordpress : 전세계에서 가장 많이 쓰이는 CMS(Contents Menagement System)툴
$ docker search wordpress

$ docker pull wordpress

$ docker run --name fastcampus-docker -p 8000:80  -d wordpress

5-4 실습: 노드제이에스 앱 만들기

1. 새 레포지토리에서 시작

$ npm init

package.json

"scripts": {
    "start": "node index.js"
}

2. 필요한 패키지 설치 및 파일 생성

$ npm i express
$ touch index.js
$ touch Dockerfile
$ touch .dockerignore

index.js

const express = require("express");

const PORT = 8080;
const HOST = "0.0.0.0";

const app = express();

app.get("/", (req, res) => {
  res.send("나는 도커를 매우 잘 이해하고 있다.");
});

app.listen(PORT, HOST, () => {
  console.log(`Server is running on http://${HOST}:${PORT}`);
});

Dockerfile

FROM node:16.14.2

WORKDIR /usr/src/app

# 패키지와 관련된 모든 정보를 가지고 와 복사 붙여넣기를 할 것이다.
COPY package*.json ./

RUN npm install

# 모든 파일들을 복사 붙여넣기
COPY . .

# index.js에서 작성한 PORT를 외부에 노출시켜줌
EXPOSE 8080

# node를 사용해 index.js를 실행시킬 것이다.
CMD ["node", "index.js"]

.dockerignore

node_modules

3. 빌드

$ docker build . -t fastcampus-docker/node-web-app

$ dcoker run --name fc-docker -p 47651:8080 -d fastcampus-docker/node-web-app

0개의 댓글