Container 기술

서버 가상화 기술과 컨테이너 기술

  • 매우 비슷하지만 목적이 다름

  • 서버 가상화 기술 : 서로 다른 환경을 어떻게 효율적으로 에뮬레이트할지를 지향

  • 컨테이너 기술 : 애플리케이션의 실행 환경을 모음으로써 이식성을 높이고 확장성이 좋은 환경에서 작동하는 것을 지향


서버 가상화 기술

  • 몇 가지 방식이 있지만 대표적인 2가지를 소개

  • 호스트형 서버 가상화

    • 하드웨어 상에 베이스가 되는 호스트 OS를 설치

    • 호스트 OS에 가상화 소프트웨어를 설치 후, 이 가상화 소프트웨어 상에서 게스트 OS를 작동

    • 가상화 소프트웨어를 설치하여 간편하게 가상 환경을 구축할 수 있기 때문에 개발 환경 구축 등에 주로 사용

    • Oracle에서 제공하는 ‘VirtualBox’나 VMware의 ‘VMware’ 등이 있음

    • 컨테이너와 다르게 호스트 OS상에서 다른 게스트 OS를 움직이기 때문에 오버헤드가 커짐

    • 간편하게 도입이 가능하지만 컴퓨터의 사양에 따라 속도가 느려질 수 있음

  • 하이퍼바이저형 서버 가상화

    • 하드웨어 상에 가상화를 전문으로 수행하는 소프트웨어인 ‘하이퍼바이저’를 배치

    • 하드웨어와 가상 환경을 제어

    • Microsoft Windows Server의 ‘Hyper-V’나 Citrix사의 ‘XenServer’ 등

    • 호스트 OS 없이 하드웨어를 직접 제어하기 때문에 자원을 효율적으로 사용할 수 있음

    • 가상 환경마다 별도의 OS가 작동하므로 가상 환경의 시작에 걸리는 오버헤드가 커짐

    • 하이퍼바이저형은 펌웨어로서 구축하는 경우가 많고, 제품이나 기술에 따라 다양한 방법이 있음

    • 클라우드의 가상 머신에서도 사용하는 방법


컨테이너

  • 호스트 OS상에 논리적인 구획(컨테이너)를 만들고, 애플리케이션을 작동시키기 위해 필요한 라이브러리나 애플리케이션 등을 하나로 모아, 마치 별도의 서버인 것 처럼 사용할 수 있게 만든 것

  • 호스트 OS의 리소스를 논리적으로 분리 후 여러 개의 컨테이너가 공유해서 사용

  • 오버헤드가 적기 때문에 가볍고 고속으로 작동

  • 컨테이너 기술 사용시 OS나 디렉토리, IP 주소 등과 같은 시스템 자원을 마치 각 애플리케이션이 점유하고 있는 것 처럼 보이게 할 수 있음

    • 호스트 OS에 영향을 받지 않는 것처럼
  • 애플리케이션의 실행에 필요한 모듈을 컨테이너로 모을 수 있기 때문에 여러 개의 컨테이너를 조합하여 하나의 애플리케이션을 구축하는 마이크로 서비스형 애플리케이션과 친화성이 높음


컨테이너 역사1. FreeBSD Jail

  • 오픈소스 Unix인 FreeBSD의 기술

  • 관리자 권한의 범위가 Jail 안으로 제한되기 때문에 시스템 관리자는 종료와 같은 시스템 전체를 조작하는 권한을 부여하지 않고도 일반 사용자에게 관리자 권한을 부여할 수 있음

  • 기능

    • 프로세스의 구획화 : 같은 Jail에서 작동하는 프로세스만 액세스할 수 있도록 프로세스 분리, 안밖이 서로 영향을 줄 수 없음

    • 네트워크의 구획화 : Jail 하나하나에 IP 주소가 하나 이상 할당, 외부에는 네트워크를 경유해야 엑세스할 수 있음

    • 파일 시스템의 구획화 : Jail에서 사용하는 파일 시스템을 구획화함으로써 조작할 수 있는 명령/파일을 제한


