Docker을 이해하고 사용하기
포스트
취소

Docker을 이해하고 사용하기

Docker란?

image

Docker는 소프트웨어 개발 및 배포를 간소화하고 효율화하기 위한 플랫폼이다.

개발을 하다보면 다양한 환경에서 애플리케이션을 실행해야 하는 경우가 많다. 예를 들어, 개발자는 로컬 환경에서 애플리케이션을 개발하고, 테스트 환경에서 애플리케이션을 테스트하며, 프로덕션 환경에서 애플리케이션을 배포한다.

그런데, 실행 환경 간 불일치 문제로 인해 개발, 테스트, 배포 등의 과정에서 문제가 발생하는 경우가 많다.

즉, 개발 시에는 잘 작동하는 애플리케이션이 프로덕션 환경에서는 제대로 동작하지 않는 경우가 발생한다.

image

이러한 문제가 발생하는 이유는 각 환경마다 다른 라이브러리, 도구, 설정 등이 사용되기 때문이다. 따라서, 개발 환경과 프로덕션 환경을 일치시키는 것은 번거롭고 까다로운 작업이다.

image

이러한 문제를 해결하기 위해 Docker는 컨테이너 기반의 가상화 기술을 사용하여 애플리케이션을 패키징하고 실행할 수 있는 환경을 제공한다.

컨테이너는 애플리케이션과 그 애플리케이션을 실행하는 데 필요한 모든 라이브러리, 도구 및 설정을 하나의 패키지로 묶은 가볍고 독립적인 실행 환경이다. Docker는 이러한 컨테이너를 관리하고 실행할 수 있는 도구와 서비스를 제공한다.

다만 이런 문제는 과거에도 이미 존재했던 문제이며, 이를 해결하기 위해 가상화 기술이 사용되었다.

그러나 가상화 기술은 가상 머신을 생성하고 운영체제를 설치하는 등의 과정이 필요했기 때문에 무겁고 느렸다.

반면 Docker는 컨테이너를 사용하여 가상화의 부담을 최소화하고 성능을 최적화하였다. 따라서 Docker는 가상화 기술의 단점을 보완하고, 더욱 경량하고 이식성이 높은 환경을 제공한다.

image

즉, 도커는 빠른 실행이 가능한 가상 환경을 제공하며, 이를 통해 개발, 테스트, 배포 등의 과정을 효율적으로 관리할 수 있게 해준다.

Docker의 주요 특징

  1. 경량성 : 컨테이너 기반의 Docker는 가상화의 부담을 최소화하고 성능을 최적화한다.
  2. 이식성 : Docker는 어떠한 환경에서도 동일하게 작동하며, 코드의 이식성을 증가시킨다.
  3. 모듈성 : Docker는 애플리케이션을 작은 조각으로 나누어 관리하므로, 각 부분을 독립적으로 개발하고 업데이트 할 수 있다.

Docker 설치하기

Docker를 시작하기 위해서는 먼저 시스템에 Docker를 설치해야 한다.

Windows에서 Docker 설치하기

Windows 10에서는 Docker Desktop을 사용하여 Docker를 설치할 수 있다.

  1. Docker Desktop을 다운로드하기 위해 Docker 허브 Docker Hub 페이지에 접속한다.
  2. ‘Get Docker’ 버튼을 클릭하여 Docker Desktop 설치 파일을 다운로드한다.
  3. 다운로드 받은 실행 파일을 실행하면 설치가 시작된다.

공식 설치 문서

MacOS에서 Docker 설치하기

MacOS에서는 Docker Desktop for Mac을 사용하여 Docker를 설치할 수 있다.

  1. Docker Desktop for Mac을 다운로드하기 위해 Docker 허브 Docker Hub 페이지에 접속한다.
  2. ‘Get Docker’ 버튼을 클릭하여 Docker Desktop 설치 파일을 다운로드한다.
  3. 다운로드 받은 ‘.dmg’ 파일을 열고 ‘Docker.app’을 Applications 폴더로 드래그한다.

공식 설치 문서

Linux에서 Docker 설치하기

