Docker와 가상화 기술

문승준·2021년 12월 16일
0

Docker의 컨테이너 가상화 기술에 대해 알아보고,

Docker를 사용하는 이유와 장점에 대해 알아보자.

1. 가상화 기술이란? (Hypervisor vs Container)

  • 가상화 기술이란 물리적인 하드웨어 자원(CPU,Memory 등)을 논리적인(추상화) 리소스로 제공하기 위한 기술이다.

Hypervisor 가상화

  • Hypervisor는 물리적인 서버 에서 하나 혹은 그 이상의 독립적인 운영체제가 돌아가는 구조이다.

    즉, 물리적 서버의 OS 위에 여러 다른 독립적인 OS가 가상적(virtually)으로 돌아가는 구조이다.

    • 하나의 물리적 서버에서 실행되고 있지만 가상적으로서 완전한 독립적 OS로 운영 되는 것이다.

    • 장점

      • 물리적 서버의 리소스를 더 효율적으로 사용할 수 있다.

        하나의 서버에 여러 OS를 실행시키면 CPU를 idle 상태로 두지않고 필요한 OS나 서비스에 할당하여 리소스를 훨씬 효율적으로 사용할 수 있다.

        왜냐면, 한 서버에 하나의 OS만 운영을 하는 경우 해당 OS가 서버의 모든 리소스를 항상 full로 사용하기 어려우므로 서버 리소스들이(예를 들어 CPU) idle 상태로 낭비되는 경우가 있다.

    • 단점

      • 기술적으로 너무 무겁다(heavy-weight).

        독립적인 OS를 실행시키는 것이기 때문에 booting 시간이 길 수 밖에 없으며 리소스를 많이 차지할수 밖에 없다.

        base OS와 가상화 OS 사이에 커널 시스템 호출을 연결 시켜주는 emulation layer가 필요하다.

  • CPU의 idle (유휴)상태란?

    • 모든 프로그램(태스크)는 CPU에서 특정한 양의 처리 시간을 차지하는데, CPU가 모든 태스크를 끝내면 유휴 상태가 된다.

    • 현대의 프로세서들은 유휴 시간을 사용하여 전원을 절약한다.
      대표적으로 CPU 전압과 함께 클럭 속도를 낮추기, 프로세서의 일부를 슬립(sleep) 상태로 보내기

Container 가상화

  • 컨테이너 가상화 기술은 OS 커널 위의 유저 공간(user space)에서 실행된다.
    즉 완전히 독립적인 운영체제를 가상화 하는 것이 아니라 독립적인 user space를 가상화한다.

    • 하나의 호스트 서버에서 여러 독립적인 user space 인스턴스들을 가상적으로 실행할 수 있게 되는 것이다.

    • 장점

      • hypervisor 가상화 보다 훨씬 가볍기 때문에 빠르고 쉽게 독립적인 가상 환경을 실행시킬수 있다.
        docker는 hypervisor 처럼 emulator가 필요없이 그냥 일반적인 시스템 API interface를 사용한다.

      • docker image만 있으면 어디서든 쉽고 빠르게 test 환경, sandbox 환경 및 production 배포를 할 수 있다.

        MSA(Micro Service Architecture)와 CI/CD에 아주 잘 어울리는 가상화 기술이다.

    • 단점

      • 완전히 독립적인 운영체제 가상화가 아니다 보니 보안적인 측면에서 hypervisor 보다 약할수 밖에 없다.

      • 독립적인 OS가 아닌 user space 가상화를 하는 형태이다 보니 운영체제가 전혀 다른 호스트에서는 실행을 시킬수가 없다. 예를 들어 Windows 를 linux 호스트에서 실행시킬수 없다.


