리눅스 컨테이너란?

리눅스 컨테이너란?

리눅스 컨테이너는 운영체제 수준의 가상화 기술로 리눅스 커널을 공유하면서 프로세스를 격리된 환경에서 실행하는 기술입니다. 하드웨어를 가상화하는 가상 머신과 달리 커널을 공유하는 방식이기 때문에 실행 속도가 빠르고, 성능 상의 손실이 거의 없습니다. 컨테이너로 실행된 프로세스는 커널을 공유하지만, 리눅스 네임스페이스Linux namespaces, 컨트롤 그룹cgroup, 루트 디렉터리 격리 등의 커널 기능을 활용해 격리되어 실행됩니다. 이러한 격리 기술 덕분에 호스트 머신에게는 프로세스로 인식되지만, 컨테이너 관점에서는 마치 독립적인 환경을 가진 가상 머신처럼 보입니다.

도커 컨테이너와 가상 머신의 차이
도커 컨테이너와 가상 머신의 차이

리눅스 컨테이너의 주요한 특징들은 다음과 같습니다.

컨테이너의 종류: 시스템 컨테이너와 애플리케이션 컨테이너

컨테이너는 크게 시스템 컨테이너와 애플리케이션 컨테이너로 나뉩니다.

시스템 컨테이너system container
시스템 컨테이너는 컨테이너 기술들을 사용해 운영체제 위에 하드웨어 가상화 없이 운영체제를 실행합니다. 일반적인 리눅스처럼 init 프로세스 등을 사용해서 다수의 프로세스가 같은 환경을 공유하는 것을 목표로 합니다. 시스템 컨테이너를 지향하는 컨테이너 런타임으로는 대표적으로 LXC와 LXD가 있습니다.
애플리케이션 컨테이너applcation container
애플리케이션 컨테이너는 컨테이너 기술을 활용해 하나의 애플리케이션(프로세스)를 실행하는 것을 목표로 합니다. 독립적인 환경을 가진다는 점에서는 시스템 컨테이너와 동일하지만, 단 하나의 프로세스만 실행한다는 점에서 확장이 쉽고 관리 요소가 거의 없습니다. 대표적인 애플리케이션 컨테이너 런타임으로는 도커Docker가 있습니다.

컨테이너를 사용해야하는 이유

2014년 애플리케이션 컨테이너 런타임인 도커Docker가 등장하면서 컨테이너 기술이 많은 관심을 받고 있습니다. 서버 운영 면에서 컨테이너는 서버 애플리케이션의 배포 단위를 새로 정의했고, 인프라스트럭처와 클라우드 변화에 큰 변화를 가져왔습니다. 기존의 서버 운영에서는 애플리케이션을 실행하기 위해 서버 컴퓨터의 상태를 지속적으로 관리하야했지만, 컨테이너를 사용하면 애플리케이션 별로 독자적인 환경을 준비하고 관리하는 것이 가능하기 때문에 서버 컴퓨터를 관리할 필요가 적어진다는 장점이 있습니다. 이러한 장점으로 이해 컨테이너 기술의 활용은 2020년 현재 급속하게 확산되고 있는 추세입니다.

프로덕션 운영 관점에서 컨테이너가 어떤 장점이 있는지 궁금하다면 다음 글을 참고해주세요.

왜 굳이 도커(컨테이너)를 써야 하나요? - 컨테이너를 사용해야 하는 이유

기사, 2019-01-14 - 컨테이너는 서버 애플리케이션을 배포하고 서버를 운영하는 표준적인 기술이 되어가고 있습니다. 하지만 처음 사용해본다면 그 장점이 잘 와닿지 않을 수도 있습니다. 왜 굳이 도커 컨테이너를 사용해야할까요? 이 글에서는 눈송이 서버를 넘어 컨테이너가 애플리케이션 배포와 운영에 있어 어떤 장점이 있는지 알아봅니다.

컨테이너 기반 서비스 운영 사례

