728x90
Docker
@2024.04.30
Docker
💡
컨테이너 기술을 사용하여 애플리케이션에 필요한 환경을 구축하고 테스트 및 배포를
할 수 있게 해주는 플랫폼
할 수 있게 해주는 플랫폼
- Docker는 기존에 존재했던 컨테이너 기술을 사용하기 쉽게 만든 프로그램
- 현재는 MSA(Micro Service Architecture) 형태로 개발하는 것이 대세
MSA(Micro Service Architecture)
💡
서비스 간의 의존성을 없애고 기능을 쪼개는 것을 중심적으로 설계한 아키텍처로
소프트웨어를 작은 독립적인 서비스로 분해하여 개발하고 배포하는 스타일이다.
소프트웨어를 작은 독립적인 서비스로 분해하여 개발하고 배포하는 스타일이다.
- 장점 : 서비스 간 결합도를 줄이고, 응집도를 높인다.
- 서비스 단위의 개발 기능
- 지속적인 통합과 배포를 효율적으로 할 수 있다.
- 패치가 필요한 서비스만 배포
- Hotfix(정기 패치 이외의 급하게 수정이 필요한 패치)를 빠르게 처리 가능
- 전체가 아닌 필요한 서비스에만 이중화 가능
- 단점 : 각각의 서비스들을 관리하기 복잡하다.
- 이를 해결해 주기 위해 서비스 컨테이너 화가 이루어지게 된다.
- 이 과정에서 Docker와 Kubernetes가 도입 ⇒ 일관된 환경 제공 (환경 차이 최소화)
- 예시 : 은행 프로그램
- 입/출금 서비스, 조회 서비스, 대출 서비스 등 기능별로 작게 쪼개서 MSA 형태로 개발
- 만약 새로운 대출 유형이 생겨 개발이 필요하면, 은행 시스템 전체를 수정할 필요 없이 대출 서비의 수정만으로 작업을 경량화 가능
Container 기술

💡
Host OS 상에서 리소스를 논리적으로 구분하여 마치 별도의 서버인 것처럼 사용할 수 있는 기술로, 소프트웨어 애플리케이션을 실행하는 데 사용되는 독립적인 실행 환경
- 애플리케이션이 언제든 실행 가능하도록 필요한 모든 요소(실행환경, 소스코드, 구성요소, 종속성 등)를 하나의 런타임으로 패키징
- Guest OS가 없고, Host OS의 커널을 공유하여 오버헤드가 적고 가벼워 빠르다.
- 서버 구성, OS 설치, 네트워크, 개발 도구 구성 등의 작업에 시간을 낭지하지 않는다.
- 우리가 개발한 최소한의 Image를 통해 실행되므로 경량
- 주요 특징
- 가벼움
- 필요한 모든 것을 포함
- 애플리케이션을 실행하는데 필요한 최소한의 리소스만 소비
- 이식성
- 호스트 시스템에 독립적
- 동일한 컨테이너 이미지를 여러 환경에서 실행 가능
- 확장성
- 동일한 호스트 시스템에서 여러 개의 컨테이너를 실행하여 애플리케이션을 확장
- 표준화
- 동일한 실행 환경을 갖는 표준화된 형식으로 패키징 되므로, 개발, 테스트, 스테이징 및 프로덕션 환경 간에 이동이 쉽다.
- 가벼움
VM 가상화 기술