2. Docker란?

  • Docker는 가상화 컨테이너 기반의 오픈소스 플랫폼이다.

    • 가상화 컨테이너는 환경에 구애 받지 않고 애플리케이션을 실행할 수 있게 해준다.

    • 도커는 가상화 컨테이너 위에 애플리케이션 배포 엔진을 더함으로써 코드를 어디서든 빠르고 가볍게 실행시킬수 있는 기술을 제공한다.

  • 컨테이너 가상화는 새로운 기술이 아닌데, 도커가 핫한 이유는?

    • 도커는 요즘 널리 사용되는 MSA(Micro Service Architecture)와 CI/CD 구축을 위해 사용한다.

      실제로 docker는 한 컨테이너 당 하나의 application이나 프로세스를 실행하는 것을 권한다. MSA의 철학과 일맥상통 하는것이다.


3. Docker의 구조

  • Docker는 크게 4가지 부분으로 되어 있다.

    • Docker client 와 server (server는 docker engine으로 불리기도 한다)
    • Docker image
    • Docker registries
    • Docker containers
  • Docker client 와 server

    • Docker는 클라이언트 와 서버 구조로 이루어저 있다. 클라이언트가 서버에 명령을 전달하고 서버가 실행시키는 구조이다.
  • Docker image

    • Docker의 life cycle에서 docker 이미지는 “build”의 부분에 해당된다. Docker container에서 실행시키고 싶은 application을 docker 이미지로 빌드해서 실행시키게 된다.
  • Docker registries

    • Docker registires는 docker 이미지를 저장하는 repository라고 보면 된다.
      Source code를 github에 저장하여 관리하듯 docker 이미지는 dockerhub 같은 docker registries에 저장한다고 생각하면 된다. Github가 마찬가지로 public registry 가 있고 private registry가 있다.
  • Docker containers

    • Docker container에서 docker 이미지가 실행된다. 즉 docker 이미지를 실행시키는 가상화 공간 이다.
      Docker container는 하나 혹은 그 이상의 프로세스를 실행 시킬수 있다 (하지만 하나의 프로세스만 실행시키는 것을 권장).
  • Docker Compose And Swarm

    • Docker에서는 여러 docker container들로 이루어진 stack이나 cluster를 관리 하는 서비스도 제공하는데 바로 docker compose 와 docker swarm이다.

    • Docker compose는 복수의 docker container들을 모아서 종합적인 application stack을 정의 하고 운영할수 있도록 해주는 서비스이다.

      • Compose 파일을 사용하여 전체적인 application 서비스를 설정한후, application을 이루고 있는 각각의 컨테이너들 (예를 들어, web 서버 컨테이너, api 서버 컨테이너 등등)을 따로 실행시킬 필요 없이 한번에 생성하고 실행할 수 있도록 해준다.

      • Docker swarm은 docker containers 들로 이러우진 cluster를 관리할수 있도록 해주는 서비스이다. 즉 docker container를 위한 clustering tool 이다.


4. Docker의 특징들

  • Docker는 modern한 리눅스 커널이 설치되어 있는 x64 호스트에서는 다 실행 가능하다.

    • 하지만 커널 버젼 3.10 이상에서 실행되는 것이 overhead가 적기 때문에 권장된다.

    • 최근에는 docker를 Windows 나 Mac에서도 사용 가능하다. 하지만 Windows 및 Mac에서 docker를 직접 실행시키면 내부적으로 가상머신이 실행되어 그 안에서 docker가 실행되기 때문에 개발용 및 테스트 용으로는 괜찮지만 production 용도로는 적합하지 않다.

  • Docker 컨테이너는 독립된 root 파일 시스템이기도 하다 그러므로 파일 시스템 분리가 이루어져 있다.
    컨테이너는 호스트와 분리된 프로세스 환경을 가지고 있으므로 독립적인 프로세스를 실행할수 있다.
    네트워크 또한 분리 되어 있어서 독립적인 가상 네트워크 인터페이스 와 IP 주소를 가질 수 있다.

  • Resource isolation and grouping - 커널의 cgroups 기능을 통해서 docker container마다 독립적인 CPU와 메모리 를 할당할 수 있다.

    • Docker 파일 시스템은 copy-on-write 을 사용하여서 효율적이며 빠른 디스크 IO를 실행한다.
  • Docker 컨테이너에서 stdin, stdout, stderr을 통해서 생성되는 로그들은 전부 수집되어서 분석하거나 trouble-shooting을 가능하게 해준다.

    • 또한 실행되고 있는 docker container의 shell에 접속해서 interact할 수도 있다.
  • 표준 스트림(standard streams)이란?

    • 컴퓨터 프로그램과 그 환경(일반적으로 단말기) 사이에 미리 연결된 입출력 통로

    • 일반적으로 유닉스에서 동작하는 프로그램은 실행 시 세 개의 스트림이 자동으로 열린다.

  • Unix의 입력, 출력 및 오류 출력에 대한 표준 스트림

    • stdin : 입력 값을 프로그램에 나타내주는 stream (ex: 키보드 입력을 받기)

    • stdout : 모든 출력값들이 가는 곳 (ex: 프로세스 결과 값 출력하기)

    • stderr : 또 다른 출력 채널로 디버깅 정보를 출력하거나 에러 출력

