Docker에 사용되는 컨테이너 개념과 Docker 기본 사용법

지니🧸·2024년 4월 2일
0

CS 저장소

목록 보기
43/48

모던 웹개발에서 Docker가 왜 필요해졌을까

Container란? 어떤 환경에서나 실행하기 위해 필요한 모든 요소를 포함하는 소프트웨어 패키지. 운영체제를 가상화해서 어느 환경에서나 애플리케이션을 실행할 수 있음!

Docker란? 애플리케이션을 개발, 배포 및 런하는 오픗 플랫폼. 컨테이너의 라이프사이클을 관리할 수 있는 플랫폼으로, 앱을 개발/테스트/배포하는 등 다양한 용도로 사용할 수 있다

Docker가 필요한 이유는?

Docker가 필요해진 이유는 컨테이너의 역사에서 찾아볼 수 있다.

  • 1960~70년대에는 한 컴퓨터가 하나의 애플리케이션 실행을 담당하는 것이 일반적이였다

그래서 프로세스도 오래 걸렸기 때문에 컴퓨팅 자원을 공유할 수 있게 해서 동시 실행이 가능하게 했더니, 여러 사용자가 자원을 같이 사용하면서 서로 간섭이 일어나는 경우가 생겼다. 하나의 프로그램이 사용 가능한 자원을 다 사용하거나 프로그램 에러가 OS까지 영향을 미치는 경우도 가능했다.

가상화(Virtualization)가 해결책

하이퍼바이저(Hypervisor) 가상화는 하나의 하드웨어에 어려 개의 독립적인 가상 운영체제 (가상머신)를 실행할 수 있게 해주는 기술이다. 하이퍼바이저 가상화로 하나의 물리적 컴퓨터에서 여러 운영체제를 동시 실행할 수 있고, 각 가상머신은 독립적인 컴퓨팅 환경을 제공받으며, 기본적인 하드웨어 자원(CPU, 메모리, 스토리지 등)은 물리적 호스트 시스템에 의해 가상화된 형태로 할당된다.

하이퍼바이저 가상화의 핵심은 하이퍼바이저라는 소프트웨어인데, 하이퍼바이저는 물리적 하드웨어와 가상 머신 사이에서 중재자 역할을 한다. 하드웨어 자원을 가상머신에 분배하고, 가상머신들이 이 자원을 안전하고 효율적으로 사용할 수 있도록 관리한다.

가상화를 통해 개발자는 다양한 운영체제 위에서 애플리케이션을 테스트하고, IT관리자는 서버를 효율적으로 활용하여 비용을 절감하고, 결과적으로 보안성이 높은 격리된 환경을 구성할 수 있다. 또한, 클라우드 컴퓨팅, 재해 복구, 시스템 마이그레이션과 같은 요구사항을 충족시키는데 핵심적인 역할을 수행한다.

하이퍼바이저란? 가상화 환경을 생성하고 관리하는 소프트웨어 핵심 구성 요소.

  1. 자원 (CPU, 메모리, 스토리지 등) 활당 및 관리하여 각 가상머신에 독립적인 운영체제 및 환경을 제공한다
  2. 가상 머신의 생성, 실행, 중지 및 삭제와 같은 생명주기를 관리한다
  3. 가상 머신 간 격리와 보안을 보장한다
  4. 가상 네트워크 인터페이스와 스위치를 통해 가상머신 간 네트워크 통신 및 외부 네트워크와 연결을 지원한다

새로운 가상화 방식으로 효율과 성능을 개선시킨 컨테이너(Container)

컨테이너 가상화는 애플리케이션을 실행하는데 필요한 코드, 런타임, 시스템 도구, 시스템 라이브러리 등을 포함하는 가벼운 격리된 환경을 생성하는 기술이다. 하드웨어 수준에서 운영체제와 환경을 격리하는 가상머신과 달리, 운영체제 수준에서 격리되며, 하나의 호스트 시스템과 같은 커널을 여러 컨테이너들이 공유하고, 동시 실행될 수 있어 자원을 효율적으로 사용한다.

컨테이너 가상화는 Cgroups네임스페이스(Namespace)를 활용하여 이루어진다.

