본문 바로가기
Docker

[Docker] Docker의 기본 개념

by 도전하는 린치핀 2024. 1. 23.

Docker 사용 이유 : Consistency(일관성)와 Multiple Containers(다중 컨테이너)

어플리케이션 동작의 일관성을 갖기위해 (어느 서버나 컴퓨터에서 동작해도 정상적으로 동일한 동작으로 하기 위해)

  • 어플리케이션 버전
  • 설정 명령어 존재 여부
  • 환경변수
  • 설정파일 누락 여부
  • 실행 환경

하나의 서버임에도 다중 컨테이너를 동작시키면 다양한 어플리케이션들을 조합하여 원하는 서버를  구동 가능하다.

Docker 개념

도커(Docker) 컨테이너 기반 가상화 플랫폼으로, 응용 프로그램과 그 종속성을 격리된 환경인 컨테이너로 패키징하여 실행하는 기술이다. 이를 통해 응용 프로그램을 서로 다른 환경에서도 일관되게 실행할 수 있고, 개발 환경과 운영 환경 사이의 차이로 인한 문제를 줄일 수 있다. 도커 컨테이너는 가볍고 빠르며 확장성이 좋아서 개발 및 배포 프로세스를 간소화하는 데 사용된다.

즉 하나의 OS 위에 다양한 어플리케이션이 구동 가능하게 하는 것으로 이때 각 어플리케이션의 단위를 컨테이너라고 한다.

  • 컨테이너 : 격리된 공간에서 프로세스가 동작하는 기술
    • Application마다 사용하는 버전과 DB와 같은것들이 다르다. 각각의 환경이 컨테이너라고 할 수 있다.
      • 단일 어플리케이션 컨테이너 관리 : Dockerfile을 통한 단일 컨테이너 구성 및 구동
      • 다중 어플리케이션 컨테이너 관리 : Docker Compose를 통한 다수의 컨테이너 구성 및 구동

 

Isolation을 위한 기술 : VM vs Container

  • VM(Virtual Machine) : OS 레벨 독립적 어플리케이션 구동 환경
    • 무겁고 느리다.
    • 리소스를 많이 사용한다.
  • Container : 경량화 독립적 어플리케이션 구동 환경
    • 가볍고 빠르다.
    • 리소스를 적게 사용한다.

출처 : https://wnsgml972.github.io/setting/2020/07/20/docker/

 

  • Docker는 Linux Container 구동을 위해 Image를 만들고 Container를 구동하는 책임을 갖는다.
  • 그렇다면 왜 Docker는 항상 Linux 명령어만 사용해야 할까?
    • 컨테이너 : 격리된 공간에서 프로세스가 동작하는 기술(Isolated Porcess in Userspace)
    • 컨테이너를 구동하는 Docker는 Linux의 LXC, cgroup, kernel namespaces 기반(Docker의 Container는 Linux Container 기반인 셈)

 

  • VM에서 Guest OS 구동을 위한 Hypervisor는 2개 타입으로 나뉜다.(출처)
    1. Baremetal (Microkernalized) : 호스트 머신(하드웨어) 위 바로 구동
      • 호스트 머신 위 동작이기에 적은 오버헤드(ex. Microsoft Hyper-V, WSL)
    2. Hosted (Monolithic) : 호스트 OS 위 소프트웨어 레이어 혹은 애플리케이션으로써 구동
      • 게스트 OS가 추상화 방식으로 동작되기에 설치 및 구성이 편리하다(ex. Oracle VirutalBox)

 

  • Window 내 Docker 설치할 때 오류나는 이유는 무엇일까?
    • Hyper-V 필요 : Docker Engine을 위해서는 Linux가 필요하다.
    • 즉 호스트 OS가 Microsoft Window라면 어쩔수 없이 Guest OS가 Linux여야 한다.
    • 이를 위해 Window 내 Linux 구동을 위해 Hyper-V가 필요하다.
    • 또는 Window 내 Linux 구동을 위해 WSL2를 사용 가능하다

