도커와 가상화 기술

가상화

  • hypervisor 가상화

물리적인 서버에서 하나이상의 독립적인 운영체제가 돌아가는 구조로 host os위에 여러 다른 독립적인 os가 가상적으로 돌아가는 것

물리적 서버의 리소스를 더 효율적으로 사용이 가능하다는 장점이 있음.

이런게 내가 하고 싶은 내 윈도우 pc에서 ubuntu os를 설치하는 것과 같은 구조

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


  • CPU의 idle상태 = 유휴상태 모든 task는 cpu에서 특정한 양의 처리시간을 차지하는데, 이 task를 끝내면 유휴상태가 된다. 가상화를 하지 않으면 기존 os만 운영하는 경우 서버의 모든 리소스를 항상 모두 사용하기 어렵기때문에 서버 리소스들이 idle상태로 낭비되는 경우가 있는데 가상화를 하면 cpu를 idle상태로 놔두지 않고 필요한 os 에 할당하여 리소스를 더 효율적으로 운영할 수 있게 된다.

  • container 가상화

컨테이너란?

컨테이너는 host os상에서 리소스를 논리적으로 구분(물리적으로 구분 x)하여 마치 별도의 서버인것 처럼 사용할 수 있게 해주는 기술.

이미지의 목적에 따라 생성되는 프로세스 단위의 격리 환경.

컨테이너 가상화는 os커널 위의 유저 공간에서 실행된다.

운영체제를 독립적으로 운영하는것이 아니라 독립적인 user space를 가상화하는 것

host OS위에 어플리케이션의 실행패키지인 이미지를 배포하는 것

도커는 하이퍼바이저와 guest os가 필요하지 않아 더 가벼움! → 기존 가상화보다 빠르고 쉽게 독립적인 가상환경 실행가능

하지만

완전히 독립적인 운영체제 가상화가 아니라서 하이퍼바이저 가상화보다 보안이 취약

또한 user space의 가상화를 하다보니 완전히 다른 운영체제를 가진 호스트에서는 실행을 시킬수가 없다.

컨테이너와 가상화의 가장 큰 차이점은 게스트 os의 유무이다.

컨테이너는 게스트 os를 설치하지 않아 가상머신보다 자원을 효율적으로 사용할 수 있다. → 가상머신은 하나씩 늘때마다 os를 위한 자원을 할당해줘야하지만 도커는 어플리케이션을 구동하는데 필요한 모든 패키지만 있으면 컨테이너를 구동시킬 수 있다.

⇒ 가상머신은 게스트os를 사용하기 위한 라이브러리, 커널등을 전부 포함하기 때문에 가상머신을 배포하기 위한 이미지로 만들었을때 크기가 큼

컨테이너는 필요한 커널을 호스트os의 커널을 공유하여 사용하소, 컨테이너 안에는 어플리케이션을 구동하는데 필요한 라이브러리 및 실행파일만 존재

가상화보다 이미지로 만들었을때 용량이 줄어듬 → 배포하는 시간이 빨라짐

그렇다면 가상화 컨테이너 기반의 오픈소스 플랫폼인 도커란 무엇일까?

DOCKER란?

도커는 가상화 컨테이너 위에 어플리케이션 배포 엔진을 더함 → 코드를 어디서든 빠르고 가볍게 실행시킬 수 있게 함.

서버환경을 컨테이너에 담아놓고 필요에 따라 꺼내 쓸 수 있는 환경을 제공합니다.

도커는 MSA 와 CI/CD 구축에 잘 어울림

도커의 등장으로 서버관리/개발방식이 편리하게 바뀜

그렇다면 도커를 사용하는 이유는 뭘까?

  1. 도커 허브에 올라온 이미지와 docker-compose.yml의 설정으로 원하는 프로그램을 편안하게 설치 가능

  2. 하나의 서버에 포트만 변경하여 동일한 프로그램을 실행하기 쉽다.

    도커를 사용하지 않으면 환경변수나 경로등의 충돌이 일어남.


    • 포트번호란?

    인터넷상의 통신에서 복수의 상대와 동시에 접속을 하기 위해서 네트워크 내에서 주소에 해당하 IP주소 아래에 설치된 서브 주소를 port라고 한다.

    쉽게 설명하여

    인터넷 상에서 컴퓨터 주소: IP

    컴퓨터의 입구: 포트

    웹 프로토콜인 HTTP와 같이, TCP/IP의 상위 프로토콜을 사용하는 응용프로그램에서는 미리 지정된 포트번호를 가지고 있다.

    포트는 0~65536번까지 있고 기본적으로 일반 사용자의 컴퓨터엔 포트가 몇개만 열려있고 해킹을 하면 해킹프로그램이 포트를 열어주는 것 그럼 열린 포트로 들어오는거다.


  • MSA와 CI/CD란? MSA : Micro Service Architecture 작은 기능별로 서비스를 잘게 쪼개어 개발하는 형태 → 서비스 단위의 개발가능하고, ci/cd를 효율적으로 할 수 있음. 하지만 서비스들을 관리하기 복잡한데 이런 문제를 도커를 이용해 쉽게 해결 가능 CI/CD : Continuous Integration 지속적인 통합이라는데 이게 뭐냐면 어플리케이션의 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어서 공유 레포지토리에 통합하는 것으로 다수의 개발자가 공유하며 사용하는 환경 예를 들면 git 같은 툴에서 사용 CD는 Continuous Delivery & Continuous Deployment는 지속적인 서비스 제공과 지속적인 배포라는 의미 Continuous Delivery는 공유 레포지토리로 자동 release(같은 제품을 새롭게 만드는것 즉새로운 버전의 배포)하는것 → 새로운 소스코드 빌드, 테스트, 병합 Continuous Deployment는 production level까지 자동으로 deploy (프로그램 등을 서버와 같은 기기에 설치하여 서비스 등을 제공하는 의미)하는 것을 의미 → 개발자의 변경 사항이 레포지토리를 넘어 고객의 production 환경(실제 서비스를 진행하는 환경)까지 release되는것을 의미