Linux에서는 패키지 매니저를 이용하여 Docker를 설치할 수 있다. Ubuntu를 기준으로 설명하면 다음과 같다.

  1. 터미널을 열고 sudo apt-get update 명령어를 입력하여 패키지 리스트를 업데이트한다.
  2. sudo apt-get install docker-ce 명령어를 입력하여 Docker를 설치한다.
  3. 설치가 완료되면 docker --version 명령어를 입력하여 정상적으로 설치되었는지 확인한다.

공식 설치 문서

Docker의 이미지와 컨테이너 이해하기

Docker를 이해하는 데 있어 가장 중요한 개념 중 두 가지는 바로 ‘이미지’와 ‘컨테이너’다. 두 개념을 이해하면 Docker의 전반적인 동작 방식을 더 잘 이해할 수 있다.

Docker 이미지

Docker 이미지는 애플리케이션을 실행하는 데 필요한 모든 것을 포함하고 있는 불변(immutable)의 파일 시스템이다. 이는 실행 가능한 소프트웨어 코드, 사용되는 라이브러리, 도구, 환경 변수 및 설정 파일 등을 포함한다.

이미지는 컨테이너를 생성하기 위한 ‘템플릿’으로 생각할 수 있다. 한 이미지에서 여러 개의 컨테이너를 생성할 수 있으며, 각각의 컨테이너는 독립적으로 작동한다.

Docker 이미지는 Docker Hub와 같은 Docker 레지스트리에 저장되고 공유될 수 있다. docker pull 명령을 사용하면 이러한 레지스트리에서 이미지를 다운로드할 수 있다.

Docker 컨테이너

Docker 컨테이너는 Docker 이미지를 기반으로 생성되며, 이미지의 실행 가능한 인스턴스다. 컨테이너는 이미지의 실행 버전이며, 독립적인 파일 시스템과 네트워크 인터페이스, 프로세스 공간을 가지고 있다.

docker run 명령을 사용하면 이미지에서 컨테이너를 실행할 수 있다. 실행 중인 컨테이너는 docker ps 명령을 통해 확인할 수 있다.

결론적으로, Docker 이미지는 애플리케이션과 그 실행 환경을 묶은 것이며, Docker 컨테이너는 이 이미지를 실행한 상태라고 생각하면 된다. 이렇게 함으로써 개발, 테스팅, 배포 과정에서 일관된 환경을 보장할 수 있다.

Docker를 이용한 Ubuntu 서버 설치 및 쉘 접속 해보기

Docker를 이용하면 운영체제를 설치하는 과정 없이 쉽게 Ubuntu 서버를 설치하고 사용할 수 있다. Docker를 이용해 Ubuntu 서버를 설치하고, 해당 서버의 쉘에 접속하는 방법을 알아보며 도커를 한번 사용해본다.

1단계: Docker 설치 확인

먼저, 컴퓨터에 Docker가 이미 설치되어 있는지 확인해야 한다. 터미널을 열고 다음 명령어를 입력한다.

1
docker version

이 명령어를 입력하면 Docker의 버전 정보가 표시된다. 만약 Docker가 설치되어 있지 않다면, 먼저 Docker를 설치해야 한다.

2단계: Ubuntu 이미지 다운로드

Docker를 사용하여 Ubuntu 서버를 설치하려면 우선 Docker 이미지를 다운로드해야 한다. Ubuntu 이미지를 다운로드하려면 다음 명령어를 입력한다.

1
docker pull ubuntu

이 명령어를 실행하면 최신 버전의 Ubuntu 이미지가 다운로드된다.

3단계: Ubuntu 컨테이너 생성 및 실행

다음으로, 다운로드한 Ubuntu 이미지를 바탕으로 Docker 컨테이너를 생성하고 실행해야 한다. 이를 위해 다음 명령어를 입력한다.

1
docker run -it --name my-ubuntu ubuntu

위 명령어를 실행하면 my-ubuntu라는 이름의 Ubuntu 컨테이너가 생성되고, 즉시 해당 컨테이너의 쉘에 접속하게 된다. 이 때 -it 옵션은 Interactive 모드를 의미하며, 컨테이너와 상호작용할 수 있도록 해준다.

4단계: Ubuntu 쉘 접속

위 단계를 거치면 Ubuntu 쉘에 바로 접속하게 된다. 만약 컨테이너를 빠져나왔다면, 다음과 같이 다시 접속할 수 있다.

1
docker exec -it my-ubuntu bash

