
컨테이너는 화물운송에 주로 시용하는, 쇠로 만든 큰 상자로, 협동일관운송에 사용될 목적으로 설계해 제조되는 표준화된 선적용기다.
/wikipedia
흔히 우리가 아는 컨테이너인 화물 컨테이너는 크기가 표준화되어 있어 대형 선박에 적재해 운송하기 용이하게 만들어주는 물체를 격리하는 공간이다.
하지만 이번에 설명할 주제는 이 컨테이너가 아닌 IT업계에서 말하는 컨테이너다.
이름이 같은 만큼 목적도 비슷하니 앞서 설명한 컨테이너를 생각하며 보면 이해하기 더 쉬울 것이다.
소프트웨어는 OS와 환경 설정, 라이브러리에 의존성을 띈다.
따라서 같은 PC에서 성격이 다른 소프트웨어를 실행하거나 관련 구성을 관리하기 어렵다.
이러한 문제를 해결하기 위한 기술이 바로 컨테이너다.
컨테이너는 어떤 환경에서나 실행하기 위해 필요한 모든 요소를 포함하는 소프트웨어 패키지로 의존성을 띄는 소프트웨어를 환경에 구애받지 않고 실행하는 기술이다.
쉽게 말해 소프트웨어를 실행할 수 있는 표준화된 단위라고 볼 수 있다.
컨테이너 vs 가상머신(VM)

격리된 환경을 구성할 수 있는 기술이 컨테이너만 있는 것이 아니다.
가상머신(VM)은 하드웨어 리소스, 운영체제 및 모든 애플리케이션이 포함된 단일 소프트웨어 패키지로 격리된 환경을 만들 수 있다.
가상머신은 하이퍼바이저라는 소프트웨어가 하드웨어 리소스를 가상화하고, 그 위체 별도의 운영체제가 설치되는 구조다.
각 가상머신마다 독립적인 Guest OS를 가지고 있어야 하기 때문에 독립적인 플랫폼을 하나씩 증가시킬 때마다 OS를 만드는 작업을 계속해야 한다.
때문에 확장성이 떨어지고, 전체 시스템 가상화를 지원해야 하기 때문에 유연성도 낮을뿐더러 메모리나 자원을 처음부터 정해놓고 실행하기 때문에 비효율적이다.
이제 컨테이너를 왜 사용하는지 알아보자.
가벼움
컨테이너는 전체 운영체제를 포함하는 VM과는 달리 운영체제를 공유하여 필요 최소한의 리소스만을 사용해 속도가 빠르고 리소스 효율성이 높다.
가상머신의 크기가 최소 GB 단위인 반면, 컨테이너는 Guest OS가 없기 때문에 크기가 MB 단위다.
이식성
컨테이너는 애플리케이션과 그에 필요한 라이브러리, 설정 파일 등 하나의 이미지로 패키징 한다.
이를 통해 개발 환경에서 테스트 환경, 운영 환경으로 동일한 환경을 보장한다.
독립성
컨테이너 내부 애플리케이션은 다른 컨테이너나 호스트 시스템에 영향을 받지 않고 독립적으로 실행되어 충돌을 방지할 수 있다.
확장성
컨테이너는 필요에 따라 여러 개를 생성하여 수평적으로 확장할 수 있다.
따라서 클라우드 환경이나 마이크로서비스 아키텍처에서 유연하게 사용할 수 있다.

