a deep dive into container technology
학교 학생, 회사의 개발자 또는 소프트웨어 애호가에 관계없이 컨테이너에 대해 들었을 가능성이 있습니다 . 컨테이너가 경량 가상 머신이라고 들었을 수도 있지만, 실제로 컨테이너의 작동 방식과 그 중요성이 무엇을 의미합니까?
이 이야기는 컨테이너, 핵심 기술 아이디어 및 응용 프로그램을 살펴 봅니다. 컴퓨터 과학에 대한 기본적인 이해 외에이 분야에 대한 사전 지식은 없다고 생각합니다.
랩톱은 다른 모든 컴퓨터와 함께 CPU, 영구 저장 장치 (디스크 드라이브, SSD), 메모리, 네트워크 카드 등과 같은 일부 하드웨어 위에 구축됩니다.
이 하드웨어와 상호 작용하기 위해 커널 이라는 운영 체제의 소프트웨어 가 하드웨어와 시스템의 나머지 부분을 연결하는 역할을합니다. 커널은 프로세스 (프로그램) 실행 을 예약 하고 장치 (디스크 및 메모리에서 주소 읽기 및 쓰기) 등을 관리합니다.
나머지 운영 체제는 사용자 프로세스가 실행되는 사용자 공간을 부팅 및 관리하는 역할을하며 지속적으로 커널과 상호 작용합니다.
따라서 MacOS를 실행하는 컴퓨터와 Ubuntu에서 실행되도록 만들어진 응용 프로그램이 있습니다. 흠… 일반적인 해결책 중 하나는 Mac OS 컴퓨터에서 Ubuntu를 실행하는 가상 머신을 부팅 한 다음 프로그램을 실행하는 것입니다.
가상 머신은 게스트 운영 체제를 실행하는 하드웨어 및 커널 가상화의 어떤 수준으로 구성되어 있습니다. 하이퍼 바이저 라고하는 소프트웨어 는 가상 디스크, 가상 네트워크 인터페이스, 가상 CPU 등을 포함하는 가상화 된 하드웨어를 만듭니다. 가상 머신에는이 가상 하드웨어와 통신 할 수있는 게스트 커널도 포함되어 있습니다.
하이퍼 바이저를 호스팅 할 수 있습니다. 이는 예와 같이 호스트 OS (MacOS)에서 실행되는 일부 소프트웨어임을 의미합니다. 시스템 하드웨어에서 직접 실행되는 베어 메탈 일 수도 있습니다 (OS 교체). 어느 쪽이든, 하이퍼 바이저 접근 방식은 모든 하드웨어 및 커널이 아닌 경우 여러 부분을 가상화해야하므로 중량이 큰 것으로 간주됩니다.
동일한 시스템에 여러 개의 격리 된 그룹이 필요한 경우 이러한 각 그룹에 대해 VM을 실행하는 것은 너무 무겁고 낭비되는 리소스로 좋은 접근 방법이 될 수 있습니다.
VM은 머신 수준 격리를 위해 하드웨어 가상화가 필요하지만 컨테이너는 동일한 운영 체제 내에서 격리를 통해 작동합니다. 고립 된 공간의 수가 증가함에 따라 오버 헤드 차이가 실제로 분명해집니다. 일반 랩톱은 수십 개의 컨테이너를 실행할 수 있지만 하나의 VM 만 실행하는 데 어려움을 겪을 수 있습니다.
2006 년 Google 엔지니어는 cgroup으로 축약 된 Linux“제어 그룹”을 발명했습니다 . 이것은 사용자 프로세스의 리소스 사용량을 격리하고 제어하는 Linux 커널의 기능입니다.
이러한 프로세스는 네임 스페이스 (기본적으로 동일한 리소스 제한을 공유하는 프로세스 모음)에 넣을 수 있습니다 . 컴퓨터는 여러 개의 네임 스페이스를 가질 수 있으며 각 네임 스페이스는 커널에 의해 강제 된 리소스 속성을 갖습니다.
네임 스페이스 당 리소스 할당은 일련의 프로세스가 사용할 수있는 전체 CPU, RAM 등의 양을 제한하기 위해 관리 할 수 있습니다. 예를 들어, 백그라운드 로그 집계 응용 프로그램은 실제로 로깅하는 실제 서버를 압도하지 않으려면 리소스 제한이 필요할 수 있습니다.
원래의 기능은 아니지만 Linux의 cgroup은 결국 네임 스페이스 격리 라는 기능을 포함하도록 재 작업되었습니다 . 네임 스페이스 격리 자체에 대한 아이디어는 새로운 것이 아니며 Linux에는 이미 많은 종류의 네임 스페이스 격리가있었습니다. 한 가지 일반적인 예는 프로세스 격리입니다. 프로세스 격리는 각 개별 프로세스를 분리하고 공유 메모리와 같은 것을 방지합니다.
Cgroup 격리는 cgroup 네임 스페이스 내의 프로세스가 다른 네임 스페이스의 프로세스와 독립적이되도록하는 높은 수준의 격리입니다. 몇 가지 중요한 네임 스페이스 격리 기능이 아래에 설명되어 있으며 컨테이너에서 예상되는 격리의 토대를 마련합니다.
PID (Process Identifier) 네임 스페이스 : 한 네임 스페이스 내의 프로세스가 다른 네임 스페이스의 프로세스를 인식하지 못하도록합니다.
네트워크 네임 스페이스 : 네트워크 인터페이스 컨트롤러, iptables, 라우팅 테이블 및 기타 낮은 수준의 네트워킹 도구 격리
마운트 네임 스페이스 : 파일 시스템이 마운트되므로 네임 스페이스의 파일 시스템 범위는 마운트 된 디렉토리로만 제한됩니다.
사용자 네임 스페이스 : 네임 스페이스 내의 사용자를 해당 네임 스페이스로만 제한하고 네임 스페이스간에 사용자 ID 충돌을 방지합니다.
간단히 말해서, 각 네임 스페이스는 그 안에있는 프로세스에 대한 자체 머신 인 것처럼 보입니다.
리눅스 cgroups는 기술이라는 길을 열었습니다 리눅스 컨테이너 (LXC). LXC는 실제로 cgroup과 네임 스페이스 격리를 활용하여 별도의 프로세스와 네트워킹 공간이있는 가상 환경을 만드는 컨테이너로 인식 한 최초의 주요 구현이었습니다.
어떤 의미에서 이것은 독립적이고 고립 된 사용자 공간을 허용 합니다 . 컨테이너 개념은 LXC에서 직접 따릅니다. 사실, 이전 버전의 Docker는 LXC 위에 직접 구축되었습니다.
Docker는 가장 널리 사용되는 컨테이너 기술이며 실제로 컨테이너를 언급 할 때 대부분의 사람들이 의미하는 바입니다. Docker https://github.com/rkt/rkt 는 다른 오픈 소스 컨테이너 기술 (예 :CoreOS의 rkt https://github.com/rkt/rkt) 및 자체 컨테이너 엔진을 구축하는 대기업 (Google의 lmctfy https://github.com/google/lmctfy 등 )이 있지만 컨테이너화 의 업계 표준이 되었습니다. Linux 커널과 최근 Windows에서 제공하는 cgroup 및 네임 스페이스를 기반으로합니다.
Docker 컨테이너는 이미지 레이어로 구성 되며 바이너리는 단일 패키지로 함께 포장됩니다. 기본 이미지에는 컨테이너의 운영 체제가 포함되며 호스트의 OS와 다를 수 있습니다.
컨테이너의 OS는 이미지 형식입니다. 이것은 호스트에서와 같이 전체 운영 체제가 아니며 차이점은 이미지는 OS의 파일 시스템 및 이진일 뿐이며 전체 OS에는 파일 시스템, 이진 및 커널이 포함됩니다.
기본 이미지 위에는 각각 컨테이너의 일부를 구성하는 여러 이미지가 있습니다. 예를 들어 기본 이미지 위에는
apt-get 종속성 이 포함된 이미지가있을 수 있습니다.
그 위에 응용 프로그램 이진 등이 포함 된 이미지가있을 수 있습니다. 이미지 레이어와 두 개의 컨테이너가있는 경우 멋진 부분입니다 a, b, c 및 a, b, d 다음 각 이미지 레이어의 복사본을 저장해야, a, b, c, d 로컬 및 저장소에 있습니다. 이것은 Docker의 통합 파일 시스템 입니다.
해시로 식별되는 각 이미지는 컨테이너를 구성하는 여러 가능한 이미지 레이어 중 하나 일뿐입니다. 그러나 컨테이너는 상위 이미지에 대한 참조가있는 최상위 이미지로만 식별됩니다. 여기에 표시된 두 개의 최상위 이미지 (이미지 1 및 이미지 2)는 처음 세 레이어를 공유합니다. 이미지 2에는 2 개의 추가 구성 관련 레이어가 있지만 이미지 1과 동일한 상위 이미지를 공유합니다.
컨테이너가 부팅되면 이미지와 해당 상위 이미지가 리포지토리에서 다운로드되고 cgroup과 네임 스페이스가 생성되고 이미지가 가상 환경을 만드는 데 사용됩니다. 컨테이너 내에서 이미지에 지정된 파일과 바이너리는 전체 시스템에서 유일한 파일 인 것처럼 보입니다. 그런 다음 컨테이너의 기본 프로세스가 시작되고 컨테이너는 살아있는 것으로 간주됩니다.Docker에는 쓰기시 복사, 볼륨 (컨테이너 간 공유 파일 시스템), 도커 데몬 (시스템의 컨테이너 관리), 버전 제어 리포지토리 (컨테이너 용 Github 등) 등 정말 멋진 기능이 있습니다. 이것들에 대해 더 배우고 Docker를 사용하는 방법에 대한 실제 예를 보려면이 매체 기사 https://medium.freecodecamp.org/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b 가 매우 유용합니다.
1프로세스 격리 외에도 컨테이너에는 다른 많은 유리한 속성이 있습니다.
컨테이너는 컨테이너를 지원하는 어느 곳에서나 실행할 수있는 자체 격리 장치 역할을합니다. 그리고 각각의 경우 컨테이너 자체는 정확히 동일합니다. 호스트 OS가 CentOS, Ubuntu, MacOS 또는 Windows와 같은 UNIX가 아닌 경우 상관 없습니다. 컨테이너 내에서 OS는 컨테이너가 지정한 OS입니다. 따라서 랩톱에서 빌드 한 컨테이너가 회사 서버에서도 실행될 수 있습니다.
컨테이너는 또한 표준화 된 작업 단위 또는 컴퓨팅 역할을합니다. 일반적인 패러다임은 각 컨테이너가 단일 웹 서버, 데이터베이스의 단일 샤드 또는 단일 Spark 작업자 등을 실행하는 것입니다. 그런 다음 응용 프로그램을 확장하려면 컨테이너 수를 확장하면 됩니다.
이 패러다임에서 각 컨테이너에는 고정 된 리소스 구성 (CPU, RAM, 스레드 수 등)이 제공되며 응용 프로그램을 확장하려면 개별 리소스 프리미티브 대신 컨테이너 수만 확장해야합니다. 따라서 응용 프로그램을 확장 또는 축소해야 할 때 엔지니어가 훨씬 쉽게 추상화 할 수 있습니다.
컨테이너는 또한 마이크로 서비스 아키텍처 를 구현하기 위한 훌륭한 도구 역할을 합니다 . 여기서 각 마이크로 서비스는 단지 협력 컨테이너의 집합입니다. 예를 들어 Redis 마이크로 서비스는 단일 마스터 컨테이너와 여러 슬레이브 컨테이너로 구현할 수 있습니다.이 (마이크로) 서비스 지향 아키텍처에는 엔지니어링 팀이 응용 프로그램을 쉽게 만들고 배포 할 수있는 매우 중요한 속성이 있습니다 (자세한 내용은 이전 기사 https://hackernoon.com/how-microservices-saved-the-internet-30cd4b9c6230 참조).
Linux 컨테이너 시대 이후로 사용자는 각 프로세스가 자체 컨테이너에서 실행되는 많은 가상 머신에 대규모 애플리케이션을 배포하려고 시도했습니다. 이를 위해서는 잠재적으로 수백 개의 가상 머신에 수만에서 수천 개의 컨테이너를 효율적으로 배포하고 네트워킹, 파일 시스템, 리소스 등을 관리 할 수 있어야했습니다. Docker는 오늘날 컨테이너 네트워킹, 파일의 볼륨을 정의하기위한 추상화를 제공하므로 약간 더 쉽게 만들 수 있습니다. 시스템, 자원 구성 등
그러나 여전히 다음과 같은 도구가 필요합니다.
실제로 사양을 취하고 컨테이너를 기계에 할당합니다 (스케줄링).
실제로 Docker를 통해 컴퓨터에서 지정된 컨테이너를 부팅합니다.
업그레이드 / 롤백 / 지속적으로 변화하는 시스템 특성
컨테이너 충돌과 같은 실패에 대응
서비스 검색, VM 간 네트워킹, 클러스터 수신 / 탈출 등과 같은 클러스터 리소스를 생성합니다.
이 문제 는 일련의 (일시적으로 일시적이거나 끊임없이 변화하는) 컨테이너 위에 구축 된 분산 시스템 의 오케스트레이션 과 관련이 있으며 사람들은이 문제를 해결하기 위해 정말 기적적인 시스템을 구축했습니다.
다음 이야기에서는 주요 오픈 소스 오케 스트레이터 인 Kubernetes의 구현에 대해 중요하지만 덜 알려진 두 가지 Mesos와 Borg의 구현에 대해 자세히 이야기하겠습니다.
이 이야기는 시리즈의 일부입니다. UC 버클리의 학부생입니다. 저의 연구는 분산 시스템에 관한 것이며 Scott Shenker의 조언을받습니다.