이제 Docker를 통해 Ubuntu 서버에 접속하였다. 이 Ubuntu 서버에서 원하는 작업을 진행하시면 된다.

컨테이너의 쉘에서 작업 중에 일시적으로 쉘을 빠져나가고 싶을 때는 Ctrl + P, Ctrl + Q 키 조합을 이용한다. 이 키 조합을 사용하면 현재 실행 중인 컨테이너를 종료하지 않고 쉘에서 빠져나올 수 있다.

Docker 명령어 소개

기본 명령어

  • docker login : Docker에 로그인을 한다.
  • docker version : Docker의 버전을 확인한다.

이미지 관련 명령어

  • docker images 또는 docker image ls : 현재 시스템에서 사용 가능한 Docker 이미지의 리스트를 확인한다.
  • docker image pull [ImageName] : Docker Hub 또는 다른 Docker 이미지 저장소로부터 [ImageName] 이미지를 가져온다.
  • docker image push [ImageName] : Docker Hub 또는 다른 Docker 이미지 저장소로 [ImageName] 이미지를 업로드한다.
  • docker image build -t [RepositoryName] [Directory] : Dockerfile을 사용하여 [Directory] 경로에 있는 소스코드로부터 [RepositoryName] 이름의 Docker 이미지를 생성한다.
  • docker image rm [ImageName] 또는 docker rmi [ImageName] : [ImageName] 이미지를 삭제한다.

컨테이너 관련 명령어

  • docker container ls 또는 docker ps : 현재 실행 중인 Docker 컨테이너의 리스트를 확인한다.
  • docker ps -a : 모든 Docker 컨테이너의 리스트를 확인한다.
  • docker ps -q : 모든 Docker 컨테이너의 ID만을 확인한다.
  • docker restart [ContainerID] : [ContainerID]에 해당하는 Docker 컨테이너를 재시작한다.
  • docker container rm [ContainerID] : 컨테이너를 삭제한다. 단, 컨테이너가 정지 상태여야 한다.
  • docker container prune : 정지된 모든 Docker 컨테이너를 삭제한다.
  • docker exec -it [ContainerID] [Command] : 실행 중인 [ContainerID] 컨테이너에 [Command] 명령을 실행한다.
  • docker exec -it [ContainerID] /bin/bash : 실행 중인 [ContainerID] 컨테이너에 접근하여 Bash 쉘을 실행한다.
  • docker exec -it [ContainerID] sh : 실행 중인 [ContainerID] 컨테이너에 접근하여 Bourne 쉘을 실행한다.

컨테이너 실행 & 종료 관련 명령어

  • docker run [ImageName] : [ImageName] 이미지를 실행하여 Docker 컨테이너를 생성하고 실행한다.
  • docker run -p [HostPort]:[ContainerPort] [ImageName] : 호스트의 [HostPort]와 컨테이너의 [ContainerPort]를 연결하며 [ImageName] 이미지를 실행한다.
  • docker run [ImageName] --name [Name] : [Name]을 이름으로 하는 Docker 컨테이너를 생성하고 실행한다.
  • docker run [ImageName] -d : [ImageName] 이미지를 백그라운드에서 실행한다.
  • docker run [ImageName] -v [HostPath]:[ContainerPath] : 호스트의 [HostPath]와 컨테이너의 [ContainerPath]를 연결(마운트)하여 [ImageName] 이미지를 실행한다.
  • docker stop [ContainerID] : [ContainerID]에 해당하는 실행중인 Docker 컨테이너를 종료한다.
  • docker start [ContainerID] : [ContainerID]에 해당하는 종료된 Docker 컨테이너를 실행한다.

컨테이너의 쉘에서 작업 중에 일시적으로 쉘을 빠져나가고 싶다면 Ctrl + P, Ctrl + Q 키 조합을 이용한다. 이 키 조합을 사용하면 현재 실행 중인 컨테이너를 종료하지 않고 쉘에서 빠져나올 수 있다.

