티스토리 뷰

반응형

이 글은 '완벽한 IT 인프라 구축을 위한 Docker(Asa Shiho 지음, Yamada Yoshihiro 감수, 신은화 옮김)'  책을 바탕으로 요약 및 실습한 내용을 정리한 글입니다.


제2장 컨테이너 가상화 기술과 Docker

2-1. 가상화 기술

가상 환경

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

물리적인 서버가 아니므로 유지 보수에 대한 부담을 덜 수 있다.


대표적인 가상화 기술

호스트 가상화

  • 하드웨어 위에 베이스가 되는 호스트OS를 설치하고 그 위에 가상화 소프트웨어를 설치한 뒤 게스트OS를 구동하는 가상화 기술.
  • 가상화 소프트웨어를 설치하여 간편하게 가상 환경을 구축할 수 있기 때문에 개발 환경 구축에 많이 사용됨.
  • 호스트OS 상에서 게스트 OS가 동작하기 때문에 오버헤드가 클 수밖에 없음.
  • ex) Oracle VM VirtualBox, VMWare Player 등

하이퍼바이저 가상화

  • 하드웨어 위에 가상화 전문 소프트웨어인 '하이퍼바이저'를 설치하고 하드웨어와 가상 환경을 제어.
  • 호스트OS 없이 하드웨어를 직접 제어하기 때문에 효율적으로 리소스 사용 가능.
  • 가상 환경별로 OS가 동작하기 때문에 가상 환경 동작에 걸리는 오버헤드가 클 수 있음.
  • ex) Hyper-V, XenServer 등

컨테이너 가상화

  • 호스트OS상에서 논리적으로 구역(컨테이너)를 나눠 애플리케이션 동작을 위한 라이브러리와 애플리케이션 등을 컨테이너 안에 넣고, 개별 서버처럼 사용.
  • 오버헤드가 적어 가볍고 빠름.
  • ex) Docker

2-2. 컨테이너 가상화 기술의 역사

FreeBSD Jail

  • 오픈 소스 UNIX인 FreeBSD의 가상화 기술
  • 프로세스 분할 : 같은 Jail에서 동작하는 프로세스에만 액세스할 수 있도록 프로세스를 분산
  • 네트워크 분할 : IP Address가 개별적으로 할당. Jail 이외에 액세스를 하기 위해서는 별도의 네트워크가 필요.
  • 파일시스템 분할 : Jail에서 사용하는 파일 시스템을 분할하여 조작할 수 있는 커맨드와 파일을 제한.

Solaris Containers

  • Oracle의 상용 UNIX인 Solaris의 가상화 기술
  • 기간계 업무 시스템 운영 환경에서 많이 이용
  • RISC 기반 마이크로프로세서로도 동작
  • Solaris Zone 기능 : 하나의 OS 공간을 가상화로 분할하여 여러 OS가 동작하는 것처럼 보이게 하는 소프트웨어 파티션 기능. 기반이 되는 OS 영역을 'global zone', 분할된 가상 Zone을 'non-global zone'이라고 함. non-global zone에서 업무 애플리케이션이 동작.
  • Solaris 리소스 매니저 기능 : non-global zone에서 CPU와 메모리 등 하드웨어 리소스를 배분하는 리소스 관리 기능. 중요도가 높은 시스템에 리소스를 우선 할당.
  • Docker와 유사.
  • 한 대의 물리 서버를 가상화하여 애플리케이션 실행 환경을 Zone으로 분할한 뒤 각각을 제어.

2-3. Docker의 특징

Docker는 컨테이너 가상화 환경에서 애플리케이션을 관리하고 실행하기 위한 오픈소스 플랫폼. Linux 위에서 동작하는 것이 특징이며 Go 언어로 만들어졌다.

Docker는 온프레미스 환경뿐만 아니라 다음의 클라우드 환경에서도 동작한다.

  • Amazon EC2
  • Google Cloud Platform
  • IBM SoftLayer
  • Rackspace Cloud

Mac OS X와 Microsoft Windows 같은 클라이언트 OS에서는 Docker Toolbox가 제공. VirtualBox로 구성된 가상 환경에서 전용 Linux 배포판을 통해 Docker를 동작.


이식성

  • 한번 만들어두면 어디에서든 동작하는 소프트웨어의 특성
  • Docker는 높은 이식성으로 클라우드 시스템과 호환이 잘되는 것이 특징
  • Docker 컨테이너의 기반이 되는 Docker 이미지가 있다면 애플리케이션을 동일한 환경에서 구동할 수 있음

