컨테이너와 오케스트레이션 이야기

제이슨·2023년 11월 14일
2
post-thumbnail

도커와 쿠버네티스를 학습하며, 공부한 내용을 스스로 정리하기 위해 포스트를 쓰게 되었습니다 😀

혹시, 제가 지식을 잘못 전달한 부분이 있다면 편하게 댓글 달아주세요!
너무 감사할 것 같고, 바로 수정하겠습니다!

컨테이너

컨테이너란?

컨테이너는 실행에 필요한 모든 파일을 포함한 전체 런타임(실행) 환경에서 애플리케이션을 패키징·격리할 수 있는 기술입니다.
container

컨테이너를 사용하는 이유?

컨테이너를 왜 써야 할까요? 컨테이너를 사용하면 아래와 같은 이점을 얻을 수 있습니다 😀

  1. 개발 팀은 개발에, 데브옵스 팀은 인프라에 집중할 수 있다.
  2. 동일한 OS 커널을 공유하기 때문에 애플리케이션 실행에 필요한 컴퓨팅 자원 경량화를 달성할 수 있다.
  3. 컨테이너가 모든 종속 항목을 함께 전달하기 때문에 한번 만든 컨테이너 이미지는 어느 컴퓨팅 환경에서든(온프레미스, 클라우드 등) 재구성 필요 없이 실행 가능하다.
  4. 컨테이너는 각각 독립적으로 실행되기 때문에 하나의 컨테이너 문제가 다른 컨테이너에 영향을 미치지 않는다. 즉, 자원 격리를 통해 안정성을 얻을 수 있다.

등등..

컨테이너 가상화

그렇다면, 컨테이너를 만들 수 있을까요? 컨테이너 가상화 기술을 사용하면 됩니다!

제가 알고 있는 컨테이너 가상화 기술은 Docker와 LXC(Linux Container)가 있는데요!
lxc_docker

LXC와 도커는 컨테이너를 만들어주는 컨테이너 가상화 기술이라는 공통점을 가지고 있지만, LXC는 OS 레벨 가상화 기술이고 Docker는 애플리케이션 레벨 가상화 기술입니다.

OS 레벨 가상화 기술은 단일 리눅스 컴퓨터(LXC host)가 여러 개의 리눅스 OS를 컨테이너로 동시에 생성·실행할 수 있게 만드는 기술입니다.
→ 런타임 환경의 리눅스 OS 컨테이너에서 여러 개의 애플리케이션을 실행할 수도 있다는 뜻!

반면에, 애플리케이션 레벨 가상화 기술은 격리 환경에서 단일 애플리케이션 실행하기 위한 목적으로 컨테이너를 생성, 실행하는 가상화 기술입니다.

즉, LXC는 OS 컨테이너화를 목적으로 하는 기술이고 도커는 애플리케이션 컨테이너화를 목적으로 하는 기술이라 할 수 있습니다 😁

LXC vs Docker출처: LXC vs Docker: Which Container Platform Is Right for You ?

도커🐳 엔진에 대하여,,,

도커 엔진은 우리가 부르는 도커 그 자체입니다! 왜냐하면, 애플리케이션을 빌드하고 컨테이너화하는 기술이기 때문이죠!

즉, 도커 데스크탑이나 CLI 명령어를 받아서 컨테이너를 생명주기와 관련된 작업을 하는 것이 바로 도커 엔진인 것입니다!

aha

그렇다면, 도커 엔진은 어떤 방식으로 작업을 수행하게 될까요?

도커 엔진의 내부 동작 순서는 아래와 같습니다!

docker-engine-process출처:쿠버네티스 어나더 클래스 (지상편) - Sprint1

dockerd (docker ‘d’aemon)

  • 도커 엔진의 핵심 데몬으로, 컨테이너 생성, 관리, 네트워킹, 이미지 빌드, 저장소 관리 등을 담당
  • 사용자 명령을 받아들여 컨테이너를 시작, 중지하고 이미지를 가져오며 빌드하여 실행
  • dockerd는 컨테이너를 시작하고 관리하는 작업을 containerd에 위임

