리눅스 컨테이너
: 운영체제 수준의 가상화 기술로 리눅스 커널을 공유하면서 프로세스를 격리된 환경에서 실행하는 기술
- 가상머신과의 차이
: 하드웨어가 아닌 커널을 공유하기 때문에 실행 속도가 빠르고 성능 상의 손실이 거의 없음
- 격리
: 컨테이너로 실행된 프로세스는 커널을 공유하지만 네임스페이스, 컨트롤 그룹, 루트 디렉터리 격리 등의 커널 기능을 활용해 격리되어 실행됨
: 호스트 머신에서는 프로세스로 인식되지만 컨테이너 관점에서는 독립적인 환경을 가진 가상머신 처럼 보임
※ 리눅스 커널
: 리눅스의 주요 구성 요소이자 컴퓨터 하드웨어와 프로세스를 잇는 핵심 인터페이스
※ 네임스페이스
: 내부 식별자에 사용될 수 있는 유효 범위를 제공하는 선언적 영역
: 개체를 구분할 수 있는 범위
=> 강아지라는 개념이 있을때 철수네 강아지, 영희네 강아지 처럼 강아지를 구별할 수 있도록 하는 '철수네/영희네' 라는 '소속'이 네임스페이스의 개념
=> /proc 디렉터리에서 1번 (systemd) 아래 네임스페이스를 의미하는 ns 디렉터리를 들어가면 'pid:[4026531836]' 과 같은 숫자가 있는데, 여기서 나오는 10자리 숫자가 바로 현재 프로세스의 PID 네임스페이스를 의미
※ 컨트롤 그룹 (cgroup)
: 프로세스들이 사용할 수 있는 컴퓨팅 자원들을 제한하고 격리시킬 수 있는 리눅스 커널의 기능
: 프로세스에 대해 메모리 / CPU / 네트워크 / 디바이스 / I/O를 제한할 수 있음
리눅스 컨테이너의 주요 특징
- 운영체제 수준의 가상화
: 별도의 하드웨어 가상화 없이 리눅스 커널을 공유해 컨테이너를 실행하며, 게스트OS 관리가 불필요
- 빠른 속도와 효율성
: 하드웨어 가상화가 없어 실행이 빠름
: 프로세스 격리를 위해 약간의 오버헤드가 있으나, 일반적인 프로세스 실행과 차이가 없는 수준
: 하나의 머신에서 프로세스 만큼 많이 실행하는 것도 가능
- 높은 이식성
: 모든 컨테이너는 호스트의 환경이 아닌 독자적인 실행 환경을 가짐
: 이 환경은 파일들로 구성되며, 이미지 형식으로 공유가 가능
: 리눅스 커널을 사용하고 같은 컨테이너 런타임을 사용할 경우 컨테이너의 실행 환경을 공유하고 손쉽게 재현할 수 있음
- 상태를 가지지 않음
: 컨테이너가 실행되는 환경은 독립적이기 때문에 다른 컨테이너에 영향을 주지 않음
: 도커와 같이 이미지 기반으로 컨테이너를 실행하는 경우 특정 실행 환경을 쉽게 재사용 할 수 있음
컨테이너의 종류
- 시스템 컨테이너 (LXC / LXD)
: 컨테이너 기술을 통해 운영체제 위에 하드웨어 가상화 없이 운영체제를 실행
: 일반적인 리눅스처럼 init 프로세스 등을 사용해서 다수의 프로세스가 같은 환경을 공유하는 것을 목표로함
- 애플리케이션 컨테이너 (Docker)
: 컨테이너 기술을 통해 하나의 애플리케이션을 실행하는 것을 목표로함
: 독립적인 환경을 가진다는 점에서 시스템 컨테이너와 동일하지만, 단 하나의 프로세스만 실행한다는 점에서 확장성을 가지며 관리 요소가 없음
컨테이너를 사용해야하는 이유
: 서로 다른 형상의 서버들이 존재하는 상황 (눈송이 서버)을 방지
: 서버 운영 기록을 서버 곳곳을 찾지 않고 도커 파일 하나로 확인 할 수 있음
- 도커 파일과 이미지, 컨테이너
: 도커 파일 (서버 운영 기록), 이미지 (운영 기록을 실행할 시점), 컨테이너 (실행 시점에 수정되어야 할 정보, 환경변수가 더한 것)의 개념
: 도커 파일로 이미지를 만들어두면 실행 시점에 상관 없이 서버의 형상을 일정하게 유지할 수 있음
도커 컨테이너의 원리
: 하드웨어 가상화 없이 리눅스 커널을 공유하여 프로세스를 실행하며, 호스트 시스템의 커널을 사용
: 커널이 다른 OS에서 같은 이미지로 컨테이너 생성 후 uname -a 실행 시 커널이 다름
: 컨테이너는 다른 프로세스들과 정확히 같은 계층에서 실행됨
도커 컨테이너의 파일 시스템 격리
: 이미지를 루트 파일 시스템으로 강제로 인식시켜 다른 파일 시스템을 사용
: chroot 명령 처럼 루트 디렉터리를 변경. 이 경우 루트 디렉터리로 지정한 위치의 상위로는 컨테이너(프로세스)가 인식할 수 없음
: 이러한 원리를 통해 컨테이너 끼리 격리된 파일 시스템을 가짐
: 루트 디렉터리를 바꾸기 위해서는 프로세스를 실행하기 위한 모든 파일들이 준비되어 있어야 하는데, 이를 도커 이미지로 부터 가져옴
도커 컨테이너의 프로세스 격리
: 리눅스 네임스페이스로 PID를 분리하여, 컨테이너 내에서 실행되는 프로세스가 PID 1번을 가짐
: unshare 명령 처럼 특정 프로세스를 실행할때 네임 스페이스를 분리하여 실행
: 이때 PID 네임스페이스를 분리하기 때문에 호스트와 다른 프로세스 공간을 가짐
- 컨테이너는 프로세스 인가?
: 컨테이너는 호스트 OS 입장에서 하나의 프로세스로 존재 (프로세스 자체임)
도커 컨테이너의 네트워크 격리
: 네트워크도 파일 시스템 및 프로세스와 마찬가지로 네임스페이스를 분리하여 도커 네트워크라는 분리된 네트워크를 가질 수 있음
: 네트워크 네임스페이스를 통해 네트워크 리소스 (네트워크 디바이스, IP, Port, 라우팅 테이블)을 네임스페이스 단위로 격리
: UTS 네임스페이스를 통해 네임스페이스 단위로 호스트명과 도메인명을 격리
: cgroup로 네트워크를 격리
Reference
'Container > Docker' 카테고리의 다른 글
도커 환경 변수 적용 방법 (0) | 2023.08.11 |
---|---|
도커 파일 (DockerFile) 완전히 파헤치기 (0) | 2023.07.25 |
failed to solve with frontend dockerfile.v0 failed to read dockerfile (0) | 2022.07.20 |
WSL 2.0 환경에서 Docker 설치 (0) | 2022.03.19 |
golang 으로 작성한 build 파일 wine으로 실행하기 (0) | 2021.12.23 |