Docker의 쉘에서 exit 혹은 Ctrl + D를 사용하면, 현재 실행 중인 프로세스(여기서는 쉘)가 종료되는데, 이 때 Docker는 해당 프로세스가 종료되었음을 감지하고 컨테이너를 종료시킨다. 이를 통해 컨테이너 내의 주요 프로세스가 실패하면 자동으로 컨테이너를 정리하도록 설계되어 있다. 이러한 동작은 “PID 1 문제”라고 불리우는데, UNIX와 Linux 시스템에서 PID 1은 시스템 종료 시까지 계속 실행되며, 모든 자식 프로세스의 종료를 처리한다. 컨테이너에서 실행하는 프로세스는 PID 1로 실행되며, 이 프로세스가 종료되면 컨테이너도 함께 종료된다.

반면에, Ctrl + P, Ctrl + Q 조합을 사용하면 쉘에서 빠져나오게 되지만, Docker 컨테이너는 여전히 실행 중이다. 이는 Docker의 ‘detach’ 모드로, 컨테이너를 백그라운드에서 계속 실행하면서도 쉘에 접근하거나 컨테이너에서 벗어날 수 있게 해준다. 이렇게 하면 여러 컨테이너를 동시에 관리하거나, 백그라운드 작업을 수행하면서도 다른 작업을 계속할 수 있다. 이런 동작은 ‘detaching’이라고 부른다.

따라서, 컨테이너 내부에서 작업을 한 뒤 Ctrl + P, Ctrl + Q를 사용하여 detaching하면, 작업은 계속 실행되지만 사용자는 다른 명령어를 입력하거나 다른 컨테이너로 전환할 수 있다.

기타 명령어

  • docker tag [ImgName]:[Tag] [ImgName]:[NewTag] : [ImgName] 이미지의 [Tag][NewTag]로 변경한다.
  • docker logs [ContainerName] : [ContainerName] 컨테이너의 로그를 확인한다.
  • docker start $(docker ps -qa) : 중지된 모든 컨테이너를 실행한다.
  • docker stop $(docker ps -q) : 모든 실행 중인 Docker 컨테이너를 중지한다.
  • docker rm $(docker ps -qa) : 모든 Docker 컨테이너를 삭제한다.
  • docker inspect [ContainerName] : [ContainerName] 컨테이너의 상세 정보를 확인한다.

명령어 정리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
docker
├── login : Docker에 로그인
├── version : Docker의 버전 확인
├── images : 사용 가능한 Docker 이미지 리스트 확인
├── image
│   ├── ls : 사용 가능한 Docker 이미지 리스트 확인
│   ├── pull [ImageName] : Docker Hub 또는 다른 저장소로부터 이미지 가져오기
│   ├── push [ImageName] : Docker Hub 또는 다른 저장소로 이미지 업로드
│   ├── build -t [RepositoryName] [Directory] : Dockerfile을 사용하여 이미지 생성
│   └── rm [ImageName] : 이미지 삭제
├── rmi [ImageName] : 이미지 삭제
├── ps : 실행 중인 컨테이너 리스트 확인
│   ├── -a : 모든 컨테이너 리스트 확인
│   └── -q : 모든 컨테이너 ID 확인
├── container ls : 실행 중인 컨테이너 리스트 확인
│   ├── restart [ContainerID] : 컨테이너 재시작
│   ├── rm [ContainerID] : 컨테이너 삭제 (정지 상태 필요)
│   └── prune : 정지된 모든 컨테이너 삭제
├── exec -it [ContainerID]
│   ├── [Command] : 실행 중인 컨테이너에서 명령 실행
│   ├── /bin/bash : 컨테이너에 접근하여 Bash 쉘 실행
│   └── sh : 컨테이너에 접근하여 Bourne 쉘 실행
├── run [ImageName]
│   ├── --name [Name] : 이름 지정하여 컨테이너 생성 및 실행
│   ├── -p [HostPort]:[ContainerPort] : 포트 연결하여 컨테이너 실행
│   ├── -d : 백그라운드에서 컨테이너 실행
│   └── -v [HostPath]:[ContainerPath] : 호스트와 컨테이너 경로 연결(마운트)
├── stop [ContainerID] : 실행중인 컨테이너 종료
├── start [ContainerID] : 종료된 컨테이너 실행
├── tag [ImgName]:[Tag] [ImgName]:[NewTag] : 이미지 태그 변경
├── logs [ContainerName] : 컨테이너 로그 확인
└── inspect [ContainerName] : 컨테이너 상세 정보 확인
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

Callback에 대해 알아보자

Maven에 대해서 알아보자

Comments powered by Disqus.