컨테이너 역사2. Solaris Containers

  • Oracle의 상용 Unix인 Solaris에서 사용하는 컨테이너 기술

  • Docker가 나오기 약 10년 전에 등장한 오래된 기술이지만 Docker와 구조가 매우 비슷

  • 애플리케이션의 실행 환경을 존으로 구획화하여 구획들을 제어

  • 기능

    • Solaris 존 기능 : 하나의 OS 공간을 가상적으로 분할하여 여러 OS가 작동하는 것 처럼 보여주는 소프트웨어 파티셔닝 기능
      베이스 영역 - 글로벌 존, 구획화된 가상 존 - 비글로벌 존(완전히 격리, 서로 액세스할 수 없음)

    • Solaris 리소스 매니저 기능 : 비 글로벌 존에서 하드웨어 리소스를 배분하는 리소스 관리 기능, 중요도에 따른 배분 가능


컨테이너 역사3. Linux Containers(LXC)

  • Linux상에서 사용하는 컨테이너 환경

  • Linux 커널의 컨테이너 기능을 이용하기 위한 툴이나 API를 제공

  • 컨테이너는 namespace와 cgroups라는 리소스 관리 장치를 사용하여 분리된 환경을 만듦

  • 데이터 영역에 대해서는 특정 디렉토리를 루트 디렉토리로 변경하는 chroot를 사용하여 분리 환경을 만듦

  • Docker는 이전 버전에서는 내부에서 LXC를 썼었지만, 현재는 사용하지 않음



Docker란?

  • 애플리케이션의 실행에 필요한 환경을 하나의 이미지로 모아두고, 그 이미질르 사용하여 다양한 환경에서 애플리케이션 실행 환경을 구축 및 운용하기 위한 오픈 소스 플랫폼

  • 내부에서 컨테이너 기술을 사용하는 것이 특징


프로그래머에게 도커란?

  • 웹 시스템 개발 시 애플리케이션을 가동시키기 위해서는 다음이 필요

    • 애플리케이션의 실행 모듈(프로그램)

    • 미들웨어나 라이브러리군

    • OS/네트워크 등 인프라 환경 설정

  • docker는 인프라 환경을 컨테이너로 관리

    • 애플리케이션의 실행에 필요한 모든 파일 및 디렉토리를 컨테이너로 모음

    • 컨테이너의 바탕이 되는 이미지를 Docker Hub같은 repository에서 공유

  • 프로그래머는 Docker를 사용하여 개발할 애플리케이션의 실행에 필요한 모든 것이 포함되어 있는 Docker 이미지 작성

    • 컨테이너에 바탕이 됨(가동시킴)

    • Docker가 설치되어 있다면 어디서든 작동(개발/테스트/운영/로컬PC/서버/클라이언트/클라우드 등) → 이식성이 높음



Docker 기능

  • 크게 3가지 기능이 있음

    • Build : Docker 이미지를 만드는 기능

    • Ship : Docker 이미지를 공유하는 기능

    • Run : Docker 이미지를 작동시키는 기능


Build - Docker 이미지를 만드는 기능

  • Docker 이미지

    • 애플리케이션의 실행에 필요한 프로그램 본체, 라이브러리, 미들웨어, OS나 네트워크 설정을 하나로 모아서 만듦

    • 실행 환경에서 움직이는 컨테이너의 바탕

    • 하나의 이미지에는 하나의 어플리케이션만 넣어두고, 여러 개의 컨테이너를 조합하여 서비스를 구축한다는 방법을 권장

    • 애플리케이션의 실행에 필요한 파일들이 저장된 디렉토리

    • Docker 명령을 사용하여 이미지를 tar 파일로 출력 가능

  • Docker 이미지 작성

    • Docker의 명령을 사용하여 수동으로 만들 수 있음

    • Dockerfile이란 설정 파일을 만들어 그것을 바탕으로 자동으로 만들 수 있음

    • 지속적인 관리 관점에선 Dockerfile로 관리하는 것이 바람직함

  • Docker 이미지는 겹쳐서 사용할 수 있음

    • OS용 이미지에 웹 애플리케이션용 이미지를 겹쳐서 새 이미지를 만들 수 있음

    • 구성에 변경이 있던 부분을 차분(이미지 레이어)으로 관리

    • 애플리케이션의 실행에 필요한 파일은 크기가 큰 경우도 있으므로 가능한 효율이 좋은 이미지를 만들 필요가 있음