Cgroups (Control Groups)란? 프로세스 그룹의 자원 사용량을 모니터링하고 제한하는 기능을 제공하여 각 컨테이너가 할당된 자원을 초과하여 사용하는 것을 방지한다. 이로써 시스템의 안정성을 유지하고 다른 컨테이너 또는 시스템 전체에 미치는 영향을 최소화한다.

네임스페이스(Namespace)란? 프로세스에게 제한된 시스템 뷰를 제공하여, 프로세스가 자신의 네임스페이스 내에서만 시스템 자원을 볼 수 있도록 한다. 이를 통해 파일 시스템 마운트, 네트워크, 호스트 이름 등을 각 컨테이너마다 독립적으로 할당하고 관리할 수 있다. 네임스페이스는 컨테이너의 격리를 보장하며, 컨테이너 내부에서 실행되는 프로세스가 호스트 시스템이나 다른 컨테이너의 리소스와 충돌하지 않도록 한다.

Docker 기본 개념과 구조

Docker 구조

Docker는 Client-Server architecture를 사용한다.

  • Docker daemon: Docker 컨테이너의 빌드, 런 및 배포 작업을 수행한다

Docker clientDocker daemondocker run, docker build, docker pull과 같은 명령을 내린다.

Docker client과 Docker daemon은 같은 시스템 상에서 동작하거나 client를 통해 원격 daemon에 연결할 수 있다.

Docker client와 Docker daemon은 REST API, UNIX 소켓, 네트워크 인터페이스 등을 통해 소통한다.

Docker daemon(dockerd)란? Docker Daemon은 Docker API 요청을 수신하고, 이미지/컨테이너/네트워크/볼륨과 같은 Docker object를 관리한다. 하나의 Daemon은 다른 Daemon들과 소통할 수 있다.

Docker client(docker)란? Docker를 사용하기 위해 활용하는 방식으로, docker run과 같은 명령어를 통해 Docker daemon을 조작할 수 있게 해준다.

Docker registry란? Docker 이미지 저장소로, docker pull, docker run과 같은 명령어를 실행하면 Docker가 이 곳에서 이미지를 pull해온다. docker push로 registry에 이미지를 올릴 수 있다. 사용자가 자신의 서버에 설치하여 프라이빗 저장소를 만들 수 있는 서버 측 응용 프로그램이라는 점에서 공식 클라우드 기반 저장소인 Docker Hub과 다르다.

Docker objects란? Docker image, container, network, volume, plugin을 통틀어 이르는 말이다.

  1. Docker Image: 도커 컨테이너를 생성하는데 사용하는 read-only 템플릿. 도커 이미지를 활용해 커스텀 도커 이미지를 흔히 만든다.
  2. Docker Container: 도커 이미지의 실행 인스턴스로, 격리된 환경에서 애플리케이션과 그 의존성을 캡슐화한다.
  3. DockerFile: 도커 이미지를 자동으로 빌드하기 위한 스크립트 파일로, 기본 이미지 설정, 명렁어, 파일, 환경 변수 설정 등 이미지 생성에 필요한 지시어를 담는다. docker build 명령어에 사용되어 새로운 도커 이미지를 생성한다. Dockerfile로 애플리케이션의 배포 과정을 표준화하고 자동화할 수 있다.

DockerEngine

도커 엔진(Docker Engine)은 컨테이너를 생성하고 관리하는 기능을 제공하는 클라이언트-서버 형태의 애플리케이션이다. (1) 도커 데몬, (2) REST API, (3) CLI 클라이언트로 구성된다.

(1) 도커 데몬: 컨테이너 관리를 위한 백그라운드 프로세스

  • 이미지 생성, 컨테이너 실행, 네트워크 설정 등의 작업을 수행한다.
  • 컨테이너의 생명주기를 관리한다.
  • 이미지를 빌드하고 저장소(registry)에서 이미지를 가져오는 역할을 수행한다.
  • REST API를 통해 도커 데몬에 접근할 수 있다.

(2) REST API: 도커 데몬과 통신하는 인터페이스

  • REST API를 통해 다양한 도커 클라이언트가 도커 데몬과 상호작용할 수 있다
  • REST API로 애플리케이션의 배포/관리/확장을 위한 명렁을 수행할 수 있다.

