본문 바로가기
Development/Docker

도커(docker)란?

by 드로니뚜벅이 2022. 4. 19.

윈도우에서 VirtualBox, VMWare나 Hyper-V와 같은 가상 머신을 통해 리눅스 운영체제를 설치해 본 경험이 있으실 겁니다. 가상 머신이 사용하기 편하긴 하지만 하드웨어를 가상화해서 실행되기 때문에 성능이 좋지 않을 뿐만 아니라 실행 이미지에는 게스트 OS라는 운영체제를 통째로 포함해야 하기 때문에 용량 크기도 꽤 큰 편입니다. 가상 머신을 생성할 때 CPU, RAM, LAN 카드 및 사운드 카드와 같은 하드웨어 정보를 설정합니다. 말 그대로 가상 머신은 컴퓨터 안에 만들어진 또 다른 컴퓨터를 소프트웨어로 가상화합니다.

반면에 도커(Docker)게스트 OS를 설치하지 않고 내가 필요한 프로그램과 관련 라이브러리만 격리해서 설치하기 때문에 성능과 용량이라는 두 마리 토끼를 다 잡은 샘입니다. 도커는 하드웨어를 가상화하는 계층이 없기 때문에 메모리 접근, 파일시스템, 네트워크 속도가 가상 머신에 비해 월등히 빠릅니다. 아래 표는 Docker 1.1.2에서 우분투 14.04 호스트와 우분투 14.04 Docker 컨테이너의 성능을 측정한 결과입니다. 수치상으로 호스트와 Docker 컨테이너 사이의 성능차이는 크지 않습니다. 호스트와 거의 동일한 속도라 할 수 있습니다.

성능 측정 항목 성능 측정 도구 호스트 도커
CPU sysbench 1 0.9945
메모리 쓰기 sysbench 1 0.9826
메모리 읽기 sysbench 1 1.0025
디스크 I/O dd 1 0.9811
네트워크 iperf 1 0.9626

Docker는 가상 머신과는 달리 이미지 생성과 배포에 특화된 기능을 제공합니다. Git에서 소스를 관리하는 것처럼 이미지 버전 관리 기능을 제공합니다. 또한, 중앙 관리를 위해 저장소에 이미지를 올리고, 받을 수 있습니다(Push/Pull). 그리고 GitHub처럼 Docker 이미지를 공유할 수 있는 Docker Hub도 제공합니다(GitHub처럼 유료 개인 저장소도 제공합니다).

다양한 API를 제공하기 때문에 원하는 만큼 자동화를 할 수 있어 개발과 서버 운영에 매우 유용합니다.

 

도커(Docker)란...

도커는 응용프로그램을 신속하게 구축 및 테스트하고 배포할 수 있는 소프트웨어 플랫폼입니다. 소프트웨어를 컨테이너라는 표준화된 유닛으로 패키징하며, 컨테이너는 라이브러리, 시스템 도구, 코드 등 소프트웨어 실행에 필요한 모든 것이 포함되어 있습니다.

즉, 도커컨테이너 환경에서 독립적으로 응용프로그램을 실행할 수 있도록 컨테이너를 만들고 관리하는 것을 도와주는 도구입니다. 도커를 통해 응용프로그램을 실행하면 독립적인 환경에서 일관된 결과를 보장합니다. 도커의 핵심 개념이미지컨테이너입니다.

 

도커의 장점

  • 한 대의 물리 서버에 여러 대의 서버를 띄울 수 있습니다. 격리된 환경을 제공하므로 프로그램이 안전한 상태로 실행되며 동일한 프로그램을 여러 개 실행할 수 있습니다.
  • 커널을 포함하지 않기 때문에 가상화 기술에 비해 가볍습니다.
  • 서버 관리가 용이합니다.

도커의 단점

  • 리눅스용 소프트웨어만 지원합니다. (Windows 시스템 내에서에서 윈도우용 컨테이너를 지원하기도 합니다.)
  • 호스트 서버에 문제가 발생할 경우 모든 컨테이너에 영향을 미칩니다.
  • 컨테이너 하나를 장기간 사용할 경우 도커를 사용하는 의미가 없을 수 있습니다.

도커의 용도

  • 프로젝트 구성원에게 동일한 개발환경을 제공할 수 있습니다.
  • 격리된 환경을 제공하므로 운영체제나 라이브러리의 새로운 버전을 테스트할 수 있습니다.
  • 동일한 서버를 필요한 만큼 여러 대 실행할 수 있습니다.

 

컨테이너(Container)