컨테이너를 프로덕션 레벨에서 사용한 가장 유명한 사례는 구글입니다. 쿠버네티스Kubernetes를 조 베다Joe Beda의 발표 대규모 컨테이너 운영Containers At Scale에 따르면, 구글에서는 2014년에 이미 모든 서비스를 컨테이너에서 운영하고 있었으며 매주 20억 개 이상의 컨테이너를 실행했습니다. 이에 대해서는 구글의 컨테이너 페이지에도 설명되어 있습니다.

Gmail에서 YouTube, Google 검색에 이르기까지 Google의 모든 제품은 컨테이너에서 실행됩니다. 개발팀은 컨테이너화를 통해 더욱 신속하게 움직이고, 효율적으로 소프트웨어를 배포하며 전례 없는 수준의 확장성을 확보할 수 있습니다. Google은 매주 20억 개가 넘는 컨테이너를 생성합니다.

리눅스 컨테이너를 구현하는 기능들은 10년 이상 이전에도 존재했습니다만, 파편화되어있었습니다. 이러한 기능을 모아놓은 LXC 등이 있었지만 시스템 컨테이너를 지향해왔습니다. 따라서 컨테이너는 마치 운영체제처럼 동작하기 때문에 실행 환경을 온전하게 이식하는 것이 쉽지 않았습니다. 도커의 등장과 함께 애플리케이션 컨테이너 기술이 각광 받기 시작했고, 빠르게 퍼져나갔습니다. 현재는 구글을 비롯해 넷플릭스Netflix, 에어비앤비Airbnb, 핀터레스트Pinterest, 레딧Reddit, 포켓몬 고Pocketmon Go, 스포티파이Spotify, 틴더Tinder, 라이엇 게임즈Riot Games 등이 컨테이너로 서비스를 운영하고 있는 것으로 알려져있습니다.

국내 기업으로는 삼성전자, 삼성SDS, 당근마켓, VCNC, 우아한형제들, 엔씨소프트, 토스 등의 사례가 있습니다.

컨테이너 런타임

컨테이너 런타임은 컨테이너를 실행하고 관리하는 도구입니다.

도커(Docker)

도커Docker는 닷클라우드dotCloud의 솔로몬 하이크가 파이콘 2013 USPyCon 2013 US에서 처음 발표한 컨테이너 런타임입니다. 애플리케이션 컨테이너 런타임을 지향했으며, 처음 등장한 이후 빠르게 데 팍토 스탠다드(사실상 표준)로 자리 잡았습니다. 초기의 도커는 LXC를 기반으로 컨테이너를 생성하고 관리했지만, 현재는 containerd와 runc를 기반으로 동작합니다. 유니온 마운트 기반으로 효율적으로 실행 환경을 이미지로 만들고 공유할 수 있다는 장점이 있습니다. 도커는 기본적으로 서버, 클라이언트 아키텍처를 가지고 있으며 REST API로 조작할 수 있습니다. 또한 CLI 명령어는 깃Git과 비슷해서 개발자들이 쉽게 접근할 수 있습니다.

도커의 기본적인 사용법에 대해서는 다음 글에서 소개하고 있습니다.

도커(Docker) 입문편: 컨테이너 기초부터 서버 배포까지

기사, 2020-03-22 - 도커(Docker)는 2013년 등장한 컨테이너 기반 가상화 도구입니다. 도커를 사용하면 컨테이너를 쉽게 관리할 수 있으며, 이미지를 만들어 외부 서버에 배포하는 것도 가능합니다. 이 글은 도커를 시작하는 하는 사람들을 대상으로 도커의 기본 기능에 대해서 소개하고, 도커 허브와 디지털 오션을 사용해 직접 만든 이미지로 서버 애플리케이션을 배포하는 방법을 소개합니다.

도커 허브(Docker Hub)