5. Docker를 사용하는 이유

서버를 코드로 구성하고 관리하는 방법으로써 도커가 지닌 장점을 알아보자.

운영하면서 만들어지는 눈송이 서버들(Snowflake Servers)

  • 여러 서버를 운영하다보면 각 서버의 운영체제, 컴파일러, 설치 패키지가 완벽하게 같기는 쉽지 않다.

    • 오래 운영하다보면 그 작은 차이들이 큰 문제로 다가올 것이다.
  • 서버 간 차이로 인한 장애가 발생하면 장애 원인을 빨리 파악하기 어렵다.

    • 해당 서버를 잘 아는 사람을 찾을 것인가?
  • 동일한 도커파일로 빌드한 이미지로 10년 후 서버를 실행해도 지금 실행한 서버와 차이가 없다.
    • 도커를 활용하면 실행 시점에 상관없이 서버 구성 시점을 고정할 수 있다.

테스트 주도 개발의 관점

  • TDD

    • 테스트 작성 -> 테스트 실패 -> 코드 작성 및 수정 -> 테스트 성공 -> 리팩토링
  • Docker

    • 도커 파일 작성 -> 이미지 빌드 실패 -> 도커 파일 수정 -> 이미지 빌드 성공 -> 효율화
  • 서버를 만들 때 미리 실패하면 미래의 서비스 장애를 조금이라도 줄일 수 있다.

    • 컨테이너에서 명령어를 입력하며 원하는 결과를 찾으면 실패-수정 과정을 더 빨리 반복할 수 있다.

클래스와 인스턴스 관점

  • 도커 이미지는 동일해도, 서버에 설치하는 패키지가 업데이트되었다면 서버 환경은 달라질 수 있다.

    • 따라서 컨테이너 실행시 적용할 설정값을 지정해야한다.
  • 서버 실행 시점에 적용할 설정값을 기록할 수 있다.

    • 도커 파일 == 서버 운영 기록

    • 도커 이미지 == 도커 파일 + 실행 시점

    • 도커 컨테이너 == 도커 이미지 + 환경 변수

  • 도커 이미지를 컨테이너로 실행할 때

  • 소스코드는 수정이 불가능하고, 환경변수는 수정이 가능하다.

  • 소프트웨어는 클래스 구조를 통해 견고함과 유연성을 모두 얻을 수 있었다.

    • 숨길 부분은 private 변수로 관리

    • 드러낼 부분은 public 변수로 관리

    • 여러 인스턴스를 생성할 수 있다.

  • 도커 이미지의 구조도 견고함과 유연성을 모두 갖추고 있다.

    • 컨테이너로 실행시 수정 불가능한 소스코드

    • 컨테이너로 실행시 수정 가능한 환경 변수

    • 하나의 도커 이미지로 여러 컨테이너를 만들 수 있다.

서버 코드화의 장점

  1. 서버 제작 과정에 견고함과 유연성을 더할 뿐 아니라

  2. 다른 이가 만든 서버를 소프트웨어 사용하듯 가져다 쓸 수 있고

  3. 여러 대에 배포할 수 있는 확장성이 있다.


profile
개발자가 될 팔자

0개의 댓글