[Docker] 컨테이너와 도커
by Choi HyeSun
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 이미지를 공유할 수 있음
-
- 공식 레지스트리 - 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에 대한 충분한 경험이 있는 경우만 사용
-
Subscribe via RSS