Blog Content

    티스토리 뷰

    [Docker] 컨테이너 가상화 기술과 Docker

    배경

    최근 클라우드 시스템이 도입되면서 가상 서버를 생성하고 관리하는 것이 쉬워졌다.

    이로 인해 인프라 엔지니어나 오퍼레이터가 ‘애플리케이션 실행 환경'을 구축하고 운영하던 일이 애플리케이션 엔지니어의 역할이 되는 경우가 많아지고 있다.


    따라서 애플리케이션 엔지니어에게도 OS와 네트워크 같은 인프라 기초 지식이 필요하게 되었다.

    이유는 아래와 같다.

      . 시스템 개발 흐름에 큰 변화

      . 다양한 인ㅍ라 구성관리 툴의 등장으로 인프라 구성을 코드로 정의할 수 있게 되었으며, 이는 구축 및 운영의 자동화로 이어지게 됨

      . 여러 반복 업무를 자동화하는 등 개발 조직에도 변화가 생겨

        개발에서부터 운영까지 전 과정을 담당하는 엔지니어가 늘고 있다.

      . 이제 '애플리케이션 엔지니어', '인프라 엔지니어'의 업무 분담이 모호해지고 있다.

      

    인프라의 종류(클라우드와 온프레미스 환경)


    온프레미스 : 지금까지 대부분 기업에서 적용해온 것으로, 시스템 구축에서부터 운영까지 자사에 테이터 센터를 두고 수행하는 형태

    Public Cloud : 인터넷을 통해 불특정 다수에게 제공하는 클라우드 서비스

    자사에 데이터센터를 두지 않기 때문에 서버와 네트워크 등 인프라 관련 초기 투자가 필요 없다.

    Private Cloud : 특정 기업 그룹에만 제공하는 클라우드 서비스


    클라우드에 적합한 케이스

    1. 트래픽 변화가 많은 시스템 - 트래픽 양에 따라 서버 스펙과 네트워크를 예측하여 설계하는 것을 '사이징'이라고 하는데

     시스템을 사이징하기 어려운 경우에는 트래픽 양에 따라 쉽게 증설할 수 있는 클라우드에서 구성하는 것이 좋다.

    2.재해에 대비하기 위해 해외에 백업을 구축하고자 하는 시스템

    3. 되도록 빨리 동작해야 하는 시스템 - 온프레미스 서비스는 초기에 장비 조달에 시간이 걸리므로.. 초기 투자가 필요한 온프레미스보다는

    시스템 사용량만큼 과금하는 클라우드가 비용 면에서도 더 적절함


    온프레미스에 적합한 케이스

    1. 높은 가용성이 요구되는 시스템 - 네트워크가 끊기면 안되는 등 클라우드 벤더가 보장하는 범위 이상의 가용성이 필요한 경우에는 클라우드에서 운영할 수 없다.

    2. 높은 기밀성이 요구되는 데이터를 다루는 시스템

    3. 특수 요건의 시스템

    4. 총 비용이 높은 시스템


    * 컨테이너 가상화 기술과 Docker

    Docker는 컨테이너 가상화 기술을 사용하여 애플리케이션 실행 환경을 구축 및 운영하기 위한 플랫폼이다.

    그렇다면, 가상화 기술이 무엇인지에 알아보자.


    2-1. 가상화 기술

    (1) 가상 환경

      개발 현장에서는 대부분 Windows 클라이언트 PC를 사용하는 경우가 많다.

      Eclipse, IntelliJ 등 IDE를 설치하고 사용하여 프로그래밍을 하고, 여러가지 라이브러리와 프레임워크 등을 사용하여

      프로그래밍과 테스트를 반복한다.

      하지만 이렇게 개발한 어플리케이션을 Linux로 된 운영 환경에서 실행한다면 어떻게 될까?

      애플리케이션 실행 환경이 바뀌면 OS와 미들웨어 동작도 달라지기 때문에 사실 운영 환경과 동일한 조건에서 시스템을 개발하는 것이 정석이다.

      운영 환경과 동일한 개발 환경과 데이터센터를 준비할 수 있다면 그 곳에서 테스트를 진행하는 것이 가장 바람직하지만,

      데이터센터 건설에는 많은 비용과 시간이 필요하므로 현실적으로는 불가능하다.

      만약, 개발용으로 사용중인 Windows기반의 하드웨어에 가상 서버를 올릴 수 있다면

      서버 장비를 새로 구입하지 않아도 개발 환경ㅇ르 구축할 수 있다.

      별도의 물리적인 하드웨어 대신 가상OS위에 애플리케이션을 구동시키는 것으로

      이를 '가상환경'이라고 하며, 물리적인 서버가 아니므로 유지보수에 대한 부담을 덜 수 있다.

      

      가상화 환경을 만들기 위해서는 기본이 되는 하드웨어에 OS를 설치하고 그 위에 가상화 소프트웨어를 올린 뒤, 게스트OS를 구동시킨다.

      가상화 소프트웨어를 사용하면 한 대의 하드웨어에 여러 OS를 가상으로 구동시키거나 파기할 수 있다.

      이러한 가상화 구조를 '호스트 가상화'라고 한다.

      최근 가장 많이 사용되고 있는 대표적인 가상화 기술은 다음 세가지다

      1. 호스트 가상화

      2. 하이퍼바이저 가상화

      3. 컨테이너 가상화

      

    (2) 호스트 가상화

    하드웨어 위에 베이스가 되는 호스트OS를 설치하고 그 위에 가상화 소프트웨어를 설치한 뒤 게스트 OS를 구동하는 가상화 기술이다.

      가상화 소프트웨어를 설치하여 간편하게 가상환경을 구축할 수 있기 때문에 개발 환경 구축에 많이 사용되지만 호스트 OS상에서 게스트OS가 동작하기 때문에

      오버헤드가 클 수 밖에 없다.

      Oracle VM VirtualBox, VMWare Player등이 있다.


    (3) 하이퍼바이저 가상화 

    하드웨어 위에 가상화 전문 소프트웨어인 '하이퍼바이저'를 설치하고 하드웨어와 가상 환경을 제어한다.

    대표적인 하이퍼바이저에는 Microsoft Windows Server의 Hyper-V와 Citrix의 XenServer 등이 있다.

    호스트OS없이 하드웨어를 직접 제어하기 때문에 효율적으로 리소스를 사용할 수 있다.

    단 가상환경 별로 OS가 동작하기 때문에, 가상 환경 동작에 걸리는 오버헤드가 발생할 수 있다.


    (4) 컨테이너 가상화 

    호스트 가상화, 하이퍼바이저 가상화는 가상화 소프트웨어를 통해 OS와 하이퍼바이저 위에 또 다른 OS를 여러 개 구동시키며 그 자체로 많은 리소스를 필요로 한다. 컨테이너 가상화는 호스트OS상에서 논리적으로 구역(컨테이너)을 나눠 애플리케이션 동작을 위한 라이브러리와 애플리케이션 등을 컨테이너 안에 넣고,

    개별 서버처럼 사용하는 것이 컨테이너 가상화이다. 컨테이너 가상화는 오버헤드가 적어 가볍고 빠른 것이 특징이다.


    2-2. Docker의 특징

    Docker는 컨테이너 가상화 환경에서 애플리케이션을 관리하고 실행하기 위한 오픈소스 플랫폼이다.

    Linux로 위에서 동작하는 것이 특징이며 Go 언어로 만들어졌다. 

    Mac OS X와 Microsoft Windows 같은 클라이언트 OS에서는 DOcker Toolbox가 제공된다.

    Docker Toolbox는 VirtualBox로 구성된 가상 환경에서 전용 Linux 배포판을 통해

    Docker를 동작시킨다.


    (1) 이식성 : 한번 만들어두면 어디에서든 동작하는 소프트웨어의 특성을 이식성(portability)이라 한다.

    시스템 개발 시, 운영환경에서 업무 애플리케이션을 구동하기 위해서는 다음과 같은 요소가 필수적임

    . 업무 애플리케이션 실행 모듈(프로그램 본체)

    . 미들웨어와 라이브러리

    . OS 및 네트워크 등 인프라 환경 설정


    Docker에서는 이러한 인프라 환경을 컨테이너로 관리한다.

    애플리케이션 실행에 필수적인 모든 파일 및 디렉터리를 통째로 컨테이너에 담고

    이 컨테이너의 기반이 되는 Docker 이미지를 Docker Hub에서 공유한다.


    애플리케이션 개발자는 Docker를 사용하여 자신이 개발한 웹 애플리케이션 실행에 필요한 모든 것을 포함한 Docker 이미지를 생성한다.

    이 이미지는 컨테이너의 템플릿이 되며 이를 기반으로 컨테이너를 동작시킬 수 있다.

    이미지는 Docker를 설치할 수 있는 환경이라면 어디에서든 동작할 수 있기 때문에

    '개발 및 테스트 환경에서는 동작하지만 운영환경에서는 동작하지 않는'리스크를 줄일 수 있다.


    (2) 상호운용성 : 여러 조직이나 시스템과 연계하여 사용할 수 있는 소프트웨어의 특성을 상호운용성(interoperability)라 한다.

    Google, Amazon 등 클라우드 벤더를 시작으로 Red Hat, Microsoft, IBM 등의 시스템 개발 벤더와 오픈소스 등이 Docker를 서포트하고 있다.

    Github와 연계하여, github 상에서 관리되는 Dockerfile을 Docker Hub와 연계한 뒤 자동으로 빌드하면,

    Docker 컨테이너 기반이 되 는 Dockker 이미지를 생성할 수 있다.

    또한, Google은 컨테이너 통합관리를 위한 Kubernetes 프레임워크를 오픈소스로 공개해두었다.


    2-3. Docker의 기본 기능

    (1) Docker 이미지 생성

      Docker는 애플리케이션 실행에 필요한 프로그램, 라이브러리, 미들웨어와 OS, 네트워크 설정 등을 하나로 모아 'Docker 이미지'를 생성한다.

      애플리케이션 실행에 필요한 파일이 담긴 디렉터리를Docker 커맨드를 사용하면 이미지를 tar 파일로 만들 수 있다.


    (2) Docker 컨테이너 동작

      Docker는 Linux 상에서 컨테이너 단위로 서버를 구동시킨다. 이 컨테이너의 기반이 되는 것이 Docker 이미지이다.

      또한 Docker 이미지를 통해 여러 컨테이너를 구동시킬 수도 있다.

      다른 가상화기술로 서버를 사용할 때에는 OSㅐ부터 구동시켜야 하므로 시간이 소요되지만

      Docker는 이미 동작하고 있는  OS 상에서 프로세스를 실행시키는 것과 거의 비슷한 속도로 빠르게 기동한다.

      

      Docker는 하나의 Linux 커널을 여러 컨테이너가 공유한다.

      컨테이너 내에서 동작하는 프로세스를 하나의 그룹으로 관리하고

      그룹별로 각각 다른 파일 시스템과 호스트명, 네트워크 등이 할당된다.

      서로 다른 그룹인 경우, 프로세스와 파일에 액세스할 수 없다.

    (3) Docker 이미지 공개 및 공유

      Docker 이미지는 Docker 레지스트리에서 통합적으로 관리할 수 있다.

      예를들어 공식 Docker레지스트리인 Docker Hub에서는 Ubuntu와 CentOS 등 Linux 배포판의 기본 기능을 제공하는

      베이스 이미지가 배포되어 있다.

      이 베이스 이미지에 미들웨어와 라이브러리, 애플리케이션 등을 포함한 이미지를 중첩하여 독자적인 Docker 이미지를 만들고 있다.

      공식 이미지 이외에도 개인이 개발한 이미지를 Docker Hub에서 자유롭게 공개하여 모두가 공유할 수 있다.

      

    2-4. Docker의 동작 구조

    Docker의 코어 기능은 어떤 구조로 동작하는지 알아보자!

    (1) 컨테이너를 구분하는 구조(namespace)

      Docker는 컨테이너라는 독립된 환경을 만들고 이를 나누어 애플리케이션 실행 환경을 만든다.

      이처럼 컨테이너를 나눌 때 Linux 커널의 namespace 기능을 사용한다.

      namespace를 직역하면 '이름공간'이라는 의미로, 한데 합쳐진 데이터에 이름을 붙여 충돌 가능성을 낮추고 쉽게 참조할 수 있도록 하는 기능을 말한다.

      

    (2) 리소스 관리 구조 (cgroup)

      Docker는 여러 컨테이너에서 물리 머신의 리소스를 공유하여 사용한다. 이때 Linux 커널 기능인 cgroup을 이용하여 리소스 할당 등의 관리를 수행한다.

      cgroup으로 컨테이너 내의 프로세스 리소스를 관리함으로써, 한 컨테이너가 같은 호스트os상에서 동작하는 다른 컨테이너에 영향을 주는 일을 막을 수 있다.

    (3) 네트워크 구성(가상 bridge 및 가상 NIC)

      Docker 컨테이너는 서버의 물리 NIC와 별도로 각 컨테이너마다 가상 NIC가 할당되어 있다.

      

      3-1) Docker 컨테이너 간의 통신

      동일한 호스트상의 Docker 컨테이너는 구동 시 private Address가 자동으로 할당되므로 컨테이너끼리 통신하기 위하여 '링크 기능'을 사용한다.

      이를 사용하면 한 호스트 상에 여러 컨테이너가 동작하는 경우, 컨테이너의 alias명을 통해 서로 다른 컨테이너에 접속할 수 있다.

      Docker는 일반적으로 1컨테이너 1프로세스로 운영된다. 웹 서버용 컨테이너와 db서버용 컨테이너에서 데이터를 연계하거나 각종 서버용 컨테이너의 로그파일을 로그용 컨테이너에 출력하는 방식으로 사용할 수 있다.

      단, 링크 기능을 사용한 통신은 동일 호스트, 즉 가상 bridge docker()에 접속한 컨테이너끼리만 가능하다.

      

      3-2) Docker 컨테이너와 외부 네트워크 통신

      Docker 컨테이너가 외부 네트워크와 통신할 때는 가상 bridge docker()와 호스트OS의 물리 NIC에서 패킷을 전송해야 한다.

      이때, Docker에서는 NAPT 기능을 사용하여 접속한다.

      NAPT(Network Address Port Translation)란 하나의 IP Address를 여러 컴퓨터에서 공유하는 기술로서 IP Address와 포트 번호를 변환하는 기능이다.

    private IP Address를 global IP Address로 변환할 때, private IP Address별로 다른 포트 번호를 변환한다.

    예를들어 클라이언트A에서는 포트 번호 1500을, 클라이언트 B에서는 포트번호 1600을 reques한다면

    인터넷 상의 서버에서는 NAPT의 global IP Address의 서로 다른 포트번호로 response를 보낸다.

    NAPT는 이 포트 번호를 토대로 private IP Address로 변환할 수 있다.


    (3) Docker 이미지 데이터 관리 구조

      'Copy on Write'라는 데이터 구조 사용!

      이는 데이터를 바로 복사하지 않고 원본을 그대로 참조하여 원본 또는 복사본 데이터 중 하나가 변경될 때 빈 공간을 확보하여 데이터를 복사하는 구조이다.

      Docker에서는 이 방식으로 컨테이너 이미지의 변경을 관리한다.

      Docker 이미지는 OS와 미들웨어 디렉터리를 포함하기 때문에 용량이 매우 크다.

      때문에 용량이 한정된 물리 스토리지 영역을 효율적으로 사용하기 위하여 Copy on Write로 이미지의 변경을 관리한다.

      

    Comments