containerd

  • 컨테이너 런타임으로써, runc를 통해 컨테이너 실행을 담당
  • containerd는 컨테이너의 생명주기를 관리하고 컨테이너 관리, 스냅샷, 이미지 저장, 네트워킹 등의 기능을 담당

runc

  • OCI Runtime 스펙에 따라 컨테이너를 실행하는 도구
    → OCI Runtime 스펙: Open Container Initiative 런타임 스펙으로써, 컨테이너 가상화 기술(도커라든지, 도커라든지…) 의존적인 쿠버네티스의 문제점을 극복하고자 어떤 컨테이너 이미지도 쿠버네티스에서 실행할 수 있게 만든 컨테이너 런타임, 포맷 표준

runc는

  1. 컨테이너 런타임을 실행하고
  2. 이를 통해 생성된 컨테이너 이미지를 해석하고
  3. 격리된 환경에서 실행

합니다!

컨테이너 오케스트레이션☸ 기술의 등장

배경

컨테이너 환경에서 앱을 배포했다고 가정해봅시다!

현재 애플리케이션의 버전은 V1 상태인데, V2로 버전을 올려서 배포하고 싶습니다. 어떻게 해야 할까요⁉️

container-deployment출처: 쿠버네티스 어나더 클래스 (지상편) - Sprint1


  1. APP V2 컨테이너를 생성한다.
  2. APP V2가 잘 작동하고 있는지 확인한다.
  3. APP V1으로 흘러가던 사용자의 트래픽을 APP V2로 전환한다(네트워크 수정).
  4. APP V1을 삭제한다.

애플리케이션 컨테이너가 하나일 때는 1~4 과정을 수행하는 것이 편하게 느껴질 수 있겠지만, 여러 개의 컨테이너를 관리해야 할 때는 관리가 어려워집니다.

특히, CI/CD 파이프라인의 일부로써 자동화 없이 대규모 애플리케이션을 관리하는 것은 불가능에 가깝습니다.

이러한 배경에서 컨테이너 배포, 관리, 확장 네트워킹 자동화 기술인 컨테이너 오케스트레이션이 등장합니다!

volia

컨테이너 오케스트레이션☸

컨테이너 오케스트레이션 기술은 여러 개가 있었지만, 현재 기업용 쿠버네티스 솔루션이 많이 나온 것을 통해 쿠버네티스가 대세인 것을 알 수 있습니다.

따라서, 쿠버네티스를 바탕으로 컨테이너 오케스트레이션을 살펴보겠습니다.

container-orchestration-tech

위에서 살펴본 앱 버전을 V1에서 V2로 변경하는 과정을 다시 살펴봅시다!

이전에는

  1. APP V2 컨테이너를 생성한다.
  2. APP V2가 잘 작동하고 있는지 확인한다.
  3. APP V1으로 흘러가던 사용자의 트래픽을 APP V2로 전환한다(네트워크 수정).
  4. APP V1을 삭제한다.

와 같은 과정을 개발자가 ‘직접’ 수행해야 했지만, 이제는 아래와 같이 컨테이너 생성, 조회, 네트워크 수정, 컨테이너 삭제 과정을 쿠버네티스가 대신 하게 됩니다 😮

container-orchestration-deployment출처: 쿠버네티스 어나더 클래스 (지상편) - Sprint1