💡
Host OS와 달리 별도의 GuestOS를 두어 원하는 애플리케이션을 설치하는 하드웨어 수준의 가상화로, 애플리케이션 프로세스 및 종속 요소와 소스들을 패키지(이미지화) HostOS와 격리된 환경 제공
- Guset OS가 존재하기 때문에 오버헤드가 비교적 크다
- OS 위에 OS가 실행하는 것이므로, 리소스(CPU, 메모리 등)을 할당하는 작업이 필요
- 하이퍼 바이저(Hypervisor) = 가상 머신 관리자
- 컴퓨터 하드웨어와 가상 머신 사이의 중개자 역할을 하는 시스템 소프트웨어
- 물리적 호스트에서 개별적으로 작동하는 각 가상 머신이 사용할 하드웨어 리소스를 할당하고 활용하는 역할
- VMware, Virtualbox등이 존재
컨테이너 기술 | VM 가상화 기술 |
---|---|
Host OS 커널을 공유하는 운영체제 수준의 가상화 | GuestOS를 두고 원하는 애플리케이션을 설치하는 하드웨어 수준의 가상화 구현 |
경량(MB) Host OS의 커널을 공유하기에 더 적은 오버헤드로 실행되고, 애플리케이션과 필요한 종속성만을 포함 | 무거움(GB) 각각의 VM에는 운영 체제의 전체 복사본, 애플리케이션, 필요한 바이너리 및 라이브러리가 포함 |
부팅 없이 docker run 명령어로 바로 실행 가능 | 개별적으로 kernel이 존재하므로 이를 로딩하는 부팅 과정 필요 |
여러 개의 컨테이너가 동일한 컴퓨터에서 실행 가능하며, 각각 사용자 공간에서 격리된 프로세스로 실행되는 다른 컨테이너와 OS 커널을 공유 | Hypervisor를 사용하면 하나의 머신에서 여러 개의 VM을 실행 가능 |
Docker Architecture

Client
💡
사용자가 Docker 엔진과 상호 작용하기 위한 명령행 인터페이스
- 명령은 Docker API를 통해 도커 엔진과 통신
Docker daemon = Docker Engin
💡
Docker 엔진의 핵심 구성 요소로, 도커 호스트에서 컨테이너를 관리하고 실행하는 역할
- 클라이언트 - 서버 구조를 가지고 있으며, 클라이언트와 서버 간의 통신은 Docker API를 통해 이루어진다.
- 외부에서 이미지를 다운로드하고, 빌드 하는 작업을 수행
- 컨테이너를 생성, 시작, 중지, 삭제하는 등의 작업을 수행
- Image
- 컨테이너가 실행하는데 필요한 모든 것이 포함된 템플릿
- 파일시스템
- 실행에 필요한 모든 파일과 디렉터리
- 라이브러리 종속성
- 실행에 필요한 라이브러리, 실행파일, 런타임, 기타 종속성
- 환경 변수 및 설정 파일
- 실행 파일 및 스크립트
- 실행 파일은 컨테이너가 시작될 때 실행되어 애플리케이션을 조작하고 초기화
- 메타데이터
- 이미지의 버전, 작성자, 라이선스 정보 등이 포함
- 파일시스템
- 읽기 전용이며, 도커 컨테이너를 시작할 때 사용
- 여러 개의 계층으로 구성
- 각 계층은 이전 계층을 기반으로 쌓이며 파일 시스템의 변경사항을 저장
- 롤백 사용 가능
- ex) Window OS에서 CentOS 운영체제를 사용하기 위해 CentOS 이미지를 받아서 사용
- 컨테이너가 실행하는데 필요한 모든 것이 포함된 템플릿
- Conatainer
- Docker 이미지를 기반으로 실행된 가상 환경 = Docker 인스턴스
- 호스트 시스템의 리소스를 격리된 환경에서 사용하여 응용 프로그램을 실행
- 각 컨테이너는 자체 파일 시스템 및 프로세스 공간을 가진다 → 독립적 실행
Docker Registry
💡
Docker 이미지를 저장하고, 관리하는 중앙 저장소
- 공개적으로 사용 가능한 Docker Hub
- 내부에서 사용하기 위해 Private 레지스트리를 구축 가능
개발과 배포
- 미들웨어 : 애플리케이션 간의 통신과 데이터 교환을 용이하게 하고, 시스템 간의 통합을 지원
- 웹서버, 애플리케이션 서버, 웹서비스 등이 해당된다.
Lagacy 환경