Docker 이미지와 컨테이너 차이

Docker의 이미지와 컨테이너 차이 = 프로그램과 프로세스의 차이

  • 프로그램프로세스
    • 프로그램(정적) : 바이너리 파일
    • 프로세스 = 실행중인 프로그램(동적) : 프로그램이 메모리에 올라가 CPU가 할당되어 동작
  • 이미지컨테이너
    • 이미지(정적) : 앱 동작을 위해 필요한 바이너리, 라이브러리 파일(Libs, Bins) 그리고 앱(App)
    • 컨테이너 = 실행중인 이미지(동적) : 메모리와 CPU 위에 이미지(파일 시스템) 구동한 것

 

Docker Workflow

  1. Build : Docker Image 생성 ← Dockerfile = Instruction
    • Build를 위해선 Instruction 필요
    • instruction 내용 그대로
    • Image는 Layer로 구성되어 있어 중간 과정을 Cache 해놓는다. 
  2. Push : Docker Image 업로드 → Registry
  3. Pull : Docker Image 다운로드 ← Registry
  4. Run : Docker Image 실행 = Container

 

Dockerfile 최적화

Docker Image 생성 주체(서버)Docker Run 실행 주체(서버)와 구분한다.

  • Local에서 Image 생성하지 않고, Remote에서 Image 생성한다.
  • Remote는 무엇이 되어야 할까?
    • Jenkins, Githun Action
    • 서비스를 수행할 EC2? 별개의 빌드용 EC2?
    • 서비스를 수행할 EC2에서 빌드까지 한다면 어떤 문제가 있을까?
      • Network Overhead
      • node_module과 같이 중간 산출물(라이브러리 등)가 너무 커서 불필요한 메모리 사용

Docker에서 숙지해야할 용어

  • Host = (Worker) Node = Instance = 내 컴퓨터 or 서버
    • = Host 는 다수의 Container를 갖는다.
    • = Node 는 다수의 Container를 갖는다.
    • = Instance는 다수의 Container를 갖는다.
    • = 서버 는 다수의 Container를 갖는다.

Dockerfile 및 Docker Engine(Daemon) 명령어

 

Docker Compose

  • Dockerfile로 정의한 개별 Container들을 한번에 띄워 Multiple Container들을 하나의 완벽한 Apllication으로 서비스하게 하는것
  • Docker Compose는 최종적으로 어떻게 연결되어야 한다는 상태만을 명시하는 선언형이다.
    • 선언형(Kubernetes, Ansible, Terraform) - 명령어(Docker)구별
    • 선언형 Declarative : 무엇이 되어야하는가 (상태성)
    • 명령형 Imperative : 어떻게 되어야 하는가 (절차성)

 

Kubernetes

  1. Application = 컨테이너s (on 1 host, 기본 Docker Compose) = Application
    • Docker(하나의 컨테이너 필요시) 혹은 Docker Compose(멀티 컨테이너가 필요시)로 관리
      • YAML 하나의 호스트 머신에서 Containers를 관리한다.
  2. Orchestration = 컨테이너s on X Hosts = MSA = Orchestration
    • Docker Swarm / Kubernetes로 관리
      • 다수의 컨테이너를 관리할 뿐 아니라 다수의 호스트도 관리해야 하니 매우 어렵다.
      • YAML → 다수의 호스트 머신에서 Containers를 관리한다.

  3. Cluster = 하나의 시스템으로 함께 작동하는 여러개의 노드(서버 or 인스턴스) 집합
    • 가용성, 복원력, 성능을 극대화
    • 다수의 컨테이너 → 다수의 인스턴스에 지능적 배치 필요 = 오케스트레이션
    • 꼭 한 노드에 하나의 Application이 위치할 필요가 없다.
      • 다수 노드에 퍼져있는 Containers(Kubernetes에선 Pods 단위)의 집합으로 Application 서빙