도커 컨테이너의 모태가 된 LXC(LinuX Container)는 컴퓨터 하드웨어를 가상화하여 운영체제를 실행하는 것이 아닌 리눅스 커널 레벨에서 제공하는 일종의 격리된(Isolated) 가상 공간입니다. 이 가상 공간에는 운영체제가 설치되지 않기 때문에 가상 머신이라 하지 않고 컨테이너라 부릅니다.

컨테이너는 격리된 공간에서 프로세스가 동작하는 기술입니다. 기존의 가상화 방식인 운영체제 가상화가 아닌 프로세스를 격리하는 방식으로 동작합니다. 리눅스에서 프로세스를 격리하는 방식을 리눅스 컨테이너라고 합니다. 단순히 프로세스를 격리하기 때문에 가볍고 빠릅니다. 또한 CPU나 메모리는 프로세스가 필요한 만큼만 추가 사용하여서 성능적으로 거의 손실이 없습니다.

다음 그림은 도커와 가상머신을 나타낸 것 입니다.

현재 윈도우 운영체제를 사용한다고 할 때 리눅스와 같은 다른 운영체제를 사용하고 싶을 때 주로 가상머신(VM)을 사용해서 OS 전체를 가상화하는 방식을 사용했습니다. 그럴 경우 윈도우라는 운영체제와 리눅스라는 운영체제가 완전히 독립적으로 하나의 머신에서 운영되고 있는 경우입니다. 그렇기 때문에 시스템 자원을 나눠 사용하다 보니 속도가 엄청나게 느려지고 설치 용량 또한 엄청 커지는 문제가 있습니다. 반면에 컨테이너는 VM을 사용하지 않고 도커 엔진을 사용하여 동작하는 개선된 프로세스 격리 방법으로 성능적인 개선과 동시에 메모리 용량도 훨씬 적게 사용하게 됩니다.

 

컨테이너 특징은 다음과 같습니다.

  •  서버에 여러 컨테이너를 실행하면 독립적으로 실행되어 가상머신을 사용하는 느낌을 줍니다.
  •  실행 중인 컨테이너에 접속하여 명령어를 입력할 수 있습니다.
  •  패키지 매니저(APT 등)를 통해 설치할 수 있고 사용자도 추가하고 프로세스를 백그라운드로 실행할 수 있습니다.
  •  CPU나 메모리 사용량을 제한할 수 있습니다.
  •  호스트의 특정 포트와 연결하거나 호스트의 특정 디렉토리를 내부 디렉토리인 것처럼 사용 가능합니다.
  •  새로운 컨테이너를 만드는데 1~2초로 매우 빠릅니다.

 

이미지 (Image)

컨테이너 실행에 필요한 파일과 설정을 포함하고 있는 것으로 상태값을 가지지 않고 변하지 않습니다. 컨테이너는 이미지를 실행한 상태이며 추가되거나 변하는 값은 컨테이너에 저장됩니다. 같은 이미지에서 여러 개의 컨테이너를 만들 수 있고 컨테이너의 상태가 바뀌거나 삭제되어도 이미지는 변하지 않고 그대로 남아 있습니다. 도커 이미지는 도커허브(Docker Hub)에 등록하거나 도커 레지스트리(Docker Registry) 저장소를 직접 만들어 관리할 수 있습니다.

 

이미지 특징은 다음과 같습니다.

  • 도커 이미지의 용량은 보통 수백 MB ~ 수 GB이지만 가상머신에 비하면 작은 용량입니다.
  • 상태값은 가지지 않고 변하지 않습니다.
  • 하나의 이미지를 통해 여러 컨테이너를 생성할 수 있고, 컨테이너를 삭제해도 이미지는 변하지 않습니다.
  • 이미지들은 도커허브를 통해 버전 관리 및 배포가 가능합니다.
  • 도커는 Dockerfile이라는 파일로 이미지를 만듭니다.

 

Dockerfile

도커 이미지를 만들기 위해 Dockerfile이라는 파일에 DSL(Domain Specific Language) 언어를 이용해 이미지를 생성할 수 있습니다. 단순 텍스트 파일로 일반적으로 소스와 함께 관리됩니다. 서버에서 프로그램을 설치하려고 할 때 Dockerfile을 통해 관리하면 됩니다. Dockerfile에서 사용할 수 있는 키워드는 20개 정도 있습니다. 여기서 이미지를 생성하는 "FROM"과 "RUN"이 가장 중요합니다.

 

FROM

FROM <image>:<tag>
FROM Ubuntu:22.04

이미지(image)는 베이스 이미지를 지정합니다. 반드시 베이스 이미지를 지정해야 하며 어떠한 이미지도 베이스 이미지가 될 수 있습니다. 태그(tag)는 버전을 지정하는 것으로 가능하면 구체적인 버전을 지정하는 것이 좋습니다.