상호운용성

  • 여러 조직이나 시스템과 연계하여 사용할 수 있는 소프트웨어의 특성
  • Docker는 벤더뿐만 아니라 여러 오픈소스와도 쉽게 연계할 수 있음

Docker 전용 Linux 배포판

  • 경량과 고속이 특징
  • 서버 용도로 사용하기 때문에 불필요한 애플리케이션과 커맨드 등은 필요하지 않음
  • 배포판에 따라 Docker 구동에 최적화되도록 OS가 튜닝
  • 파일 시스템의 일부분이 읽기 전용(read only)로 되어 있어 보안 리스크도 줄어듬
  • ex) Red Hat Enterprise Linux Atomatic Host(RHEL Atomic Host), Project Atomic, Snappy Ubuntu Core, Core OS

2-4. Docker의 기본 기능

Docker 이미지 생성

  • Docker는 애플리케이션 실행에 필요한 프로그램, 라이브러리, 미들웨어와 OS, 네트워크 설정 등을 하나로 모아 'Docker 이미지'를 생성
  • Doocker 이미지란 애플리케이션 실행에 필요한 파일이 담긴 디렉터리
  • Docker 이미지는 Docker 커맨드를 사용하여 수동으로 만들 수 있으며 Dockerfile 프로그램을 통해 자동으로 생성할 수도 있음
  • Docker 이미지를 중첩하여 사용 가능
  • Docker에서는 구성 변경이 일어난 부분을 따로 관리

Docker 컨테이너 동작

  • Linux 상에서 컨테이너 단위로 서버를 구동
  • Docker 이미지를 통해 여러 컨테이너 구동 가능
  • 이미 동작하고 있는 OS상에서 프로세스를 실행시키는 것과 거의 비슷한 속도로 빠르게 기동
  • 하나의 Linux 커널을 여러 컨테이너가 공유
  • 컨테이너 내에서 동작하는 프로세스를 하나의 그룹으로 관리하고 그룹별로 각각 다른 파일 시스템과 호스트명, 네트워크 등이 할당
  • 서로 다른 그룹인 경우, 프로세스와 파일에 접근 불가
  • 컨테이너를 독립된 공간으로 관리

Docker 이미지 공개 및 공유

  • Docker 이미지는 Docker 레지스트리에서 통합적으로 관리 가능
  • 베이스 이미지(ex) Ubuntu, CentOS, ... )에 미들웨어와 라이브러리, 애플리케이션 등을 포함한 이미지를 중첩하여 독자적인 Docker 이미지 생성
  • Docker 커맨드를 통해 Docker Hub에 로그인하여 레지스트리상에서 이미지를 검색하고 업로드 및 다운로드 가능
  • GitHub 위에서 Dockerfile을 관리하고 Docker 이미지를 자동으로 생성하여 Docker Hub에 공개 가능 -> Automated Build

Docker 컴포넌트

Docker는 코어 기능을 제공하는 'Docker Engine'을 중심으로, 이미지를 생성→공개→컨테이너 실행하기 위한 여러 가지 컴포넌트를 제공합니다.

Docker Engine(Docker의 코어 기능)

  • Docker 이미지 생성과 컴포넌트 구동 등을 위한 Docker의 코어 기능
  • Docker 커맨드 실행 및 Dockerfile을 통한 이미지 생성 등을 수행

Docker Kitematic(Docker의 GUI 툴)

  • Docker 이미지 생성과 컴포넌트 구동 등을 위한 Docker의 GUI 툴

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

  • 컨테이너의 기반이 되는 Docker 이미지를 공개 및 공유하기 위한 레지스트리 기능

Docker Compose(여러 컨테이너를 통합 관리)

  • 여러 컨테이너의 구성 정보를 코드로 정의하고 커맨드를 통해 애플리케이션 실행 환경을 구성하는 컨테이너 통합 관리 툴

Docker Machine(Docker 실행 환경 구축)

  • 로컬 호스트용인 VirtualBox를 시작으로 AWS EC2와 DigitalOcean, SoftLayer 등 클라우드 환경에 Docker 실행 환경을 커맨드로 자동 생성하기 위한 툴

Docker Swarm(클러스터 관리)

  • 여러 Docker 호스트를 클러스터화하기 위한 툴
  • Manager는 클러스터 관리와 API를 제공하며 Node는 Docker 컨테이너를 실행