Ship - Docker 이미지를 공유하는 기능

  • Docker 레지스트리

    • Docker 이미지를 공유할 수 있음
  • Docker Hub

    • 공식 레지스트리 - Ubuntu나 CentOS같은 Linux 배포판의 기본 기능을 제공하는 베이스 이미지를 내포

    베이스 이미지에 미들웨어/라이브러리/전개할 애플리케이션 등을 넣은 이미지를 겹쳐서 독자적인 Docker 이미지를 만듦

    • 공식 이미지 외에 개인이 작성한 이미지도 Docker Hub에서 자유롭게 공개하여 공유할 수 있음

    • Docker 명령을 통해 Docker Hub에 로그인하여 레지스트리에 있는 이미지를 검색, 업로드, 다운로드 할 수 있음

  • Automated Build

    • Docker Hub는 GitHub이나 Bitbucket과 연동할 수 있음

    • Dockerfile을 GitHub 등을 통해 관리하고, 거기서 Docker 이미지를 자동으로 생성하여 Docker Hub에서 공개하는 것


Run - Docker 이미지를 작동시키는 기능

  • Docker는 Linux 상에서 컨테이너 단위로 서버 기능을 작동

    • 바탕은 Docker 이미지

    • Docker 이미지만 있으면 Docker가 설치되었다면 어디서든 컨테이너 작동 가능

    • Docker 이미지로 여러 컨테이너를 기동할 수 있음

  • 컨테이너의 기동, 정지, 파기는 Docker 명령어를 사용

  • 가상화 기술과의 비교

    • 가상화 기술 : 서버 기능을 실행시키려면 OS의 실행부터 시작하기 때문에 시간이 걸림

    • 도커 기술 : 이미 움직이는 OS에서 프로세스를 실행시키는 것과 흡사한 속도로 빨리 실행 가능

  • 운영 환경에서의 Docker

    • 모든 Docker 컨테이너를 한 대의 호스트 머신에서 작동시키는 일은 드물고, 여러 대의 호스트 머신으로 된 분산 환경을 구축
      - 시스템의 트래픽 증감, 가용성 요건, 신뢰도 요건 등 공려

    • 관리는 오케스트레이션 툴을 이용하는 것이 일반적
      - 오케스트레이션 툴은 분산 환경에서 컨테이너를 가동시키기 위해 필요한 기능을 제공


Docker 컴포넌트

  • Docker Engine (Docker의 핵심 기능)

    • Docker 이미지를 생성하고 컨테이너를 기동시키기 위한 핵심 기능

    • Docker 명령 실행 및 Dockerfile에 의한 이미지 생성

  • Docker Registry (이미지 공개 및 공유)

    • Docker 이미지를 공개 및 공유하기 위한 레지스트리 기능

    • Docker의 공식 레지스트리 서비스인 Docker Hub도 이 Docker Registry를 사용

  • Docker Compose (컨테이너 일원 관리)

    • 여러 개의 컨테이너 구성 정보를 코드로 정리하고, 명령을 실행함으로써 애플리케이션의 실행 환경을 구성하는 컨테이너들을 일원 관리하기 윈한 툴
  • Docker Machine (Docker 실행 환경 구축)

    • 로컬 호스트용인 VirtualBox를 비롯하여 AWS의 EC2나 MS Azure와 같은 클라우드 환경에 Docker의 실행 환경을 명령으로 자동 생성하기 위한 툴
  • Docker Swarm (클러스터 관리)

    • 여러 Docker 호스트를 클러스터화하기 위한 툴

    • Kubenetes로도 가능


Docker를 클라이언트 OS에서 사용하려면?

  • macOS (OSX Yosemite 10.10.3 이상)

    • Docker for Mac 설치
  • Windows (Microsoft Windows 10 Professional or Enterprise 64-bit)

    • Docker for Windows 설치
  • 위 외에는 Docker Toolbox를 이용



Docker 작동구조

  • Docker는 Linux 커널의 기술이 베이스

  • Docker가 작동하기 위한 기초 기술


