Docker | Docker 개념 정리
Docker
오픈 소스 컨테이너화 플랫폼
개발자는 애플리케이션을 컨테이너로 패키징 가능
컨테이너
▪ 애플리케이션 소스 코드를 임의의 환경에서 해당 코드의 실행에 필요한 운영체제(OS) 라이브러리 및 종속 항목과 결합하는 실행 가능한 표준 컴포넌트
▪ Linux 커널에 빌드된 가상화 기능과 프로세스 격리를 통해 가능하게 됨
▪ 프로세스 간의 리소스 할당을 위한 제어 그룹(Cgroups) 및 시스템의 기타 리소스나 영역에 대한 가시성이나 프로세스 액세스를 제한하기 위한 네임스페이스 등의 기능을 사용하면 다수의 애플리케이션 컴포넌트가 호스트 운영체제의 단일 인스턴스의 리소스를 공유가능
▪ 하이퍼바이저를 통해 다수의 가상 머신(VM)이 단일 하드웨어 서버의 CPU, 메모리 및 기타 리소스를 공유하는 것과 거의 유사한 방식
도커 동작 방법
✅ 도커 구조
일반 서버 : 물리서버 ➡ 리눅스 운영체제(OS) ➡ 프로그램 데이터가 직접 올라감
도커 서버 : 물리서버 ➡ 리눅스 운영체제(OS) ➡ 도커엔진 ➡ 컨테이너 (프로그램, 데이터 컨테이너 내부에 위치)
❓ 도커에서는 컨테이너가 완전히 분리되어 있으므로 밑바탕이 되는 리눅스 운영체제의 주변부분이 컨테이너 속 프로그램 명령을 전달받을 수 없음
➡컨테이너 속 운영체제 주변 부분이 들어있어 프로그램 명령을 전달받고 이를 커널에 전달하는 구조
✅ 도커 동작방식 ➡ 레이어
도커는 이미지를 통째로 생성하지 않고 , 바뀐 부분만 생성한 뒤 부모 이미지를 계속 참조하는 방식으로 동작
이미지는 여러개의 읽기전용(read only) 레이어로 구성되고, 파일이 추가 되거나 수정되면 새로운 레이어가 생성
이미지는 Url방식으로 관리하며 태그를 붙일 수 있다.
✅ 도커 아키텍처
클라이언트-서버 아키텍처 기반
Docker의 client는 사용자의 입력을 받아서 Docker daemon과 통신
Docker client와 Docker daemon은 같은 시스템에서 실행되거나 UNIX 소켓, REST API 등으로 원격으로 통신도 가능합니다.
🐳 Docker Client
▪ 사용자와 상호작용 하는 곳.
▪ 명령어를 입력하면 Docker Daemon에게 Docker API를 통해 전달
▪ 한개의 Client는 두 개 이상의 Daemon과 통신이 가능
🐳 Docker Daemon
▪ Docker Client 측에서 보낸 명령어를 Docker API를 통해 전달받고 Docker의 이미지, 컨테이너, 네트워크, 볼륨 등 Docker 객체를 관리
🐳 Docker Registry
▪ Docker Registry는 Docker 이미지를 저장하는 공간입니다. 개인 레지스트리를 구성할 수 도 있으며, 공용 레지스트리인 Docker Hub도 존재합니다.
Docker 객체
🐳 이미지
▪ 이미지는 본인이 직접 만들거나, 다른 사람들이 레지스트리에 올려놓은 이미지가 있으며 직접 만들 때는 Dockerfile을 사용
▪ 이미지는 계층, 레이어로 이루어져 최종적으로 단일 이미지로 결합 ➡Docker이미지를 사용 시 CI/CD가 빨라짐
▪ 계층으로 이루어져 있기 때문에 Dockerfile을 변경하여 빌드하면, 변경되지 않은 부분의 레이어는 그대로 있고, 변경된 부분의 레이어만 새로 빌드해 적용
▪ 레이어는 이미지를 빌드할 때뿐만 아니라, 저장소에서 이미지를 주고받을 때도 기존의 이미지와 차이점이 없는 부분은 그대로 두고, 추후 변경사항만 주고받게 되기에 Docker 이미지가 가볍고 빠르게 사용됨
🐳 컨테이너
▪ 컨테이너는 Docker이미지를 실행하는 객체, 혹은 이미지를 실행한 상태
▪ 애플리케이션을 배포하고 테스트하는 단위입니다
▪ 다른 컨테이너와 잘 분리되어있으며 이미지와 컨테이너 설정으로 구성되어 있습니다. 컨테이너는 실행하는데 필요한 모든 구성요소를 담고 있어서 호스트 OS에 의존할 필요가 없다.
▪ 호스트 OS와도 분리가 잘 되어있으며 컨테이너는 쉽게 공유되며 이로 인해 모든 사람들이 동일한 개발 환경을 가질 수 있다.
Docker의 전체적인 실행 흐름
사용자가 실행하는 명령을 입력 ➡ client가 daemon에게 전달 ➡daemon이 images에 해당 이미지가 있는지 확인하여 있으면 실행하고, 없으면 registry에서 이미지를 가져와 실행
컨테이너 vs vm
✅ 기존 가상화 (VM)
가상화 이전의 시대에서는 하나의 서버에 하나의 어플리케이션만 구동
➡ 하나의 서버에 남는 자원이 많아짐
➡ 가상화 기술의 등장 ( 주로 하이퍼바이저 기반 가상화가 많이 이용됨)
✅ 하이퍼바이저
논리적으로 분할된 공간에서 VM 이라는 독립된 가상환경을 만들고,
host 시스템에서 VM에 깔린 게스트OS를 구동 및 모니터링하는 역할
논리적으로 구분된 공간에서 독립된 가상의 하드웨어를 할당 받은 VM들은 서로에게 어떤 영향도 미치지 않는다
즉, 1개의 가상환경에서의 Error 가 다른 가상환경에 영향을 미치지 않는다. 이러한 장점으로 가상화 사용
컨테이너 vs vm 차이 => 게스트 OS의 유무
▪ VM은 Guest OS가 깔리지만 도커는 그렇지 않음 -> 자원의 효율성 측면에서 차이
▪ VM는 하나씩 늘 때마다 OS를 위한 자원을 할당해주어야 하는 반면에 도커는 어플리케이션을 구동하는데 필요한 모든 패키지만 있으면 컨테이너를 구동시킬 수 있다.
✅ 도커 동작 방식 -> 도커의 컨테이너는 호스트 OS의 커널을 공유
✅ 커널
- 하드웨어 자원을 관리하고 하드웨어와 프로세스 사이의 인터페이스 역할을 수행하는 OS의 핵심 구성 요소중 하나
- 커널은 컴퓨팅 자원을 가상화하고 이를 프로세스에 할당함
결과적으로 하나의 커널을 공유하고 있기 때문에 호스트 시스템에서도 컨테이너 내부의 프로세스를 볼 수 있다. 즉, 내가 만약 MySQL을 도커 컨테이너로 시작한다면 도커가 아닌 호스트의 일반 셸에서 프로세스를 검색해 본다면 (ps-e |grep MySQL) MySQL 프로세스를 발견할 수 있다.
❓ 호스트 프로세스에서 컨테이너 프로세스를 볼 수 있다면 이것은 독립된 공간이라고 할 수 있을까?❓ 도커는 어떻게 독립된 공간을 만들어낼까?
➡ 리눅스 커널의 Cgroup(control groups) 과 네임스페이스 기능을 이용해서 다른 프로세스 사이에 벽을 만듦
Docker Engine 은 또다른 하나의 VM 이다. VM은 Guest OS를 갖고 있다.Docker의 Guest OS가 바로 리눅스가 되고 이 위에 쌓이는 컨테이너에는 더이상 Guest OS가 깔리지 않으며 리눅스 커널의 기능으로 각 컨테이너들은 격리가 된다.
Docker 는 그 자체로는 VM 이기 때문에 하이퍼바이저를 포함하고 있고실제 환경(PC)과 가상 환경(도커)의 관계에서는 Guest OS 이고 도커와 컨테이너의 관계에서는 Host OS 인 리눅스가 설치되어 있다.
https://velog.io/@rlaclgns321/Docker
https://velog.io/@kdaeyeop/%EB%8F%84%EC%BB%A4-Docker-%EC%99%80-VM%EC%9D%98-%EC%B0%A8%EC%9D%B4
https://velog.io/@kdaeyeop/%EB%8F%84%EC%BB%A4-Docker-%EC%99%80-VM%EC%9D%98-%EC%B0%A8%EC%9D%B4