반응형
리눅스 컨테이너
- 운영체제 수준의 가상화 기술로 리눅스 커널을 공유하면서 프로세스를 격리된 환경에서 실행하는 기술이다.
- 하드웨어 가상화 기술을 사용하는 VM이나 Vbox 같은 가상 머신과는 달리 커널을 공유하는 방식이므로 실행 속도가 빠르고 성능 상의 손실이 거의 없다.
- 컨테이너로 실행된 프로세스는 커널을 공유하지만, Linux Namespace, cgroup(Control group), root directory 격리 등의 커널 기능을 활용하여 격리된 환경에서 실행된다.
- 위와 같은 격리 기술로 인해 호스트 머신에게는 프로세스로 인식되고, 컨테이너 관점에서는 마치 독립적인 환경을 가진 가상 머신처럼 인식된다.
도커 컨테이너 방식
인프라 위에 Host Operating System 위에 Docker 엔진 위에 App A, App B, App C, App D 등이 컨테이너처럼 격리되어 실행
즉, 인프라 → Host OS → Docker 엔진 → 컨테이너들
가상 머신 방식
인프라 위에 Hypervisor 위에 Virtual Machine 안에 Guest OS가 있고 그 위에 AppA가 있으며 또 다른 Virtual Machine 안에 Guest OS가 있고 그 위에 App B, 또 다른 Virtual Machine 안에 Guest OS가 있고 그 위에 App C
즉, 인프라 → Hypervisor → Virtual Machine1(Guest OS → App A), Virtual Machine2(Guest OS → App B), Virtual Machine3(Guest OS → App C)
리눅스 컨테이너의 주요 특징들
- 운영 체제 수준의 가상화 : 별도의 하드웨어 에뮬레이션 없이 리눅스 커널을 공유해 컨테이너를 실행하며 Guest OS 관리가 필요없음
- 빠른 속도와 효율성 : 하드웨어 에뮬레이션이 없으므로 컨테이너가 아주 빠르게 실행되고, 하나의 머신에서 프로세스만큼 많이 실행하는 것이 가능하다. 단, 프로세스 격리를 위해 약간의 오버헤드가 있지만 일반적으로 프로세스를 실행할 때와 거의 차이가 없다.
- 높은 이식성 : 모든 컨테이너는 호스트의 환경이 아닌 독자적인 실행 환경을 가지므로, 이러한 환경은 파일들로 구성이 되고, 이미지 형식으로 공유될 수 있다. 또한, 리눅스 커널을 사용하고 같은 컨테이너 런타임(컨테이너를 실행하고 관리하는 도구, ex. 도커)을 사용한다면 컨테이너의 실행 환경을 공유하고 쉽게 재현 가능하다.
- 상태를 가지지 않는다는 점 : 컨테이너는 독자적인 환경을 가지므로 다른 컨테이너에게 여향을 주지 않는다. 도커와 같이 이미지 기반으로 컨테이너를 실행하는 경우는 특정 실행 환경을 쉽게 재사용할 수 있다.
컨테이너 종류
- 시스템 컨테이너
- 컨테이너 기술들을 사용해 운영체제 위에 하드웨어 가상화 없이 운영체제를 실행한다.
- 일반적인 리눅스들과 같이 init 프로세스 등을 사용해 다수의 프로세스가 같은 환경을 공유하는 것을 목표로 한다.
- 시스템 컨테이너를 지향하는 컨테이너 런타임으로는 대표적으로 LXC(Linux Container)와 LXD가 있다.
- 애플리케이션 컨테이너
- 컨테이너 기술을 활용해 하나의 애플리케이션(프로세스)를 실행하는 것을 목표로 한다.
- 독립적인 환경을 가진다는 것에서는 시스템 컨테이너와 같지만, 단 하나의 프로세스만 실행한다는 점에서 확장이 쉽고 관리 요소가 거의 없다는 것이 다르다.
- 대표적인 애플리케이션 컨테이너 런타임으로는 Docker가 있다.
컨테이너를 사용해야 하는 이유
- 애플리케이션 컨테이너 런타임인 Docker가 2014년에 등장한 이후로 서버 운영 면에서 서버 애플리케이션의 배포 단위를 새로 정의했고, 인프라와 클라우드 변화에 큰 변화를 가져왔다.
- 기존의 서버 운영에 있어서 애플리케이션을 실행하기 위해서는 서버 컴퓨터의 상태를 지속적으로 관리해야 했지만, 컨테이너를 사용하면 애플리케이션 별로 독자적인 환경을 준비하고 관리하는 것이 가능하므로 서버 컴퓨터를 관리할 필요가 적어진다.
컨테이너 기반 서비스 운영 사례
- Netflix
- Airbnb
- Pocketmon Go
- Spotify
- Tinder
- Riot Games
- Samsung 전자
- Samsung SDS
- 당근마켓
- VCNC
- 우아한형제들
- NCSOFT
- Toss
도커 컨테이너와 가상 머신의 차이점
가상머신은 운영체제 위에 하드웨어를 에뮬레이션하고 그 위에 운영체제를 올리고 프로세스를 실행하는 반면에, 도커 컨테이너는 하드웨어 에뮬레이션 없이 리눅스 커널을 공유해서 바로 프로세스를 실행한다
컨테이너 런타임(컨테이너를 실행하고 관리하는 도구) 종류
- Docker : dotCloud의 솔로몬 하이크가 파이콘 2013 US에서 처음 팔뵤한 컨테이너 런타임이다.
- 애플리케이션 컨테이너 런타임을 지향했으며, 초기에는 LXC를 기반으로 컨테이너를 생성하고 관리했지만, 현재는 containerd와 runc를 기반으로 동작한다.
- 유니온 마운트 기반으로 효율적으로 실행 환경을 이미지로 만들고 공유할 수 있다는 장점이 있다.
- Docker는 기본적으로 서버, 클라이언트 아키텍처를 가지고 있으며 REST API로 조작할 수 있다.
- Docker hub : 도커에서 제공하는 공식 원격 이미지 저장소이다.
- 도커 허브의 초기 이름은 도커 레지스트리이다.
- 기존의 컨테이너 기술들의 접근성이 떨어졌던 이유 중 하나는 실행 환경을 공유하는 것이 쉽지 않다는 점인데, 시스템 컨테이너의 경우는 실행 환경이 무겁고, 변경 사항을 적절하게 저장하고 공유하는 것이 어려웠었다. 하지만 도커는 유니온 마운트 기반의 이미지 개념을 도입해 실행 환경을 효율적으로 관리하고 적절한 단위로 공유할 수 있는데 Docker hub를 통해 이미지를 쉽게 전달하거나 공유할 수 있도록 함으로써 접근성을 높혔다.
- 원격 이미지 저장소를 직접 설치해서 사용하는 것도 가능하다.
- 클라우드 서비스들에서는 프라이빗 이미지 저장소를 서비스로 제공한다. AWS의 ECR, Azure의 Container Registry, CNCF의 Harbor
- Docker Compose : 다수의 컨테이너를 쉽게 관리할 수 있도록 도와주는 도구
- 도커 명령어는 주로 하나의 컨테이너를 조작하는 데 사용되는데 Docker Compose를 사용하면 YAML 형식으로 컨테이너들의 명세를 작성한 후에 컨테이너를 한번에 실행하거나 종료할 수 있다.
- 로컬 개발 환경을 구성하는 데 사용되거나, 컨테이너 오케스트레이션 구성 이전에 초기 단계의 배포 작업에 사용되곤 한다.
- LXC
- 리눅스 컨테이너의 줄임말로, OS 수준의 가상화를 구현하는 도구이다.
- 주로 시스템 컨테이너를 관리하기 위해 사용되지만, 애플리케이션 컨테이너를 실행하거나 관리하는 것도 가능하다.
- LXD
- 새로운 시스템 컨테이너를 지향하는 컨테이너를 실행하고 관리하는 컨테이너 도구이다.
- LXC에 비해 기능이 강화되었고 편리한 인터페이스를 제공하며, REST API로 조작하는 것이 가능하다.
- 단순히 LXC를 개선한 도구는 아니며 내부적으로 컨테이너를 실행할 때는 LXC를 사용한다.
- CRI-O
- OCI(Open Container Initiative) 표준을 따르는 런타임으로 쿠버네티스 CRI(Kubernetes Container Runtime Interface)를 구현하고 있다.
- 도커보다 가벼운 컨테이너 런타임으로 쿠버네티스 지원을 지향하고 있다.
- Kata Container
- 오픈스택 재단에서 개발중인 경량 VM 기반으로 컨테이너를 실행하는 런타임이다.
- 컨테이너 전용 가상 머신을 준비한다는 점에서 제 3의 접근이라고 할 수 있다.
- 경량 VM을 사용하므로 일반적인 가상 머신보다 빠르며, 가상 머신이기 때문에 커널을 공유하는 일반적인 컨테이너보다 훨씬 안전한 샌드박스를 구현하는 것이 가능하다.
- Haconiwa
- DSL로 리눅스 컨테이러들에서 사용되는 프로세스 격리 기능들을 조합해 자신만의 컨테이너를 만들어볼 수 있는 프로젝트이다.
컨테이너 오케스트레이션
- 다수의 컨테이너를 적절하게 분산하고 스케줄링하는 방법과 도구이다.
- Kubernetes
- Amazon ECS
- Rancher
- Nomad
컨테이너에서 사용하는 프로세스 격리 기능
- 컨테이너 구현에는 Linux Namespace, Root Directory 격리, cgroup, 캐퍼빌리티, 유니온 마운트 등 다양한 리눅스 커널의 기능들이 사용됨
Linux Namespace
- 특정 프로세스의 리눅스 리소스 접근을 제어하기 위해 사용되는 기능이다.
- 리소스 별로 IPC 네임스페이스, 마운트 네임스페이스, 네트워크 네임스페이스, PID 네임스페이스, 사용자 네임스페이스, UTS 네임스페이스, 컨트롤 그룹 네임스페이스 등으로 나뉜다.
- 시스템 상에서 실행되는 프로세스들은 init 프로세스의 네임스페이스를 공유하지만 시스템콜이나 unshare 명령어를 사용해 리소스 별로 네임스페이스를 분리하는 것이 가능하다.
- PID 네임스페이스는 프로세스의 ID를 격리할 수 있는 네임스페이스이다. 프로세스 ID를 격리하여 마치 컨테이너가 init 프로세스(PID)인 것처럼 실행해준다.
- network 네임스페이스는 프로세스 별로 고유한 네트워크 환경을 구축할 수 있도록 도와준다. 프로세스에 전용 IP를 할당하거나 네트워크 인터페이스를 추가하고 설정할 수 있다. network 네임스페이스는 ip 명령어로 조작할 수 있다.
- UTS 네임스페이스는 호스트 네임과 NIS 도메인 이름을 격리하는 네임스페이스이다. 네트워크 네임스페이스와 함께 사용되는 경우가 많다.
루트 디렉토리 격리와 chroot
- 컨테이너는 호스트의 파일 시스템이 아닌 별도의 실행 환경을 가지고 있는데, 이때 사용되는 기술이 루트 디렉토리 격리 기술로 chroot, pivot_root와 같은 시스템 콜이 이용된다. 이를 통해 프로세스가 바라보는 루트 디렉토리를 파일 시스템 상의 특정한 디렉토리로 변경하는 것이 가능하다.
croups
- 컨트롤 그룹은 프로세스에서 사용 가능한 CPU, 메모리, 네트워크 대역폭, 디스크 I/O 등을 그룹 단위로 제어하는 리눅스 커널의 기능이다.
- 원래는 프로세스 컨테이너 이름으로 제안되었지만, 후에 컨트롤 그룹이 되었다.
- 컨테이너에서만 사용되는 기술이 아니라 리눅스 시스템에서 프로세스 관리를 위해 일반적으로 사용된다.
리눅스 캐퍼빌리티(Linux capabilities)
- 리눅스 캐퍼빌리티는 프로세스의 권한을 제어하는 기능이다.
- 리눅스의 프로세스는 크게 2가지로 루트권한(사용자 ID 0)으로 실행되는 특권 프로세스와 일반 사용자(사용자 ID 0 이외)가 실행하는 비특권 프로세스로 나뉜다.
- 루트의 권한을 세분화하여 프로세스에 적용할 수 있도록 만든 기능이다.
- 컨테이너 런타임에서도 일부 루트 권한이 필요한 경우 리눅스 캐퍼빌리티를 사용해 필요한 권한을 지정하는 방식을 지원하고 있다.
유니온 마운트(Union Mount)
- 계층화된 파일 시스템을 구현한다.
- 컨테이너에 필수적인 기능은 아니지만 도커에서 이미지 구현에 사용하면서 필수적인 기능으로 자리잡았다.
- 효율적인 이미지 구현이 가능할 뿐 아니라, 이미지 빌드 과정에서 캐시를 사용하거나 이미지를 관리하는 데도 이점이 있다.
https://www.44bits.io/ko/keyword/linux-container#컨테이너에서-사용하는-프로세스-격리-기능
반응형
'Notes > Docker' 카테고리의 다른 글
[Docker Note] Dockerfile과 docker-compose.yml (0) | 2022.09.05 |
---|---|
[Note] Docker 입문 정리 (0) | 2022.08.07 |