컨테이너 오케스트레이션은 아래와 같은 방식으로 동작합니다.
  1. 구성(JSON 또는 YAML 형식의 config) 파일을 작성한다.
    1. APP 구성 컨테이너 이미지와 경로(레지스트리) 정의
    2. 스토리지, 기타 리소스 프로비저닝(프로비저닝은 인프라 생성, 설정 프로세스를 뜻함)
    3. 컨테이너 간 네트워크 연결 정의·보호
    4. 버전 관리 지정
  2. 컨테이너 배포
    1. kube-apiserver에 Pod 생성 API 호출
    2. kube-apiserver는 kubelet에 Pod 생성 요청
    3. kubelet은 컨테이너 런타임(도커, rkt, cri-o)에 컨테이너 생성 요청
  3. 컨테이너 오케스트레이션 툴의 컨테이너 라이프사이클 관리
    1. 컨테이너 간 확장성(위 및 아래), 부하 분산 및 리소스 할당 관리
    2. 가동 중단 또는 시스템 리소스 부족 시 컨테이너를 다른 호스트로 재배치하여 가용성 및 성능 보장
    3. 애플리케이션의 상태와 성능을 모니터링하는 데 사용되는 로그 데이터 등을 수집·저장

쿠버네티스 도커 지원 종료 이슈?

쿠버네티스는 v1.20 이후 컨테이너 런타임으로서 도커를 사용 중단(deprecating)한다고 발표했습니다.

컨테이너 오케스트레이션 동작 방식에서 kublet이 도커에 컨테이너 생성 요청을 한다고 소개했던 내용을 기억하고 계신가요?

쿠버네티스의 도커 지원 중단은 파드(Pod) 생성을 담당하는 kublet에서 도커 api 호출이 제거된다는 의미합니다.

사실 이 이슈는 역사가 긴 문제인데, 쿠버네티스 버전별로 도커와 관련된 역사는 아래와 같습니다.


쿠버네티스가 도커를 지원하지 않게 된 배경에는

  • 도커가 컨테이너 런타임 인터페이스인 CRI(Container Runtime Interface)를 준수하지 않아 CRI 도구인 도커심(Dockershim)을 사용해야 하고
  • 도커심은 추가적인 유지 관리를 필요로 하고 오류의 가능성도 높아지기

때문입니다.

결국 쿠버네티스가 필요한 건 위 그림에서 볼 수 있듯이 컨테이너 런타임인데, “왜 도커 api를 호출해야 하며 CRI 준수를 위해 쿠버네티스에서 도커심을 만들고 있어야 하냐!!!” 라는 말이죠 😀

why

이런 관점에서 본다면, 도커와 쿠버네티스는 여전히 함께 사용할 수 있습니다.

왜냐하면 도커가 ‘실제로 생성하는 이미지’는 도커에 한정된 이미지가 아니라 OCI 표준을 갖춘 ‘호환 이미지’이며, 이 이미지는 쿠버네티스에서든 도커에서든 똑같이 사용할 수 있기 때문이죠!

따라서, 쿠버네티스에서는

기존 도커 엔진 노드를 도커심에서 cri-dockerd로 마이그레이션하는 방법

도커 엔진과 쿠버네티스를 통합하는 방법

을 안내하며, 여전히 쿠버네티스와 도커는 함께 사용할 수 있다고 알려주고 있습니다.

요약하면, kublet에서 컨테이너 생성을 요청할 때 사용하는 CRI 플러그인이 도커심(dockershim)에서 cri-dockerd로 바뀐다는 것이지 도커와 쿠버네티스를 함께 사용하지 못하는 것이 아니란 얘기입니다!!

참고자료

쿠버네티스 어나더 클래스 (지상편) - Sprint1

레드햇 토픽 컨텐츠: 컨테이너화란?

IBM 토픽 컨텐츠: 컨테이너란?

LXC vs Docker: Which Container Platform Is Right for You ?

IBM 토픽 컨텐츠: 컨테이너 오케스트레이션이란 무엇인가요?

쿠버네티스 문서: 도커 엔진 노드를 도커심에서 cri-dockerd로 마이그레이션하기

쿠버네티스 문서: 컨테이너 런타임

쿠버네티스 문서: 당황하지 마세요. 쿠버네티스와 도커

profile
계속 읽고 싶은 글을 쓰고 싶어요 ☺

0개의 댓글