2-5. Docker의 동작 구조

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

  • 컨테이너를 나눌 때 Linux 커널의 namespace 기능을 사용
  • 한데 합쳐진 데이터에 이름을 붙여 충돌 가능성을 낮추고 쉽게 참조할 수 있도록 하는 기능
  • 이름이 어떤 namespace에 속하느냐에 따라 달라지며 같은 이름이더라도 서로 다른 namespace라면 다른 존재로 인식됨

Linux 커널의 namespace 기능은 Linux 오브젝트에 이름 붙이는 것을 통하여 다음에서 설명하는 6가지의 독립된 환경을 구축할 수 있습니다.

*PID namespace

  • PID와 프로세스를 분리
  • namespace가 서로 다른 프로세스는 서로 액세스 불가능
※ PID : Linux에서 각 프로세스에 할당된 고유한 ID

Network namespace

  • 네트워크 디바이스, IP Address, 포트 번호, 라우팅 테이블, 필터링 테이블 등 네트워크 리소스를 namespace별로 할당 가능
  • 호스트OS 위에서 사용 중인 포트가 있어도 컨테이너 안에서 같은 번호의 포트 사용 가능

UID namespace

  • UID(user ID), GID(Group ID)를 namespace별로 독립하여 가질 수 있음
  • namespace 안에서 호스트OS상의 UID 및 GID와 서로 연결되어 namespace 안과 밖에서 서로 다른 UID 및 GID를 가질 수 있음
  • namespace의 관리자 계정이 호스트OS에서는 관리 권한을 가질 수 없게 할 수 있으므로 보다 보안을 강화할 수 있음

*MOUNT namespace

  • 마운트를 조작하여 namespace 내에 파일 시스템 트리를 구성
  • namespace 내의 마운트는 호스트OS와 다른 namespace에서 액세스할 수 없음
※ MOUNT(마운트) : 컴퓨터 내에 접속한 기기와 기억장치를 OS에 인식시키는 것

UTS namespace

  • namespace별로 호스트명과 도메인명을 독자적으로 가질 수 있음

IPC namespace

  • 프로세스 간의 통신(IPC) 오브젝트를 namespace별로 가질 수 있음
  • PID : 공유 메모리와 

    *세마포어 및 

    *

    메세지 큐의 System V 프로세스 간 통신 오브젝트

※ 세마포어 : 프로세스에 필요한 자원 관리에 이용되는 배타 제어 방식
※ 메세지 큐 : 여러 프로세스 사이에서 비동기 통신이 이루어질 때 사용하는 큐잉 방식

리소스 관리 구조(cgroup)

  • 프로세스 및 thread를 그룹화하여 이를 관리하는 기능
  • 호스트OS의 CPU, 메모리와 같은 리소스를 그룹별로 제한 가능
  • 한 컨테이너가 같은 호스트OS상에서 동작하는 다른 컨테이너에 영향을 주는 일을 막을 수 있음
  • 다음과 같은 주요 서브 시스템 관리 가능
항목설명
cpuCPU 사용량 제한
cpuacctCPU 사용량 통계 정보 제공
cpusetCPU와 메모리 배치 제어
memory메모리와 스와프 사용량 제한
devices디바이스 액세스 허가 및 제한
freezer그룹에 속한 프로세스 정지 및 재개
net_cls네트워크 제어 태그 추가
blkio블록 디바이스 입출력량 제어
  • 계층 구조로 프로세스를 그룹화하여 관리 가능
  • 하위 cgroup은 상위 cgroup의 제한 설정이 그대로 적용됨

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

※ 브리지(bridge) : OSI 모델의 데이터 링크 계층에 있는 여러 개의 네트워크 세그먼트를 연결해줌.

※ NIC(Network Interface Controller) : 컴퓨터를 네트워크에 연결하여 통신하기 위해 사용하는 하드웨어 장치. 랜 카드, 네트워크 인터페이스 컨트롤러(NIC), 네트워크 인터페이스 카드, 네트워크 어댑터, 네트워크 카드, 이더넷 카드 등으로도 불림.


Docker의 컨테이너는 서버의 물리 NIC와 별도로 각 컨테이너마다 가상 NIC가 할당되어 있습니다. 또한 이러한 가상 NIC는 docker0이라는 가상 bridge에 접속하여 컨테이너끼리 통신합니다. docker0은 Docker 데몬을 기동한 후에 생성되며, 172.17.42.1 주소가 할당됩니다. (그림 참조)

Docker에서 컨테이너를 구동하면 컨테이너에 172.17.0.0/16 subnet mask를 가진 private IP Address가 eth0에 자동으로 할당됩니다. eth0에는 호스트OS에 생성된 가상 NIC(vethxxx)가 페어로 할당됩니다. veth는 OSI 7계층 Layer 2의 가상 네트워크 인터페이스로서 페어된 NIC끼리 터널링 통신을 수행합니다.

