컨테이너 사전 지식
도커 컨테이너에 대한 짧은 이야기
Last updated
도커 컨테이너에 대한 짧은 이야기
Last updated
과거에는 물리적인 서버에서 운영체제 버전에 맞는 소프트웨어를 설치하여 운영 하는 환경이었다. 이러한 구성을 스노우플레이크 서버 라고 불렀는데, 이렇게 구성된 서버는 다시 재현해내기 어렵다.
컨테이너는 Host OS의 시스템 커널을 사용한다.
가상머신
기존의 가상화 기술은 하이퍼바이저를 이용해 여러 개의 운영체제를 하나의 호스트에서 생성해 사용하는 방식
하이퍼 바이저가 존재하고 각각의 Guest OS 들이 리소스들을 활용하기 위해서 하이퍼 바이저를 통해 시스템 콜을 발생 시킨다.
이 때, 중요한 점은 각종 시스템 자원을 가상화하고 독립된 공간을 생성하는 작업은 반드시 하이퍼바이저를 거치기 때문에 일반 Host에 비해 성능의 손실이 발생한다는 것이다.
이외에도 가상머신은 GuestOS를 사용하기 위한 라이브러리, 커널 등을 전부 포함하기에 가상 머신을 배포하기 위한 이미지로 만들었을 때 이미지 크기가 커져 가상머신 이미지를 애플리케이션으로 배포하기는 부담스럽다.
도커 컨테이너
가상 머신과 달리 도커 컨테이너는 도커 컨테이너 엔진이 별도의 프로세스로 할당 되어 실행이 되고 각각의 프로세스들을 격리해서 사용한다.
chroot로 특정 자원만 사용하도록 제한
cgroup을 사용하여 자원의 사용량을 제한
namespace로 특정 유저만 자원을 볼 수 있도록 제한
overlay network 등 네트워크 가상화 기술 활용
union file system (AUFS, overlay2)로 이식성, 비용절감
컨테이너에 필요한 커널은 호스트의 커널을 공유해 사용하고 컨테이너 안에는 애플리케이션을 구동하는데 필요한 라이브러리 및 실행 파일만 존재하기 때문에 컨테이너를 이미지로 만들었을 때 이미지의 용량 또한 가상 머신에 비해 대폭 줄어든다.
무엇보다 컨테이너의 내용을 수정해도 호스트 OS에 영향을 끼치지 않고 애플리케이션의 개발과 배포가 편해지며 여러 애플리케이션의 독립성과 확장성이 높아진다.
도커 데몬
사용자가 명령어를 입력하면 docker.sock
을 통해 도커 데몬의 API 를 호출한다. 도커 데몬에서 발생한 이벤트는 docker events 를 통해 확인할 수 있다.
"docker 명령어가 dockerd라는 도커 데몬과 docker.sock을 참조하고 있음을 확인할 수 있다"
docker stat 과 docker system df 를 통해 도칵 현재 Host의 자원을 얼마나 사용중인지 확인할 수 있다.
"도커 데몬은 크게, 컨테이너 이미지 빌드, 관리, 공유, 실행 및 컨테이너 인스턴스 관리 등의 기능을 하며, 앞에서 살펴봤듯 모든 컨테이너를 자식 프로세스로 하는데 이에 따른 문제점은 없을까?"
"하지만 파일 시스템은 다르다"
프로세스를 별개로 실행 시켜 파일 시스템이 다르다는 것을 어떻게 할 수 있는 것일까?
프로세스는 이와 같이 자기 자신이 위치해 있는 곳을 루트로 인식 하기 때문에 컨테이너가 곧 자신의 세상이라고 인식하는 것이다.
그래서 컨테이너 내에선 자기가 첫번째 프로세스로 할당된다.
"Host OS는 컨테이너를 어떻게 바라볼까?"
위 프로세스는 Nginx 컨테이너인데, Nginx를 직접 실행하나, 컨테이너 안에서 실행되나 Host OS에겐 그저 동일한 Nginx 프로세스일 뿐이다.
"도커 컨테이너는 격리 되어 있는데 어떻게 다른 컨테이너와 통신이 가능할까?"
도커 컨테이너는 컨테이너들의 위치를 아는 요소가 존재한다. 만약, Nginx 프로세스를 관리하는 도커 컨테이너 1개를 생성 했을 때 망 구성이 어떻게 될지 살펴보자.
"요약 해보자면"
망 외부 통신
IP가 172.17.0.3
인 녀석이 172.17.0.0/16
망 외부와 통신하려고 할 때 172.17.0.1
에게 통신을 보낸다.
물론, 이 때 서버 내에서 172.17.0,3
IP로 직접 통신도 가능하다.
망 내부 통신
IP가 172.17.0.3
인 녀석이 172.17.0.0/16
망 내부와 통신하려고 할 때 docker0는 L2 Switch 역할을 하는 bridge 모드를 통해서 직접 통신을 한다.
"컨테이너 IP를 직접 다 확인하기 어렵고 외부로부터 오는 요청은 Host의 NIC로 오는데 어떻게 다른 컨테이너간 통신을 유연하게 이룰 수 있지?"
"컨테이너 이미지를 제거하면 어떻게 될까?"
컨테이너 이미지는 읽기 전용이다. 즉, 컨테이너를 제거하면 메모리에서 사라지기 때문에 영속적인 데이터를 다룰 수 없다.
그렇기 때문에 영속성 데이터는 위 이미지 처럼 컨테이너가 아닌 외부에 데이터를 저장하고, 컨테이너는 그 데이터로 동작할 수 있도록 stateless 하게 구성해야한다.
도커의 문제점은 해당 에서 읽어볼 수 있습니다.