(3) CLI 클라이언트: 사용자가 커맨드 라인으로 도커엔진으로 상호작용할 수 있게하는 인터페이스

  • 사용자는 CLI 클라이언트를 통해 컨테이너를 생성하고 관리한다
  • 사용자는 CLI 클라이언트를 통해 이미지를 빌드하고 도커 허브 같은 이미지 저장소와 상호작용할 수 있다.

Docker의 동작방식

1. 이미지 다운로드 또는 빌드

컨테이너를 실행하기 전, 도커 엔진은 해당 애플리케이션을 실행하는데 필요한 모든 파일과 설정이 포함된 도커 이미지가 필요하다. 사용자는 도커 허브나 이미지 저장소에서 이미지를 다운로드하거나, Dockerfile을 정의하고 이를 통해 새로운 이미지를 빌드할 수 있다.

2. 컨테이너 생성

이미지가 준비되면, 사용자는 도커 데몬에게 컨테이너 생성을 요청한다.이 때 네트워크나 볼륨 마운트과 같은 추가적인 옵션을 설정한다. 도커 데몬은 이 정보를 바탕으로 새로운 컨테이너의 인스턴스를 생성한다.

3. 컨테이너 실행

컨테이너가 생성되면, 도커 데몬은 컨테이너 내부에서 정의된 애플리케이션을 실행한다. 이 과정에서 컨테이너는 독립적인 파일 시스템, 네트워크 인터페이스, 프로세스 ID 공간 등을 갖고, 호스트 시스템과 격리된 환경에서 실행된다.

4. 컨테이너 관리

도커 엔진은 실행 중인 컨테이너의 상태를 모니터링하고 관리한다. 사용자는 도커 CLI로 컨테이너를 조회하고, 컨테이너를 중지/재시작/삭제할 수 있다

5. 리소스 관리

도커 엔진은 Cgroups와 네임스페이스와 같은 리눅스 핵심 기능으로 컨테이너의 리소스 사용량을 제한하고, 컨테이너 간 격리를 유지한다.

핵심 질문

1. 한정된 개발기간에 기능 개발보다 배포에 시간을 투자한 이유는?

어떤 서비스든 실사용자의 소프트웨어 사용으로 사용성을 인정받고 피드백을 반영하는 것이 중요하다고 판단해 배포에 시간을 투자했습니다. 짧은 배포 주기로 사용자의 반응에 긴밀하게 대응하는 것을 우선시했습니다.
또한, 성능과 같이 로컬 호스트 환경에서 소프트웨어가 로컬 호스트 환경을 벗어나 배포되어야지만 확인할 수 있는 문제를 해결하고자 했습니다.
컨테이너화된 소프트웨어는 다양한 요구사항을 편리하게 반영할 수 있고, 개발환경이 다른 곳에서도 작업할 수 있기 때문에 장점으로 적용됐습니다.

2. 왜 배포가 편해야 할까?

서비스의 버그 또는 사용자의 피드백으로 인한 수정 사항을 빠르게 해결하고 해결된 버전을 배포하는 과정을 효율적으로 수행하기 위해서는, 수정되자마자 사용자에게 수정된 서비스가 전달되어야 합니다.
이 과정에 있어서 배포가 번거로운 건 곧 프로덕트 릴리즈의 딜레이로 직결됩니다.

3. 여러 배포 방법 중 컨테이너(Docker)를 사용한 이유는?

컨테이너는 런타임 환경을 일관적으로 유지하며, 설정에 따라 개발/테스트/프로덕션 모드를 손쉽게 선택하고 실행할 수 있다. 환경 자체를 애플리케이션과 함께 컨테이너 이미지에 탑재하기 때문에 의존성 누락 등 환경적 요인으로 서비스나 애플리케이션이 다르게 작동할 위험을 크게 줄인다. 이렇듯 컨테이너는 Portability가 높아 개발자가 로컬 환경에서 온전성 테스트를 수행하기 용이하고, 버그를 발견했을 때 프로덕션과 동일한 버전의 코드를 간단히 배포할 수 있어 문제를 재현하기도 쉽다.


참고:

profile
우당탕탕

0개의 댓글