namespace : 컨테이너 구획화

  • Linux 커널의 namespace 기능으로 Docker 컨테이너를 구획화

  • namespace

    • ‘이름공간’

    • 한 덩어리의 데이터에 이름을 붙여 분할함으로써 충돌 가능성을 줄이고, 쉽게 참조할 수 있게 하는 개념

  • Linux 커널의 namespace는 Linux의 오브젝트에 이름을 붙임으로써 6개의 독립된 환경을 제공

  • ① PID namespace

    • PID : Linux에서 각 프로세스에 할당된 고유 ID

    • PID namespace : PID와 프로세스를 격리 → namespace가 다른 프로세스끼리는 서로 액세스 불가

  • ② Network namespace

    • Network namespace : 네트워크 디바이스, IP 주소, 포트 번호, 라우팅 테이블, 필터링 테이블 등과 같은 네트워크 리소스를 격리된 namespace마다 독립적으로 가질 수 있음

    • 호스트 OS상 사용 중인 포트가 있더라도 컨테이너 안에서 동일한 번호의 포트 사용 가능

  • ③ UID namespace

    • UID namespace : UID(사용자 ID), GID(그룹 ID)를 namespace 별로 독립적으로 가질 수 있게

    • namespace 안과 호스트 OS상의 UID/GID가 서로 연결되어 이름공간 안팎에서 서로 다른 UID/GID를 가질 수 있음

    • namespace 관리자 계정은 호스트 OS에 대해서는 관리 권한을 일절 갖지 않음

  • ④ MOUNT namespace

    • Linux에서 파일 시스템을 사용하기 위해서는 마운트(컴퓨터에 연결된 기기나 기억장치를 OS에 인식시켜 이용 가능한 상태로 만듦)가 필요

    • MOUNT namespace : 마운트 조작을 하면 namespace 안에 격리된 파일 시스템 트리를 만듦

    • namespace 내에서 수행한 마운트는 다른 namespace에서 액세스할 수 없음

  • ⑤ UTS namespace

    • UTF namespace : namespace별로 호스트명이나 도메인명을 독자적으로 가질 수 있음
  • ⑥ IPC namespace

    • IPC namespace : 프로세스 간의 통신(IPC) 오브젝트를 namespace별로 독립적으로 가질 수 있음

    • IPC : System V 프로세스 간의 통신 오브젝트라고 하는 공유 메모리나 세마포어/메시지 큐

    • 세마포어 : 프로세스가 요구하는 자원 관리에 이용되는 배타제어 장치

    • 메시지 큐 : 여러 프로세스 간에서 비동기 통신을 할 때 사용되는 큐잉 장치


cgroups : 릴리즈 관리 장치

  • Docker에서는 cgroups 기능을 사용하여 물리 머신 상의 자원을 여러 컨테이너가 공유하여 작동할 때 자원의 할당 등을 관리

  • 프로세스와 스레드를 그룹화하여, 그 그룹 내에 존재하는 프로세스와 스레드에 대한 관리를 수행하기 위한 기능

    • Linux에서는 프로그램을 프로세스로서 실행

    • 프로세스는 하나 이상의 스레드 모음으로 움직임

  • 예) 호스트 OS의 CPU나 메모리와 같은 자원에 대해 그룹별로 제한을 둘 수 있음

    • 어떤 컨테이너가 호스트 OS의 자원을 모두 사용해버려서 동일한 호스트 OS 상에서 가동되는 다른 컨테이너에 영향을 주는 일을 막을 수 있음
  • cgroups으로 관리할 수 있는 주요한 서브 시스템

항목 설명
cpu CPU 사용량 제한
cpuacct CPU 사용량 통계 정보 제공
cpuset CPU나 메모리 배치 제어
memory 메모리나 스왑 사용량 제한
devices 디바이스에 대한 액세스 허가/거부
freezer 그룹에 속한 프로세스 정지/재개
net_cls 네트워크 제어 태그 부가
blkio 블록 디바이스 입출력량 제어


  • 계층 구조를 사용하여 프로세스를 그룹화하여 관리할 수 있음

    • 부모자식 관계에서는 자식이 부모의 제한을 받음

    • 자식이 부모의 제한을 초과하게 설정하더라도, 부모의 제한에 걸림


