컨테이너 기술의 개요, Docker의 개요, Docker의 기능, Docker의 작동 구조
컨테이너
HOST OS상에 논리적인 구획을 만들고 애플리케이션을 작동시키기 위해 필요한 라이브러리나 애플리케이션들을 하나로 모아 별도의 서버인 것 처럼 사용하게 만드는 것
오버헤드가 적기 때문에 가볍고 고속이다.
컨테이너 사용 장점
앱 구동을 위해 개발자가 알아야 하는 정보에서 'OS 요소'가 사라진다.
Host OS에서 움직이는 애플리케이션은 같은 시스템 리소스를 사용
동일한 디렉토리, IP를 공유 -> 컨테이너 사용 시 각 애플리케이션이 자원을 점유하는 것 처럼 사용이 가능
호스트형 서버 가상화 : Virtual Box, Workstation Player 같은 것을 의미, Host OS위에 Guest OS를 올리는 방식, 컨테이너 방식과 다르게 Guest OS가 하나 더 가동하는 것이여서 오버헤드가 크다.
컴퓨터 성능이 떨어지면 속도가 느려짐
하이퍼 바이저형 서버 가상화 : 하드웨어위에 바로 가상화 전문 소프트웨어 '하이퍼 바이저'를 올린다. Host OS없이 직접 사용하므로 자원의 효율이 좋다. 단 가상환경마다 별도의 OS가 작동하므로 시작에서 오버헤드가 존재
(클라우드의 가상 머신에서 사용하는 기법)
알아두면 컨테이너 도입 명분, 사용 이유를 알 수 있다.
FreeBSD Jail의 특징
프로세스 구획화 : 똑같은 Jail에서 Process만 접근 가능, Jail안의 Process는 Jail밖의 Process에 영향을 줄 수 없다.
네트워크 구획화 : Jail은 하나 하나에 IP주소를 할당, Jail의 외부에는 네트워크를 경유해야 액세스 할 수 있음
파일 시스템 구획화 : 파일 시스템을 구획함으로써 조작할 수 있는 명령이나 파일등을 제한
Solaris Containers의 특징
Solaris 존 기능 : 하드웨어위에 Solaris를 올리고 그 위에 '비 글로벌 존'을 올린다.(Docker의 Conatiner 역할)
'비 글로벌 존'끼리는 서로 액세스할 수 없다.
Solaris 리소스 매니저 기능 : CPU, Memory같은 하드웨어 리소스를 업무 중요도에 따라 배분하는 기능
OS에 바로 올리는 경우
개발 ~ 스테이징까지 테스트하고 제품 환경에서 안되는 경우가 존재, 다른 환경의 미들 웨어, OS, 하드웨어가 모두 영향을 준다.
Container 사용
Container 기술을 사용하면 환경이 달라서 안되는 문제를 해결할 수 있다.
크게 3가지 기능 Build, Ship, Run
이 존재함
Docker는 애플리케이션의 실행에 필요한 프로그램 본체, 라이브러리, 미들웨어, OS, 네트워크 설정 등을 하나로 모아서 Docker Image로 만든다.
Docker Image를 Docker Registry에 공유,
Ubuntu, CentOS같은 기본 기능을 제공하는 베이스 이미지도 공유되어 제공
개인적인 정보는 Docker Image에서 제외하고 공유하는 것이 좋다.
Docker가 설치된 환경에서 Docker Image를 가지고 Conatiner를 가동
1개의 Image를 사용해 2개 이상의 Container를 가동할 수 있다.
다른 가상화 기술은 OS까지 새로 올리는 것이여서 실행속도가 느리나
Container는 1개의 Process여서 실행속도가 빠름
server OS : Ubuntu, CentOS, Debian...
public Cloud OS : AWS, Azura
client OS : MAC OS, WIndow
Docker는 몇개의 컴포넌트로 구성, 핵심 기능이 되는 Docker Engine을 중심으로 컴포넌트를 조합하여 애플리케이션 실행 환경을 구축
Docker Engine : 이미지를 생성하고 컨테이너 기동을 위한 핵심 기능, Docker 명령의 실행이나 Dockerfile에 의한 이미지도 생성
Docker Registry : Container의 바탕이 되는 Docker Image를 공개 및 공유하기 위한 Registry 기능
(Docker Hub : Docker 공식 Registry Service )
Docker Compose : 여러 개의 컨테이너 구성 정보를 코드로 정의, 명령을 실행함으로써 애플리케이션의 실행 환경을 구성하는 컨테이너들을 일원 관리하기 위한 툴
Docker Machine : Cloud 환경에서 Docker의 실행 환경을 명령으로 자동 생성하기 위한 툴
Docker는 Linux 커널 기술이 베이스이며 커널은 네트워크, 하드웨어와 같은 하위 레이어와 밀접한 부분이기 때문에 애플리케이션 개발자에게는 익숙하지 않은 영역
컨테이너를 구획하는 기술에 Linux namespace를 사용
Linux 커널의 namespace 기능은 Linux Object에 이름을 붙여 6개의 독립된 환경을 구축할 수 있다.
이름과 연결된 실체는 그 이름이 어떤 namespace에 속해 있는지 고유하게 정해짐, namespace가 다르면 동일한 이름이라도 다른 실체로 처리
PID namespace : PID란 Linux에서 각 프로세스에 할당된 고유한 ID를 말함. namespace가 다른 프로세스끼리는 서로 액세스할 수 없음
Network namespace : 디바이스, IP주소, 포트 번호, 라우팅 테이블같은 네트워크 리소스를 격리된 namespace마다 독립적으로 가질 수 있게 함
UID namespace : 사용자 ID, 그룹 ID를 namespace별로 독립적으로 가질 수 있음, namespace안의 UID/GID 0인 사용자를 root로 하고 HostOS에서는 일반 사용자로 할 수 있음 (namespace의 관리자 계정은 HostOS에 대하여는 관리 권한이 아예 없어서 보안적으로 뛰어남)
MOUNT namespace : Linux에서는 파일 시스템 사용을 위해 마운트가 필요(컴퓨터에 연결된 기기, 기억장치를 이용 가능한 상태로 만드는 것)
MOUNT namespace를 조작하면 namespace에 격리된 파일시스템 트리를 만든다.(다른 namespace나 Host에서 접근할 수 없음)
UTS namespace : namespace별로 호스트명, 도메인명을 독자적으로 가질 수 있다.
IPC namespace : 프로세스간 통신 오브젝트를 namespace별로 가질 수 있다.
물리머신의 자원을 여러 컨테이너가 공유하여 사용함
리눅스 커널 기능인 cgroups(control groups)기능을 사용하여 자원의 할당 등을 관리
Linux는 프로그램을 프로세스로서 실행, 프로세스는 하나 이상의 스레드 모음으로 움직이며 cgroups는 프로세스와 스레드를 그룹화하여 해당 그룹안의 프로세스, 스레드의 관리를 수행
계층 구조를 사용하여 프로세스를 그룹화하여 관리
부모 자식관계에서는 부모의 제한을 물려받음
Linux는 Docker를 설치하면 서버의 물리 NIC가 docker0이라는 가상 브리지 네트워크로 연결 ( docker0는 Docker 실행 후 자동으로 생성 )
도커 컨테이너가 실행되면 컨테이너에 172.17.0.0/16
라는 서브넷 마스크를 가진 프라이빗 IP주소가 eth0으로 자동 할당
NAPT(Network Address Port Translation) 기술로 컨테이너에 접근한다.
도커 컨테이너 시작 시 컨테이너 안에서 사용하는 포트를 가상 브리지(docker0)에 개방
docker run command의 option -p 80:80
가 가상 브리지에 개방하는 것
NAPT
하나의 IP 주소를 여러 컴퓨터가 공유하는 기술로 IP주소와 Port를 변환하는 기술, 하나의 글로벌 IP주소로 여러 대의 머신이 동시에 연결할 수 있다.
NAPT vs NAT
NAT : private ip가 라우터 밖으로 나갈 때 패킷의 source가 private ip에서 public ip로 변경시킨다.
NAPT : NAT 기반에서 Port도 함께 변환한다.
Translation 기술은 서비스 분야(게임, 웹...)마다 변형이 많다.
어떤 데이터를 복사할 필요가 생겼을 때는 새로운 빈 영역을 확보하고 거기에 복사한다.
하지만 복사한 데이터가 변경이 없다면 비효율적이다.
그래서 복사 요청에 바로 복사하지 않고 일단 참조만 하고 수정이 가해진 시점에 새로운 빈 영역을 확보해 복사한다.