💡
하나의 물리 서버에 애플리케이션을 배포하며, 그로 인해 애플리케이션 간 라이브러리나
미들웨어 간의 충돌 발생할 수 있다.
미들웨어 간의 충돌 발생할 수 있다.
- 개발자가 개인 PC에 애플리케이션을 개발하고 Repository에 배포
- Repository에서 애플리케이션을 받아 테스트 환경에서 테스트
- Repository에서 애플리케이션을 받아 스테이징 환경에서 서비스를 구동하기 위한 모든 애플리케이션 테스트
- 실 환경에 애플리케이션 배포
- 단점
- 애플리케이션은 모든 환경에서 같으나, 각 환경에 서버의 운영체제나 그 위에 올라가있는 미들웨어 프로그램이 동일하지 않는다.
- 의존성 문제나 제품 자체가 달라 문제 발생
- 개발자 개인 PC에는 애플리케이션이 정상 작동하나, 테스트 환경에서는 오류 발생
- 무겁고, 이식 확장에 불리하며, 관리가 복잡하다.
Docker 환경

💡
Docker를 이용해 서비스를 운영한다 = 애플리케이션들을 컨테이너 화 했다.
- 개발자가 개인 PC에서 Docker 이미지를 빌드해서 Repository에 배포
- 테스트, 스테이징, 프로덕션 환경에 Docker 프로그램만 설치하고 배포된 애플리케이션 이미지를 받아 테스트한다.
- 애플리케이션에 필요한 미들웨어도 컨테이너로 받아서 사용
- 스테이징 환경에서 테스트가 완료되면, 도커 이미지를 실 환경에 배포
- 장점
- 서버의 운영체제나 미들웨어의 의존성에 대해 걱정할 필요 없이 Docker만 설치되어 있으면 실행 가능
Docker 작동 원리
Namespace 기술
💡
리눅스 커널 기능 중 하나로, 각각의 컨테이너 프로세스가 시스템에 대해 독립할 수 있게 해주는 기술
- 컨테이너 별로 독립적인 환경을 가질 수 있는 이유는 namespace를 사용하기 때문
- Hypervisor(가상머신) → 충돌나지 않도록 Hardware Resource 자체를 가상화
- Namespace → Hardware Resource 자체를 가상화하는 것이 아닌, Linux 내의 자원을 가상화
- PID 네임 스페이스
- 각 컨테이너는 고유한 프로세스 ID를 가진다.
- 이는 해당 컨테이너가 호스트 시스템과 다른 컨테이너 프로세스와 격리되는 것
- 마운트 네임 스페이스
- 각 컨테이너는 자체 파일 시스템을 가진다.
- 이는 호스트 시스템과 다른 컨테이너의 파일 시스템과 격리되는 것
- 네트워크 네임 스페이스
- 각 컨테이너는 독립적인 네트워크 인터페이스를 가진다.
- 이는 호스트 시스템과 다른 컨테이너와의 네트워크와 격리되는 것
- 유저 네임 스페이스
- 각 컨테이너는 독립적인 사용자와 그룹 ID를 가진다.
- 이는 호스트 시스템과 다른 컨테이너의 사용자와의 격리되는 것
- PID 네임 스페이스
cgroups(Control Groups) 기술

💡
리눅스 커널 기능 중 하나로, 프로세스들이 사용할 수 있는 자원을 제한하고 격리 시킬수 있는 기술
- Namespace를 사용하여 격리된 환경을 만들지만, 컨테이너가 실행되는 Host OS의 물리적인
리소스는 공유하기에
cgroups을 사용하여 리소스를 제어- 컴퓨터의 자원이 각 프로세스 별로 독립적으로 격리되어 할당
- 제한 할 수 있는 자원 : CPU, Memory, Network, Device, I/O
- cgroups 기능
- 사용할 수 있는 자원의 양을 제한 가능
- 프로세스 간의 우선순위를 조정
- 각 프로세스 그룹의 자원 사용량을 모니터링하여, 사용량에 대한 경고나 알림 설정 가능
728x90