도커 허브Docker Hub는 도커에서 제공하는 공식 원격 이미지 저장소입니다. 도커가 처음에 자리잡는 데 가장 중요한 역할을 했던 게 바로 도커 레지스트지(도커 허브의 초기 이름)이빈다. 기존의 컨테이너 기술들의 접근성이 떨어졌던 이유 중 하나로 실행 환경을 공유하는 것이 쉽지 않다는 점을 꼽을 수 있습니다. 시스템 컨테이너의 경우 실행 환경이 무거울 뿐만 아니라, 변경 사항을 적절하게 저장하고 공유하는 것이 어려웠습니다. 이와 달리 도커에서는 유니온 마운트 기반의 이미지 개념을 도입해 실행 환경을 효율적으로 관리하고 적절한 단위로 공유할 수 있습니다. 도커 허브를 통해 이미지를 쉽게 전달하거나 공유할 수 있도록 함으로써 접근성을 높였습니다.

원격 이미지 저장소를 직접 설치해서 사용하는 것도 가능합니다.

도커 레지스트리(Docker Registry): 프라이빗 도커 이미지 저장소 - 설치부터 S3 연동까지

기사, 2014-05-08 - 도커(Docker)의 이미지는 도커 레지스트리(Docker Registry) 서버로 공유하는 게 가능합니다. 이 글에서는 프라이빗 도커 이미지 저장소 서버 직접 설치하는 방법과 AWS S3와 연동해서 사용하는 방법을 소개합니다.

클라우드 서비스들에서는 프라이빗 이미지 저장소를 서비스로 제공합니다. 대표적으로 아마존 웹 서비스Amazon Web Service아마존 엘라스틱 컨테이너 레지스트리ECR, Amazon Elastic Container Registry, 마이크로서비스 애저Microsoft Azure컨테이너 레지스트리Container Registry 등이 있습니다. CNCF에서 관리하고 있는 오픈소스 도커 레지스트리 프로젝트 하버Harbor도 있습니다.

도커 컴포즈(Docker Compose)

도커 컴포즈Docker Compose는 다수의 컨테이너를 쉽게 관리할 수 있도록 도와주는 도구입니다. 원래는 피그Fig라는 도커와 무관한 프로젝트였습니다만, 2014년 7월 도커 사가 인수했습니다. 도커 명령어가 주로 하나의 컨테이너를 조작하는 데 사용되는 반면, 도커 컴포즈를 사용하면 YAML 형식으로 컨테이너들의 명세를 작성한 후에 컨테이너를 한꺼번에 실행하거나 종료할 수 있습니다. 도커 컴포즈는 로컬 개발 환경을 구성하는 데 사용하거나, 컨테이너 오케스트레이션 구성 이전에 초기 단계의 배포 작업에 사용되곤 합니다.

도커(Docker) 컴포즈를 활용하여 완벽한 개발 환경 구성하기

기사, 2019-03-20 - 개발 환경을 구축하기란 그리 쉬운 일이 아닙니다. 문서화를 해두어도 누군가 계속 신경쓰지 않으면 내용이 낡기 마련이고, 계속 신경 쓰자니 이 또한 쉽지 않죠. 어떻게 하면 손쉽게 개발 환경을 구성하고, 곧바로 개발 과정에 들어갈 수 있을까요? 이 글에서는 도커를 사용하여 개발 환경 구성을 손쉽게 해결하는 방법을 알아보겠습니다.

LXC

LXC는 리눅스 컨테이너Linux Containers의 줄임말로, OS 수준의 가상화를 구현하는 도구입니다. 주로 시스템 컨테이너를 관리하기 위해 사용되지만, 애플리케이션 컨테이너를 실행하거나 관리하는 것도 가능합니다. 도커가 처음 공개되었을 때는 내부적으로 컨테이너를 실행하는 데 사용되기도 하였습니다.

LXD