사실, 저와 같은 경우에는 FROM 키워드때문에 도커를 사용한다해도 과언이 아닙니다. 우분투 버전에 따라 라이브러리 충돌이 되는 경우가 종종 있어 특정 버전으로 이미지를 생성해서 업데이트와 상관없이 사용하는 게 목적이니까요.

 

RUN

RUN <command>
RUN bundle install

가장 많이 사용하는 구문 중 하나로 말 그래도 명령어를 실행합니다. 내부적으로 "/bin/sh -c" 뒤에 명령어를 실행하는 방식입니다.

 

도커 설치하기

도커는 리눅스 컨테이너 기술이라 맥이나 윈도우에서는 가상머신에 설치가 됩니다. 여기서는 리눅스에서 도커를 설치하는 방법을 알아보겠습니다.

 

리눅스에서는 자동 설치 스크립트를 활용하여 도커를 설치합니다.

curl -fsSL https://get.docker.com/ | sudo sh

 

도커(Docker) 명령어

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG..]

Options

Option Description
-d detached mode 로 흔히 말하는 백그라운드 모드
-p 호스트와 컨테이너의 포트를 연결 (포워딩)
-v 호스트와 컨테이너의 디렉토리를 연결 (마운트)
-e 컨테이너 내에서 사용할 환경변수 설정
-name 컨테이너 이름 설정
-rm 프로세스 종료 시 컨테이너 자동 제거
-it -i와 -t를 통시에 사용한 것으로 터미널 입력을 위한 옵션
-link 컨테이너 연결 [컨테이너 이름:별칭]

 

"run" 명령어를 사용하면 사용할 이미지가 저장되어 있는지 확인하고 없으면 다운로드를 한 후 컨테이너를 생성하고 시작합니다.

docker run --rm -it ubuntu:16.04 /bin/bash

컨테이너 내부에 들어가기 위해 뒤에 "/bin/bash"를 붙이고 키보드 입력을 위해 "-it" 옵션을 줍니다. 추가로 프로세스가 종료되면 컨테이너가 자동 삭제하도록 "--rm" 옵션도 추가했습니다.

 

컨테이너(Container) 명령어

컨테이너 목록 확인하기 : docker ps

docker ps [options]

-

$ docker ps -a // 종료된 컨테이너 목록까지 보여준다.

 

컨테이너 중지하기 : docker stop

실행 중인 컨테이너를 중지하는 명령어로 실행 중인 컨테이너를 하나 혹은 그 이상을 중지할 수 있습니다.

docker stop [options] container [container...]

* 도커 ID의 길이는 64 자리입니다.

 

 컨테이너 제거하기 : docker rm

종료된 컨테이너를 제가하는 명령어로 종료된 컨테이너를 하나 혹은 여러 개 삭제할 수 있습니다.

(중지된 컨테이너만 제거가 가능합니다. 실행중인 컨테이너를 강제로 중지하고 제거하려면 "-f" 옵션을 추가합니다.)

docker rm [options] container [container...]

- 중지된 컨테이너 모두 삭제

$ docker rm -v $(docker ps -a -q -f status=exited) // 중지된 컨테이너 모두 삭제

- 실행중인 모든 컨테이너 강제 종료 후 삭제

$ docker rm -f $(docker ps -aq) # stop containers

 

컨테이너 로그 보기 : docker logs

컨테이너가 정상적으로 동작하는지 확인하는 방법입니다.

docker logs [options] container

 

컨테이너 명령어 실행하기 : docker exec

실행중인 컨테이너에 들어가 보거나 컨테이너 파일을 실행하고 싶을 때 사용합니다.

docker exec [options] container command [arg...]

 

이미지(Image) 명령어

이미지 목록 확인하기 : docker images

도커가 다운로드한 이미지 목록을 확인하는 명령어입니다.

docker images [options] [repository[:tag]]

 

이미지 다운로드 하기 : docker pull

이미지를 다운로드 하는 명령어입니다.

docker pull [options] name[:tag|@digest]

* run 명령어를 실행할 때 이미지가 없을 때 자동으로 다운로드가 됩니다. pull 명령어는 최신 버전 다운로드할 경우에 사용합니다.

 

이미지 삭제하기: docker rmi

이미지를 삭제하는 명령어입니다. 단, 컨테이너가 실행중인 이미지는 삭제되지 않습니다.

docker rmi [options] image [image...]

Tip! 모든 이미지 한번에 삭제하기

$ docker rm -f $(docker ps -aq) # stop containers
$ docker rmi $(docker images -q) # remove images

Tip! 댕글링된 이미지 모두 삭제하기

$ docker image prune -a

 

참고 사이트