가상 NIC(vethxxx)는 컨테이너에서 eth0으로 인식됩니다.

※ 데몬(daemon) : 사용자가 직접적으로 제어하지 않고, 백그라운드에서 돌면서 여러 작업을 하는 프로그램. 일반적으로 프로세스로 실행. 대개 부모 프로세스를 갖지 않아 PPID가 1이며, 프로세스 트리에서 init 바로 아래에 위치.

Docker 컨테이너는 이러한 네트워크 구성을 기본으로 다음과 같이 네트워크 통신을 수행합니다.

Docker 컨테이너 간의 통신

동일한 호스트 상의 Docker 컨테이너는 구동 시 private Address가 자동으로 할당되므로 컨테이너끼리 통신하기 위하여 '링크 기능'을 사용합니다. 컨테이너를 구동할 때, 통신하려는 컨테이너 이름을 지정하여 링크하면 해당 정보가 /etc/host에 환경변수로 저장되어 직접 통신할 수 있습니다.


단, 링크 기능을 사용한 통신은 동일 호스트, 즉 가상 bridge docker0에 접속한 컨테이너끼리만 가능합니다. 멀티 호스트 환경에서는 링크 기능을 이용한 통신이 불가능하므로 주의해야 합니다. 또한 보안 요구 사항에 따라 컨테이너 간 통신을 차단하도록 설정할 수 있습니다.

Docker 컨테이너와 외부 네트워크 통신

Docker 컨테이너가 외부 네트워크와 통신할 때에는 가상 bridge docker0와 호스트OS의 물리 NIC에서 패킷을 전송해야 합니다. 이 때, Docker에서는 NAPT 기능을 사용하여 접속합니다.

NAPT(Network Address Port Translation)란 하나의 IP Address를 여러 컴퓨터에서 공유하는 기술로서 IP Address와 포트 번호를 변환하는 기능입니다. TCP 및 UDP 포트 번호까지 동적으로 변환하기 때문에 여러 머신에서 한 global IP Address로 접속할 수 있습니다.

이 기능은 컨테이너를 구동할 때, 내부에서 사용하고 있는 포트를 가상 bridge docker0에서 개방할 때 사용됩니다. 예를 들어 컨테이너 구동 시, 컨테이너 내의 웹 서버(http 데몬)가 사용하는 80번 포트를 호스트OS의 8080번 포트로 전송하도록 설정하였을 때, 외부 네트워크에서 호스트OS의 8080번 포트에 액세스하면 컨테이너 내의 80번 포트로 연결되는 구조입니다.


NAT와 NAPT의 차이

private IP Address와 global IP Address를 변환하여 private IP Address가 할당된 컴퓨터가 인터넷에 접속할 수 있도록 하는 기술로 NAT와 NAPT(IP masquerade)가 있습니다.

  • NAT(Network Address Translation) : global IP Address와 private IP Address를 1:1로 변환. 여러 클라이언트가 액세스할 수 없음
  • NAPT(Network Address Port Translation) : private IP Address와 포트 번호까지 변환하는 기술. private IP Address별로 다른 포트 번호를 변환.

Docker 이미지의 데이터 관리 구조

데이터를 바로 복사하지 않고 원본을 그대로 참조하여 원본 또는 복사본 데이터 중 하나가 변경될 때 빈 공간을 확보하여 데이터를 복사하는 구조를 'Copy on Wirte'라고 합니다. Docker에서는 이러한 Copy on Write 방식으로 컨테이너 이미지의 변경을 관리합니다.

Docker 이미지를 관리하는 스토리지 디바이스는 다음과 같습니다.

  • Btrfs : Linux용 Copy on Write 파일 시스템. subvolume 기능과 snapshot 기능을 사용하여 컨테이너 이미지의 변경을 파일 시스템 층에서 관리
  • AUFS : 서로 다른 파일 시스템의 파일과 디렉터리를 중첩하여 하나의 파일트리를 구성할 수 있는 파일 시스템
  • Device Mapper : Linux 블록 디바이스 드라이버와 이를 지원하는 라이브러리. 파일 시스템의 블록 I/O와 디바이스 매핑을 관리. 개별 파일 시스템에 의존하지 않으므로 다양한 환경에서 사용 가능
  • overlay : Union filesystem의 하나로 파일 시스템에 또 다른 파일 시스템을 합치는 구조


반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함