LXD는 새로운 시스템 컨테이너를 지향하는 컨테이너 도구입니다. LXC와 마찬가지로 컨테이너를 실행하고 관리하는 도구입니다. LXC에 비해서 기능이 강화되었으며, 편리한 인터페이스를 제공하고, REST API로 조작하는 것이 가능합니다. LXD는 단순히 LXC를 개선한 도구는 아니며, 내부적으로 컨테이너를 실행할 때는 LXC를 사용합니다.

CRI-O

크리-오cri-o는 쿠버네티스를 위한 경량 컨테이너 런타임 프로젝트로 현재 CNCFCloud Native Computing Foundation에서 인큐베이팅 단계로 관리하고 있습니다. 크리-오는 OCIOpen Container Initiative 표준을 따르는 런타임으로 쿠버네티스 CRIKubernetes Container Runtime Interface를 구현하고 있습니다. 도커보다 가벼운 컨테이너 런타임으로 쿠버네티스 지원을 지향하고 있습니다.

CRI-O의 아키텍처 구성도. 공식 사이트에서 발췌
CRI-O의 아키텍처 구성도. 공식 사이트에서 발췌

카타 컨테이너(Kata Container)

카타 컨테이너Kata Container는 오픈스택 재단OpenStack Foundation에서 개발중인 경량 VM 기반으로 컨테이너를 실행하는 런타임입니다. 컨테이너와 가상머신의 가장 중요한 차이는 호스트 머신과 커널을 공유하는지로 나눌 수 있습니다만, 카타 컨테이너는 컨테이너 전용 가상 머신을 준비한다는 점에서 제 3의 접근이라고 할 수 있습니다. 경량 VM을 사용하기 때문에 일반적인 가상 머신보다 훨씬 빠르며, 가상 머신이기 때문에 커널을 공유하는 일반적인 컨테이너보다 훨씬 안전한 샌드박스를 구현하는 것이 가능합니다.

일반적인 컨테이너 런타임과 카타 컨테이너의 비교. Leveraging Containers and Openstack에서 발췌
일반적인 컨테이너 런타임과 카타 컨테이너의 비교. Leveraging Containers and Openstack에서 발췌

카타 컨테이너에 대한 더 자세한 소개는 다음 글을 참고해주세요.

하코니와(Haconiwa)

하코니와는 DSL로 리눅스 컨테이너들에서 사용되는 프로세스 격리 기능들을 조합해 자신만의 컨테이너를 만들어볼 수 있는 프로젝트입니다. 리눅스 컨테이너를 구현하는 데 사용되는 기술로는 리눅스 네임스페이스Linux namespace, 컨트롤 그룹cgroup, 리눅스 캐퍼빌리티Linux Capabilities, 바잉드 마운트, chroot 등 다양한 기능들이 있습니다. 도커를 비롯한 컨테이너 런타임에서는 이러한 기능들을 하나의 세트로 제공하고, 세부적인 설정을 지원하지 않습니다. 하코니와를 사용하면 이러한 기능들을 조합해 커스텀한 컨테이너를 만들어볼 수 있습니다. 컨테이너 기술의 이해를 도와주는 프로젝트입니다.

컨테이너 오케스트레이션

컨테이너 오케스트레이션은 다수의 컨테이너를 적절하게 분산하고 스케줄링하는 방법과 도구입니다. 대표적으로 구글이 처음에 주도하고 현재는 CNCF에서 관리하고 있는 쿠버네티스가 있습니다.

쿠버네티스(Kubernetes)

쿠버네티스Kubernetes는 구글의 엔지니어 조 베다Joe Beda, 브렌던 번스Brendan Burns, 크레이그 맥룩키Craig McLuckie 등이 주도적으로 시작한 컨테이너 오케스트레이션 도구로 2014년 중반 오픈소스로 공개되었습니다. 쿠버네티스는 컨테이너 오케스트레이션 분야에서 데 팍토 스탠다드로 자리 잡았으며, 현재는 온프레미스, 클라우드 환경 가릴 것 없이 많은 서비스들이 쿠버네티스 위에서 동작하고 있습니다.

아마존 ECS(Amazon ECS)

