나만의 가상화 컨테이너 만들기 #2 기초 이론

해당 게시글에는 일부 잘못된 내용이 있을 수도 있습니다, 양해 부탁드립니다!

📖 개요

오늘은 앞선 게시글에서 언급했듯이 가상화 컨테이너를 개발하기 위한 기초 이론에 대해서 알아보도록 하겠습니다.

🖥 가상화란?

가상화(virtualization)은 컴퓨터 내 리소스를 논리적으로 분할하는 과정입니다. 쉽게 말하자면 자신이 사용하고 있는 PC에다가 가상의 컴퓨터를 하나 더 만든다고 생각하면 됩니다. 즉, 물리적 자원을 논리적으로 분배해 가상의 PC를 만드는 것이라고도 할 수 있습니다.

가상화의 종류와 추세

기존의 가상화는 호스트형 가상화라는 방식을 사용해 왔습니다. 호스트형 가상화는 호스트 OS 위에서 또다른 게스트 OS를 구동하는 방식으로 작동됩니다.

또 다른 가상화 방식으로는 하이퍼바이저 가상화가 존재합니다. 이 방식은 호스트형 가상화와 달리, 호스트 OS가 존재하지 않고 하이퍼바이저라는 존재가 대신 가상화 환경을 관리합니다. 이 덕분에 기존보다 성능이 향상되는 등의 장점이 존재합니다.

마지막으로 컨테이너 가상화의 경우, 운영체제를 가상화하는 것이 아니라, 앱(프로세스)에게 가상화된 자원을 직접 제공하는 방식입니다. 게스트 OS가 필요없다는 특성 덕분에 앞서 언급한 가상화들보다 월등한 속도를 자랑하지만, 앞선 두 방식과는 달리 여러 종류의 OS를 사용할 수 없다는 단점이 존재합니다.

요즘 가상화의 추세는 컨테이너 가상화로 건너가고 있습니다. 앞서 언급한 성능상의 우위에다, Linux 뿐만 아니라 Mac과 Windows도 지원하는 Docker의 등장을 비롯한 여러가지 이유들로 인해서입니다.

⚙️ 컨테이너 가상화를 구현하는 요소

리눅스에서는 커널 단위에서의 리소스 격리를 지원합니다. 우리는 이 기능들을 통해 컨테이너 가상화를 구현할 수 있고, 실제로 Docker, LXC와 같은 컨테이너 가상화 소프트웨어들도 이것들을 기반으로 동작하고 있습니다.

네임스페이스(namespace)

네임스페이스는 시스템 자원을 논리적으로 분리해 특정 프로세스를 격리시키는 기능을 제공합니다. 대표적으로 다음과 같은 네임스페이스가 존재합니다.

PID 네임스페이스

리눅스에서는 여러 프로세스들이 부모 프로세스 밑에서 트리 구조로 동작하는데요, pstree 명령어를 통해서 다음과 같이 동작함을 확인할 수 있습니다 :

systemd─┬─ModemManager───2*[{ModemManager}]
        ├─NetworkManager───2*[{NetworkManager}]
        ├─accounts-daemon───2*[{accounts-daemon}]
        ├─acpid
        ├─avahi-daemon───avahi-daemon
        ├─bluetoothd
        
        이하 생략..

여기서의 최상위 부모 프로세스는 systemd로, 이러한 프로세스들을 init 프로세스라고 부릅니다. PID 네임스페이스는 특정 프로세스를 격리한 뒤, 그 프로세스를 init 프로세스로 만들어주는 역할을 합니다.

예를 들어, 위 트리에 있는 ModemManager 프로세스에 PID 네임스페이스를 적용하게 된다면, ModemManager스스로를 init 프로세스로 인식하게 됩니다. 이 기능은 격리된 프로세스(자식 포함)가 다른 네임스페이스를 가진 프로세스에 접근하는 것을 막아줍니다.

네트워크 네임스페이스

네트워크 네임스페이스는 프로세스에게 격리된 네트워크 인터페이스(앞으로 'NIF'라고 부르겠습니다)를 제공합니다. 이로 인해서 얻을 수 있는 효과 중 하나는 포트 중복의 가능입니다.

프로세스가 기존의 NIF와 격리되었다는 것은, 기존 NIF에서는 사용중이던 포트가 격리된 곳에서는 사용중이지 않다는 것을 의미합니다. 덕분에 이 특징은 특정 포트만을 사용하는 소프트웨어를 사용할 때에도 유리합니다.

UID 네임스페이스

사용자를 격리할 수 있는 네임스페이스입니다. 네임스페이스 내부의 UID/GID와 외부의 UID/GID를 연결시킬 수도 있습니다. 이를 통해 외부에서는 일반 유저이지만, 특정 네임스페이스에서는 root 권한을 가지도록 설정할 수도 있습니다.

Mount(File system) 네임스페이스

마운트 네임스페이스는 기존의 마운트된 파일 시스템으로부터 프로세스를 격리하게 됩니다. 다만 mount 명령을 통해 별도로 파일 시스템을 재지정하지 않을 경우 기존 파일 시스템과 연결이 유지됩니다.

재지정을 해야하는 단점 때문에 일반적으로는 chroot를 이용해 파일 시스템의 루트를 바꿔버리는 경우가 많습니다.

컨트롤 그룹(cgroup)

네임스페이스가 자원의 가시성에 중점을 두었다면, 컨트롤 그룹(cgroup)CPU와 Memory 자원에 대한 할당을 통제합니다. cgroup을 이용해 우리는 프로세스에 CPU 자원과 메모리 자원을 제한할 수 있습니다.

👏 마무리하며

이번 게시글은 자료 수집이 힘들어 내용의 정확도가 떨어진 거 같습니다. 댓글로 잘못된 내용을 지적해주신다면 가능한 빨리 반영해 수정하도록 하겠습니다.

다음 시간에는 본격적인 설계에 들어가보고자 합니다.
감사합니다.

좋은 웹페이지 즐겨찾기