가상 브리지, 가상 NIC : 네트워크 구성

  • Linux는 Docker를 설치하면 서버의 물리 NIC가 docker0이라는 가상 브리지 네트워크로 연결

  • docker0 : 가상 브리지

    • Docker를 실행시킨 후 디폴트로 만들어 짐
  • verthxxx : 가상 NIC

    • 가상NIC는 컨테이너에서는 eth0으로 확인됨

    • Docker컨테이너 실행시 컨테이너에 프라이빗 IP 주소가 eth0으로 자동 할당

    • OSI 참조 모델의 2 Layer인 가상 네트워크 인터페이스, 페어인 NIC와 터널링 통신

  • Docker 컨테이너와 외부 네트워크 통신시 가상 브리지 docker0와 호스트 OS의 물리 NIC에서 패킷을 전송하는 장치가 필요

    • Docker에서는 NAPT 기능에 Linux의 iptables를 사용
  • NAPT(Network Address Port Translation)

    • 하나의 IP 주소를 여러 컴퓨터가 공유하는 기술

    • IP와 포트 번호를 변환하는 기능

    • 프라이빗 IP 주소와 글로벌 IP 주소를 부과적으로 상호 변환하는 기술

    • TCP/IP의 포트 번호까지 동적으로 변환

    • 글로벌 IP 주소로 여러 대의 머신이 동시에 연결할 수 있음

  • Docker에서 NAPT 기능 사용시

    • 컨테이너 시작 시 컨테이너 안에서 사용하고 있는 가상 브리지인 docker0 개방

    • IP 마스커레이드(NAPT)를 통해 호스트 port(예: 8080)와 컨테이너 port(예: 80) 설정

    • 외부에서 8080으로 붙으면, 컨테이너의 80과 연결됨


NAT와 IP마스커레이드 차이

  • NAT(Network Address Translation)

    • 글로벌 IP 주소와 프라이빗 IP 주소를 1:1로 변환, 동시에 여러 클라이언트가 엑세스할 수 없음
  • NAPT(Network Address Port Translation)

    • 프라이빗 IP 주소와 함께 포트 번호도 같이 변환

    • 프라이빗 IP 주소를 글로벌 IP 주소로 변환할 때 프라이빗 IP 주소별로 서로 다른 포트로 변환

    • 하나의 글로벌 IP와 여러 개의 프라이빗 IP 주소를 변환할 수 있음

    • Linux에서 NAPT를 구축하는 것을 IP 마스커레이드(mascarade;가면무도회)라고 부름


Docker 이미지의 데이터 관리 장치

  • Copy on Write

    • Docker에서 해당 방식으로 컨테이너의 이미지를 관리

    • 복사를 요구받아도 바로 복사하지 않고 원래의 데이터를 그대로 참조시켜, 원본 또는 복사 어느 쪽에 수정이 가해진 시점에 비로소 빈 영역을 확보하고 데이터를 복사

  • Docker 이미지를 관리하는 스토리지 디바이스

    • AUFS : 현재 표준 Linux 커널의 일부가 아님, 다른 파일 시스템의 파일이나 디렉토리를 투과적으로 겹쳐서 하나의 파일 트리를 구성할 수 있는 파일 시스템

    • Btrfs : Linux용 Copy on Write 파일 시스템, 롤백 기능이나 스냅샷 기능을 갖고 있음, 2007년 Oracle에 의해 발표

    • Device Mapper : Linux Kernel 2.6에 들어간 Linux의 블록 디바이스 드라이버와 그것을 지원하는 라이브러리들, 파일 시스템의 블록 I/O와 디바이스 매핑 관계를 관리
      thin-provisioning/snapshot 기능, RedHat OS 계열이나 Ubuntu 등에서 Docker를 이용할 때 사용

    • OverlayFS : UnionFS 중 하나, 파일 시스템에 다른 파일 시스템을 투과적으로 머징(merging)
      Linux Kernel 3.18에 도입, 읽기 전용 파일/디렉토리를 읽기/변경 가능
      Docker에서는 overlay와 overlay2라는 2 종류의 드라이버 이용 가능, Linux Kernel 4.0 이상의 경우 overlay2 사용 권장

    • ZFS : 썬마이크로시스템즈(Oracle)이 개발한 새로운 파일 시스템
      볼륨관리, 스냅샷, 체크섬 처리, 리플리케이션 지원. ZFS on Linux에 대한 충분한 경험이 있는 경우만 사용