아마존 ECSAmazon Elastic Container Service는 아마존 웹 서비스Amazon Web Service에서 완전 관리형으로 제공되는 컨테이너 오케스트레이션 서비스입니다. 비교적 개념이 단순하고, 다른 AWS 서비스와의 상성이 좋다는 단점이 있지만 커뮤니티가 작고 오픈소스가 아니라는 단점이 있습니다. AWS에서는 쿠버네티스 마스터 노드를 관리형으로 제공하는 EKSElastic Kubernetes Service를 제공하는 한편, ECS도 지속적으로 개선해나가고 있습니다.

아마존 엘라스틱 컨테이너 서비스(ECS)와 도커(Docker)로 시작하는 컨테이너 오케스트레이션

기사, 2018-07-18 - 컨테이너는 격리된 환경에서 애플리케이션을 실행할 수 있도록 도와줍니다. 컨테이너를 프로덕션 환경에서 사용하기 위해서는 적절한 스케줄링과 관리를 위한 도구가 필요합니다. 이 글에서는 AWS에서 제공하는 매니지드 컨테이너 오케스트레이션 서비스인 ECS를 소개합니다.

랜처(Rancher)

랜처는 쿠버네티스 기반의 컨테이너 오케스트레이션 도구입니다. 기존의 랜처 1.0에서는 도커 기반의 컨테이너 오케스트레이션을 구현했습니다만, 2.0 버전은 쿠버네티스를 기반으로 동작합니다.

노마드(Nomad)

노마드Nomad는 오픈소스로 인프라스트럭처 관련 도구를 만드는 하시코프HashiCorp에서 내놓은 컨테이너 오케스트레이션 도구입니다. 노마드는 태스크 관리와 스케줄링에 집중하고 있는 도구로 반드시 컨테이너를 사용하지 않더라고 사용할 수 있습니다. 또한 다른 도구들에 비해서 비교적 단순하다는 장점이 있습니다.

컨테이너에서 사용하는 프로세스 격리 기능

컨테이너 구현에는 리눅스 네임스페이스, 루트 디렉터리 격리, 컨트롤 그룹, 캐퍼빌리티, 유니온 마운트 외에 다양한 리눅스 커널의 기능들이 사용됩니다.

리눅스 네임스페이스(Linux namespace)

리눅스 네임스페이스Linux namespace는 특정 프로세스의 리눅스 리소스 접근을 제어하기 위해 사용되는 기능입니다. 네임스페이스는 리소스 별로 IPC 네임스페이스, 마운트 네임스페이스, 네트워크 네임스페이스, 프로세스 ID 네임스페이스, 사용자 네임스페이스, UTS 네임스페이스, 컨트롤 그룹 네임스페이스 등으로 나뉩니다. 시스템 상에서 실행되는 프로세스들은 기본적으로 init 프로세스의 네임스페이스를 공유하지만 시스템콜이나 unshare 명령어를 사용해 리소스 별로 네임스페이스를 분리하는 것이 가능합니다.

아래 글에서는 도커에서 PID 네임스페이스가 어떻게 사용되고 있는지와 PID 네임스페이스를 분리하는 방법을 소개합니다.

도커(Docker) 컨테이너는 가상 머신인가요? 프로세스인가요?

기사, 2020-01-13 - 도커 컨테이너는 가상 머신과 비슷한 특징을 가지고 있습니다. 독립적인 파일 시스템 환경을 가지고 있고, 프로세스 아이디도 호스트와 다르고, 네트워크도 격리되어 있습니다. 하지만 분명 가상 머신은 아닙니다. 이 글에서는 도커 컨테이너가 가상머신과 어떻게 다르고, 호스트 입장에서는 단순히 프로세스라는 것을 직접 확인해봅니다.

루트 디렉터리 격리와 chroot