도커는 어떻게 동작하는가?

도커의 컨테이너는 호스트 os의 커널을 공유한다.


  • 커널이란? 커널이란 하드웨어 자원을 관리하고 하드웨어와 프로세스 사이의 인터페이스 역할을 수행하는 os의 핵심 구성 요소 중 하나이다. 커널의 주요 기능은 컴퓨터에 속한 자원들에 대한 접근을 중재하는 것 소프트웨어가 컴퓨터시스템에서 수행되기 위해서는 메모리에 그 프로그램이 올라가 있어야한다. 운영체제 역시도 소프트웨어로서 컴퓨터 전원이 켜지면 메모리에 올라갸야한다. 하지만 운영체제처럼 너무 큰 프로그램이 모두 메모리에 올라가면 한정된 메모리 공간의 낭비가 심할것이다. 따라서 운영체제 중 항상 필요한 부분만 메모리에 올려놓고 나머지는 필요할 때만 메모리에 올려 사용하게 된다. 이때 메모리에 상주하는 운영체제의 부분을 커널이고 하고 운영체제에서 가장 핵심적인 부분을 뜻한다.

호스트os와 하나의 커널을 공유하고 있기때문에 호스트 시스템에서도 컨테이너 내부의 프로세스를 볼 수 있다. (MySQL을 도커 컨테이너에서 시작해도 호스트의 쉘에서 프로세스를 검색하면 MySQL 프로세스를 찾을 수 있다)

그런데 어떻게 도커는 독립된 공간을 만들어 낼 수 있을까?

이는 리눅스 커널의 Cgroup(control groups)과 네임스페이스 기능을 이용해서 구현되어 있다. 이 기능을 이용해서 다른 프로세스 사이에 벽을 만든다.

먼저 리눅스에서 쓰이는 CGroup과 네임스페이스(namespaces)에 대해서 알아야 합니다. 이것들은 컨테이너와 호스트에서 실행되는 프로세스 사이에 벽을 만드는 리눅스 커널 기능들입니다.

  • C Group: CPU, 메모리, Network, HD I/O 등 프로세스 그룹의 시스템 리소스 사용량을 관리
    • 어떤 애플리케이션 사용량이 너무 많다면 그 어플리케이션 같은 것을 C Group에 집어 넣어서 CPU와 메모리 사용 제한 가능 (필요한 만큼만 할당해줌)
  • 네임스페이스: 하나의 시스템에서 프로세스를 격리시킬 수 있는 가상화 기술(별개의 독립된 공간을 사용하는 것처럼 격리된 환경을 제공하는 경량 프로세스 가상화 기술)

도커 엔진은 또다른 하나의 가상머신으로 게스트os를 가지고 있다. 도커의 게스트 os가 리눅스가 되고 이 위에 쌓이는 컨테이너들은 더이상 게스트 os가 깔리지 않게 되고 리눅스 커널의 기능으로 각 컨테이너들은 격리된다.

도커 그 자체로는 가상머신이기 때문에 하이퍼 바이저를 포함하고 있고 실제 PC와 가상 환경인 도커의 관계에서는 게스트os이고 도커와 컨테이너관계에서는 호스트os인 리눅스가 설치되어 있다.

그리고 도커 위 컨테이너에는 VM과 달리 OS가 설치되지 않는다.

초보를 위한 도커 안내서 - 도커란 무엇인가?

이미지 : 컨테이너를 실행하기 위해 필요한 빌드된 패키지

docker image build -t myapp:v1

태그 : 이미지에 할당된 라벨

컨테이너 : 이미지로부터 실행된 실행 주체

docker image push myapp:v1
docker container run -d -p 80:80 myapp:v1

컨테이너에 부하분산, 다운 타임을 최소화하기 위한 방법, 장애 발생 시 탐지나 컨테이너 복구는 어떻게해? → 오케스트레이터 : 컨테이너 그룹을 관리하는 서비스 ex) 쿠버네티스

단순하게 단일 컨테이너를 가동하는것이 아닌 여러 컨테이너를 가동하기 위해서는 단일 호스트가 아니라 여러 호스트로 이루어진 클러스터를 구성해야한다. 특정 호스트가 문제가 생겼을 경우 —> 컨테이너 복구 및 정상 호스트 중 얼마만큼의 컨테이너가 가동되야하는지 고려

  1. 컨테이너 배치 관리 : 클러스터 구성을 전제로 신규 컨테이너를 가동한 경우 각 컨테이너가 호스트에 균등하게 부하를 주도록 분산배치하는 것이 바람직하다.
  2. 컨테이너 부하 분산 : 처리량에 따라 요청 분산
  3. 컨테이너 상태 감시 및 자동 복구 : 컨테이너 상태 체크 → 정해둔 컨테이너 수 유지
  4. 컨테이너 배포 : 새로운 버전 업데이트 → 가동 중인 컨테이너 정지 후 새로운 컨테이너로 교체 이걸 오케스트레이터를 이용해 자동화
profile
혼자 이것저것 해보는걸 즐깁니다..!

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기
Powered by GraphCDN, the GraphQL CDN