컨테이너에 대해 알아봤으니 이제 도커에 대해서 알아보자.
docker라는 단어는 부두 노동자, 즉 항구에서 선박의 짐을 내리고 싣는 사람이라는 뜻이다.
여기에 항구를 어떤 환경, 짐을 컨테이너로 적용하면 어떤 환경에서 소프트웨어를 실행할 수 있고, 배포할 수 있게 해주는 것이 된다.
즉, 도커는 컨테이너 기반 가상화 기술을 제공하는 오픈소스 플랫폼으로 애플리케이션과 그 실행 환경을 컨테이너라는 독립적인 단위로 패키징, 배포, 실행할 수 있게 해준다.
Immutable Infrastructure Paradigm(불변 인프라 패러다임)
Immutable Infrastructure(불변 인프라)는 말 그대로 서버나 시스템을 한 번 배포한 이후에 변경하지 않는 인프라스트럭처 관리 접근 방식이다.
탄생 배경은 다음과 같다.
물리 서버를 개인이 직접 운영 -> 호스팅 서비스 이용 -> 호스팅 서버 구입과 설치에 비용이 많이 듦 -> 가상화가 발전하면서 클라우드 환경으로 변화 -> 가상 서버 임대 -> 서버 수 많아짐 -> 개인이 일일이 환경을 설정하기 힘듦 -> Immutable Infrastructure Paradigm 탄생
OS와 서비스 환경을 각각 분리하여 이해하고, 분리한 것들 중 서비스 환경 부분을 이미지화하여 배포한 뒤 가급적 변경하지 않고 사용한다.
서비스 환경의 업데이트는 서비스 환경을 변경하는 것이 아닌 이미지를 교체하는 식으로 이루어진다.
그리고 도커는 호스트 OS와 서비스 운영 환경(서버 프로그램, 소스코드, 컴파일된 binary파일)을 분리한다는 패러다임과 한 번 설정한 운영 환경은 변하지 않는다는 위 개념을 기반으로 탄생한 도구다.

컨테이너를 어떻게 만들어야 하는지에 대한 설명서라고 볼 수 있다.
어플리케이션을 구동하기 위해 필요한 파일들, 어떤 프레임워크나 라이브러리를 설치해야 하는지, 필요한 환경변수, 어떻게 구동해야되는지에 대한 스크립트를 포함할 수 있다.
Docker file을 이용해 이미지를 만들 수 있다.
애플리케이션을 실행하기 위해 필요한 코드, 런타임 환경, 시스템 툴, 시스템 라이브러리, 모든 세팅들이 포함되어 있다.
즉, 실행되고 있는 애플리케이션의 상태를 스냅샷해 이미지로 만든 것과 같다.
만들어진 이미지는 불변의 상태다.
도커 컨테이너는 애플리케이션의 이미지를 고립된 환경(개별적인 파일 시스템 안에서)에서 실행할 수 있는 것이다.
컨테이너 안에서 애플리케이션이 동작한다고 볼 수 있다.
즉, Docker Image를 이용해 애플리케이션을 구동한다.
객체지향 프로그래밍에 빗대어 설명하면 이미지를 클래스, 컨테이너를 인스턴스라고 생각할 수 있다.
동작하고 있는 애플리케이션을 스냅샷 해 템플릿 형태로 이미지를 만들어 두고, 이미지를 이용해 실제로 애플리케이션이 동작하는 각각의 컨테이너를 만들 수 있다.
이미지는 캡쳐했을 당시의 프로젝트 상태를 가지고 있고, 컨테이너에서 각각 동작하는 애플리케이션은 개별적으로 수정이 가능한 상태가 된다.
컨테이너(인스턴스)에서 수정된 파일은 이미지(클래스)에 영향을 끼치지 않는다.
컨테이너를 어떻게 만드는지에 대해 알아봤으니 이제 배포하는 방법도 알아보자.
로컬 머신에서 이미지를 생성한 후 container registry에 push를 하면 필요한 서버나 PC에서 이미지를 가져와 그대로 실행하면 된다.
이때 이미지를 정상적으로 실행하기 위해선 도커와 같은 컨테이너 엔진을 설치해야 한다.
이미지를 공유할 수 있는 레지스트리는 pubic과 private이 있는데,
다양한 개발자가 사용하는 public에는 docker hub, github packages, redhat Quay.io 가 있다.
회사와 같이 보안이 중요한 곳에서 사용하는 private에는 aws, google cloud, azure가 있다.
전체적인 프로세스는 다음과 같다.
References
https://docs.docker.com/get-started/docker-overview/
https://hoon93.tistory.com/48
https://www.youtube.com/watch?v=LXJhA3VWXFA