컨테이너는 호스트의 파일 시스템이 아닌 별도의 실행 환경을 가지고 있습니다. 이 때 사용되는 기술이 바로 루트 디렉터리 격리 기술로 chroot, pivot_root와 같은 시스템 콜이 이용됩니다. 이를 통해 프로세스가 바라보는 루트 디렉터리를 파일 시스템 상의 특정한 디렉터리로 변경하는 것이 가능합니다. chroot는 명령어로도 사용할 수 있기 때문에 컨테이너 런타임 없이도 비교적 쉽게 기능을 사용해볼 수 있습니다.

컨테이너 기초 - chroot를 사용한 프로세스의 루트 디렉터리 격리

기사, 2018-12-03 - chroot는 프로세스의 루트 디렉터리를 변경하는 리눅스 시스템콜/명령어입니다. 루트를 변경함으로써 아주 기초적인 단계의 컨테이너를 구현해볼 수 있습니다. chroot는 아주 단순한 프로그램입니다만, 루트가 달라지면 프로세스의 동작 방식 달라져 실제로는 사용하기가 까다로운 편입니다. 이 글에서는 chroot의 기본적인 원리와 사용법에 대해서 소개합니다.

컨테이너 기초 - 정적 링크 프로그램을 chroot와 도커(Docker) scratch 이미지로 실행하기

기사, 2018-12-10 - C 프로그램을 작성하고 이를 동적 링크 컴파일한 경우와 정적 링크 컴파일한 경우로 나눠서 chroot로 실행해봅니다. 그리고 도커(Docker)의 scratch 이미지를 기반으로 같은 방식을 적용하는 법을 소개합니다.

컨트롤 그룹(cgroups)

컨트롤 그룹cgroups은 프로세스에서 사용 가능한 CPU, 메모리, 네트워크 대역폭, 디스크 I/O 등을 그룹 단위로 제어하는 리눅스 커널의 기능입니다. 원래는 프로세스 컨테이너 이름으로 제안되었지만, 나중에 컨트롤 그룹이 되었습니다. 컨트롤 그룹은 컨테이너에서만 사용되는 기능은 아니고, 리눅스 시스템에서 프로세스 관리를 위해 일반적으로 사용되고 있습니다.

리눅스 캐퍼빌리티(Linux capabilities)

리눅스 캐퍼빌리티Linux capabilities는 프로세스의 권한을 제어하는 기능입니다. 리눅스의 프로세스는 크게 루트 권한(사용자 ID 0)으로 실행되는 특권 프로세스와 일반 사용자(사용자 ID 0 이외)가 실행하는 비특권 프로세스로 나뉩니다. 루트의 권한을 세분화해서 프로세스 적용할 수 있도록 만든 기능이 바로 리눅스 캐퍼빌리티입니다. 컨테이너 런타임에서도 일부 루트 권한이 필요한 경우 리눅스 캐퍼빌리티를 사용해 필요한 권한을 지정하는 방식을 지원하고 있습니다.

유니온 마운트(Union Mount)

유니온 마운트는 계층화된 파일 시스템을 구현합니다. 컨테이너에 필수적인 기능은 아니지만, 도커에서 이미지 구현에 사용하면서 필수적인 기능으로 자리잡았습니다. 유니온 마운트를 사용해 효율적인 이미지 구현이 가능할 뿐만 아니라, 이미지 빌드 과정에서 캐시를 사용하거나, 이미지를 관리하는 데도 이점이 있습니다. 유니온 마운트에 대한 더 자세한 내용은 다음 글을 참고해주세요.

만들면서 이해하는 도커(Docker) 이미지: 도커 이미지 빌드 원리와 OverlayFS

기사, 2019-12-24 - 도커 이미지는 유니온 마운트 기술을 활용해 계층화된 레이어들로 구성되며, 도커 레지스트리를 사용해 쉽고 효율적인 공유를 가능하게 해줍니다. 이 글에서는 도커 이미지가 저장되는 방식과 도커 이미지 빌드의 원리, 그리고 그 바탕이 되는 유니온 마운트 구현체의 하나인 OverlayFS에 대해서 알아봅니다.