Docker 기본 ✏️
The concept and background of Docker, and comparison with virtualization technology
// INDEX
들어가며
도커가 2013년 출시한 이후로 여러 카테고리에서 많은 변화가 있었다. 컨테이너의 대중화를 이끌면서 그로부터 파생된 많은 기술과 산업군이 생겼다. 소프트웨어 개발 방식 및 배포 방식 또한 변화가 있었다.
엄청난 변화들은 차치하더라도 일관된 환경과 여러 종속성에 대해 가벼운 실행 방식은 빠르게 개발하고 테스트하는 개발자들에겐 최고의 환경이 아닐 수 없다.
그런 엄청난 이점을 누리기 위해 도커에 대해서 처음부터 알아보자. 이 글은 도커에 대해서 많이 들어봤지만 어떤 기술인지 아직 모르는 분들을 위해서 작성하며, 내가 개인적으로 참고하여 개발에 많은 도움을 받기 위해 기술해둔다. 소프트웨어 실행 및 배포에 있어서 컨테이너만큼 가벼운게 있을까 싶다. 그말은 내가 뭔가 만들고 배포할때 빠른 사이클로 실행해볼 수 있다는 의미니까.
물론 나도 배우는 입장이라 당연히 틀리고 부족한 설명이 아주 많다. 또한 기술적인 부분에 대해선 객관적으로 작성하고 의견을 얘기하는 부분엔 주관적으로 작성하려고 노력하지만, 잘 지켜지지 않은 부분도 있을 것이다. 그렇기 때문에 모든 사람들의 비판적인 시각과 의견을 아주 웰컴하게 받아들인다. 언제든지 github, email, x, youtube 를 통해서 의견을 주시면 나와 우리의 발전에 기여를 해주시는 분들이라 여기며 너무 감사함을 전한다.
Docker 의 배경
모든 기술은 존재하는 문제를 해결하기 위해 발전한다. 기술이 나오기까지 어떤 문제점들이 있었고 어떻게 해결하기 위해 노력했으며, 그 노력을 통해서 어떻게 진화하고 발전했는지를 이해하는것은 단편적으로 기술을 습득하는 것보다 더 많은 것을 배울 수 있다고 생각한다. 그리고 그렇게 기억하면 외우지 않아도 전체적인 흐름이 더 친근하게 다가오고 납득이 되며 이해된다.
출처: https://anilktalla.medium.com/why-container-virtualization-abb8bfc04048
전통적인 서버 운영 방식
하나의 서버에서 애플리케이션을 실행하는 방식이 일반적인 서버 운영 방식이었다.
이와 같은 방식은 여러 문제점을 초래한다.
- 동일한 호스트에서 실행되는 애플리케이션간 충분한 격리가 이루어지지 않기 때문에 서버에 영향을 끼치는 장애 발생 시 서버 전체의 애플리케이션이 영향을 받을 수 있다.
- 애플리케이션이 사용하는 자원을 (cpu, 메모리, 네트워크, 디스크 입출력 등) 효율적으로 분배할 수 없어 자원 낭비 혹은 부족이 일어날 수 있다.
- 작동하는 애플리케이션의 환경이 다른 경우 해당 환경 구성을 위해 복잡한 설정이 필요하다.
- 사용량 예측을 통해 물리 서버의 스펙을 구매 (혹은 대여) 했기 때문에 비용적인 손해가 심했고, 과성능 혹은 부족한 성능으로 인한 즉각적인 확장 및 축소가 어렵다.
위와 같은 문제를 해결하기 위한 기술이 바로 가상화였다.
가상화
가상화 기술의 발전으로 단일 물리 서버에서 여러개의 가상머신을 격리된 환경에서 실행할 수 있게 된다.
💡 가상화는 하이퍼바이저와 같은 소프트웨어를 사용하여 프로세서, 메모리, 스토리지 등 단일한 물리 서버의 자원을 다수의 가상 머신으로 분할하여 사용할 수 있는 하드웨어의 추상화 계층을 구축하고 독립적인 가상의 운영체제를 실행할 수 있도록 하는 것이다.
추상화 계층이란 하나뿐인 자원의 일부만 사용하는 사용자가 독립적인 자원을 사용하는 것처럼 작동하게 하는 계층이다.
출처 - https://bi-insider.com/posts/virtual-machines-vs-containers/
가상화 기술이 발전하면서 여러 가상 머신을 단일한 호스트 위에서 실행할 수 있게 된다.
각각의 가상 머신은 격리되어 있기 때문에 서로 다른 가상 머신간 영향도가 최소가 된다.
원하는 수의 가상머신을 실행하고, 실행된 가상머신에 애플리케이션을 구동하면 애플리케이션의 장애 발생 시 다른 가상 머신의 애플리케이션에 영향을 미치지 않게 된다.
사용 가능한 하드웨어 자원에 대한 가상화를 통해 사용량에 대한 설정을 통해 자원분배가 효율적으로 이루어진다.
예를 들어, cpu 연산이 많은 애플리케이션을 실행하려는 경우 cpu 사용량을 높인 가상 머신을 실행해서 해당 가상 머신에 cpu 연산이 많은 애플리케이션을 구동하는 방식이다.
가상 머신간 필요한 자원에 대한 효율적으로 분배가 가능해 결과적으로 비용적으로 이점이 생기게 된다.
각각의 머신은 격리되어 있기 때문에 각각의 환경도 격리되어 있다.
필요한 라이브러리, 바이너리에 대한 의존성을 애플리케이션이 필요한 환경으로 구성할 수 있다.
하나의 서버에서 실행하며 필요했던 복잡한 의존성을 쉬운 방식으로 관리가 가능하게 된다.
이러한 이점은 하나의 서버에 애플리케이션을 띄우는 방식에 존재하던 문제점을 대부분 해결한다.
가상 머신은 머신 레벨에서 필요한 추상화를 충분히 제공한다. 하지만 구조적으로 가지는 문제점과 애플리케이션의 관점에서 가지는 문제점이 몇가지 존재한다.
- 하이퍼바이저와 같은 소프트웨어가 필요하기 때문에 애플리케이션을 호스트에서 직접 실행하는 것보다 성능과 자원에서 오버헤드가 존재한다.
- 가상 머신 내 게스트 운영체제가 중복해서 필요하기 때문에 자원 낭비가 발생한다.
- 가상 머신을 재부팅하거나 확장하는 경우 가상 머신 내 게스트 os 부팅 시간 등으로 인해 애플리케이션 실행 준비 시간이 길어 민첩함이 떨어진다.
- 개발, 테스트, 운영 환경에 대한 환경 설정이 가상 머신에 대한 환경 설정부터 라이브러리와 바이너리의 의존성 버전 및 커널 버전 등에 대해 완전히 동일한 설정을 구성하기 어렵다.
가상화가 풀지 못한 문제점을 컨테이너 기술로 해결이 가능하게 된다.
컨테이너 기술
컨테이너 기술은 프로세스에 대한 가상화로 하나의 운영체제 내에서 여러 개의 격리된 사용자 공간을 생성하여 애플리케이션을 격리된 사용자 공간에 배치 및 실행하는 기술이다.
호스트 운영체제 커널을 공유하면서 각각의 컨테이너는 독립된 파일 시스템, 라이브러리, 실행 환경을 가질 수 있다. (이는 위에서 본 추상화 계층과 가상화와 완전하게 동일한 맥락으로 설명된다.)
출처 - https://www.docker.com/resources/what-container/
컨테이너 환경은 가상 머신보다 자원 낭비가 적고 애플리케이션의 실행을 빠른 속도로 할 수 있다.
또한 라이브러리, 설정 파일, 환경 정보 등이 포함되어 관리되기 때문에 애플리케이션 실행에 일관된 상태를 유지하기 쉽게 만들어
애플리케이션 실행에 있어 가지고 있던 가상머신의 문제점을 해결했다.
컨테이너 기술은 주로 리눅스 운영체제의 cgroup, namespace, chroot 등 기술을 기반으로 사용한다. 해당 기술은 리소스 할당, 사용자 권한 제어, 권한에 따른 자원 격리 등에 관련된 기술이며, 리눅스와 호환되는 운영체제에서 작동한다.
2013년 도커가 공식 릴리즈하기 이전에도 컨테이너 기술은 존재했다.
하지만 기능이나 사용자의 사용성 면에서 불편함이 많아 상용화 되지 못했다.
그리고 도커가 릴리즈 되면서 컨테이너 기술이 대중적으로 많이 사용된다.
가상머신과 컨테이너 - 비교 보단 화합
출처 - https://www.bmc.com/blogs/containers-vs-virtual-machines/
| 항목 | 가상 머신 (Virtual Machine) | 컨테이너 (Container) |
|---|---|---|
| 부팅 시간 | 수 분 | 수 초 |
| 운영체제 | 각 가상 머신마다 게스트 OS가 필요 | 호스트 OS 커널을 공유 |
| 자원 효율성 | 중간 계층 (하이퍼바이저)로 인해 자원 사용 비효율적 | 비교적 경량화된 자원 사용 |
| 성능 | 하이퍼바이저로 인한 오버헤드 발생 가능 | 거의 네이티브 성능 |
| 배포 및 이동성 | 전체 VM 이미지를 복제하여 배포, 이미지가 커서 이동이 어려움 | 컨테이너 이미지로 경량화, 빠른 배포 및 이동성 제공 |
| 환경 일관성 | 개발, 테스트, 운영 환경 간의 차이 존재 | 모든 환경에서 일관된 실행 환경 제공 |
| 관리 복잡성 | 비교적 복잡 | 상대적으로 단순 |
| 운영체제 호환성 | 다양한 운영체제 지원 가능 | 주로 리눅스 기반, Windows 컨테이너도 지원 |
| 보안 | 각 VM은 독립된 OS로 보안성이 높음 | 컨테이너 간 커널 공유로 보안 측면에서 추가적인 고려 필요 |
가상 머신과 컨테이너는 단순히 서로를 대체하는 개념이 아니다.
각각의 기술은 고유한 장점과 단점을 가지고 있으며, 특정 상황과 요구 사항에 맞춰 적절히 선택되고 사용될 수 있다.
가상 머신은 높은 격리와 다양한 운영체제 지원이 필요한 환경에서 유리하며, 컨테이너는 빠른 배포와 자원 효율성이 중요한 환경에서 사용성이 높다.
현대의 IT 에서는 이 두 기술이 상호 보완적으로 혼합되어 사용된다. 예를 들어, 클라우드는 가상화와 컨테이너 기술의 혼합으로 높은 사용성을 가진 산업으로 발전했다. 가상 머신 위에서 컨테이너를 실행함으로써 두 기술의 장점을 모두 활용할 수 있다. 높은 격리 수준과 함께 컨테이너의 빠른 배포와 경량화의 이점을 취할 수 있기 때문에 가상 머신과 컨테이너는 각각의 강점을 살려 최적의 IT 환경을 구성하는 데 중요한 역할을 한다.
도커란 무엇인가?
리눅스 커널에 있는 격리된 환경과 사용자 권한 부여 등과 관련된 기술들을 활용해 컨테이너 기술이 발전했다. 다양한 컨테이너 환경을 만드는 기술이 나왔지만 사용자가 사용하기 쉬운 방식이 아니었다. 예를들면 특정 운영체제 버전에 종속적이거나, 초기 설정이 너무 복잡하거나, 보안적으로 이슈가 있는 등이었다. (관련 키워드 - LXC, OpenVZ, Linux-VServer 등)
Docker 는 이런 기술들이 가지고 있는 단점을 보완하고 장점을 취하여 만들어진 컨테이너 환경 관리 플랫폼 기술이다.
- 컨테이너 생성, 애플리케이션 배포, 컨테이너 관리에 대해 직관적이고 쉬운 방식
- 쉬운 이미지 구축 방식 및 DockerHub 를 통해서 이미지를 쉽게 공유
- Docker compose 를 통해 복합 애플리케이션 관리
- 광범위한 커뮤니티 지원
애플리케이션 실행에 필요한 애플리케이션 소스, 라이브러리 의존성, 실행에 필요한 런타임(python, java),
운영체제를 하나의 이미지로 만들고, 이미지를 통해서 컨테이너를 실행시킨다.
격리된 공간에 가상의 프로세스를 만들어 실행함으로써 사용자는 완전히 격리된 환경의 작은 서버로 동작하는 것과 같이 느낄 수 있다.
도커는 위와 같은 특징을 바탕으로 손쉽게 컨테이너 환경을 구축할 수 있도록하며, 컨테이너화의 대중성에 큰 기여를 하게 된다.
도커가 이끈 컨테이너화의 대중적인 흐름과 함께 CI/CD, DevOps, container orchestration 등 다양한 개념들이 컨테이너와
함께 진화되고 발전했다.