Docker vs. Kubernetes

슬로우플랫폼·2024년 4월 12일
2
post-thumbnail

안녕하세요, Slow Platform의 Tony입니다.

저희 서비스의 백엔드 개발은 MSA Architecture로 개발을 진행하고 있습니다.
때문에 MSA Architecture의 안정적인 서비스 운영을 위해 Kubernetes에 대한 이해도를 높이기 위해 Docker와 Kubernetes에 대하여 나름대로의 정리를 해보고자 합니다.

Docker는 컨테이너 기반의 오픈소스 가상화 플랫폼으로, 2013년에 공개되어 마이크로서비스를 기반으로 하는 컴퓨팅 모델의 시작을 알렸습니다. 컨테이너는 운영 체제에 의존하지 않기 때문에, 팀들은 애플리케이션, 필요한 종속성, 그리고 설정을 컨테이너 이미지 형태로 선언적으로 패키징하여 관리할 수 있습니다. 이로 인해 개발 과정이 유연해지고 마이크로서비스를 확장하기가 더 쉬워졌습니다.

하지만 애플리케이션이 복잡해지고 많은 서버에 걸쳐 수많은 컨테이너를 관리해야 할 경우, 컨테이너들을 효율적으로 조정하고 운영하는 데 필요한 여러 문제들이 발생합니다. 예를 들어, 여러 컨테이너를 어떻게 조정하고 예약할지, 컨테이너 간 통신은 어떻게 활성화할지, 컨테이너 인스턴스를 어떻게 확장할지 등의 문제들입니다.

이러한 문제를 해결하기 위해 도입된 Kubernetes는 구글의 내부 프로젝트 Borg로부터 출발한 다양한 컨테이너 런타임을 지원하는 컨테이너 오케스트레이션 플랫폼으로, Docker를 포함한 많은 런타임에서 컨테이너의 실행과 관리를 돕습니다. Kubernetes는 복잡한 환경에서 컨테이너의 운영을 간소화하고 효율화하여, 팀이 애플리케이션을 더욱 쉽게 배포하고 관리할 수 있도록 지원합니다.

Docker (도커)

Docker란 Go언어로 작성된 리눅스 컨테이너 기반의 오픈소스 가상화 플랫폼입니다.
현재 Docker 0.9버전 부터는 직접 개발한 libcontainer 컨테이너를 사용하고 있습니다.

가상화를 사용하는 이유는?

이제는 향상된 컴퓨터의 성능을 더욱 효율적으로 사용하기 위해 가상화 기술이 많이 등장 하였습니다.

서버 관리자 입장에서 CPU 사용률이 10%대 밖에 되지 않는 활용도가 낮은 서버들은 리소스 낭비일 수밖에 없습니다.  그렇다고 모든 서비스를 한 서버 안에 올린다면 안정성에 문제가 생길수도 있습니다. 그래서 안정성을 높이며 리소스도 최대한 활용할 수 있는 방법으로 나타난게 서버 가상화입니다. 모두가 아는 대표적인 가상화 플랫폼으로는 VM(Virtual Machin)이 있습니다. VM은 누구나 아는 OS가상화지요. 그렇다면 컨테이너란 무엇일까요?

컨테이너란?

컨테이너는 가상화 기술 중 하나로 대표적으로 LXC(Linux Container)가 있습니다. 기존 OS를 가상화 시키던 것과 달리 컨테이너는 **OS레벨의 가상화로 프로세스를 격리시켜 동작하는 방식**으로 이루어집니다.

가상화 기술에 대해 조금만 더 깊게 들어가볼까요?

가상화 기술 (Virtualization)

가상화란 한 대의 시스템 하드웨어를 논리적으로 분할하여 가상의 시스템에 활용하는 개념입니다.
가상 시스템들은 서로 독립적인 하나의 시스템으로 인지되기 때문에 주어진 하드웨어 리소스를 효율적으로 사용할 수 있습니다.

가상화의 핵심은 Isolation이며 이는 하나의 물리적 장치를 논리적으로 격리시킨다는 것입니다.
제대로 격리가 이루어진다면 해당 가상 시스템 안에서 문제가 발생해도 그 밖의 영역으로는 영향을 미치지 않는다는 장점을 가집니다.

과거에 쓰이던 하드웨어 가상화와는 달리 현재 쓰이는 소프트웨어적인 가상화 기술을 Hypervisor라고 합니다.

가상화 기술

1) 호스트 OS형 가상화


그림1 : 호스트형 가상화 기술

호스트 가상화는 Base가 되는 Host OS위에 Guest OS가 구동되는 방식입니다. 종류로는 VM Workstation, VMware Server, VMware Player, MS Virtual Sever, Virtual PC, Virtual Box, Paralles Workstation 등이 있습니다.

  • 장점 : 가상의 하드웨어를 에뮬레이팅하기 때문에 호스트 운영체제에 크게 제약사항이 없음.
  • 단점 : OS위에 OS가 얹히는 방식이기 때문에 오버헤드가 클 수 있음.

2) 하이퍼바이저 가상화

그림2 : 하이퍼바이저 가상화 기술

하이퍼바이저는 호스트OS를 필요로 하지 않는 타입의 가상화 방식입니다.
호스트OS를 설치하는 게 아니라, 하이퍼바이저라는 소프트웨어를 물리 하드웨어 위에 직접 작동시켜, 하이퍼바이져 위에 각각의 하드웨어에 게스트 운영체제를 설치해서 움직이게 하는 것입니다.
호스트OS 형과 다른 점은 가상머신이 마치 독립적인 호스트 시스템처럼 작동한다는 것이며 복수의 가상화머신이 서로 간섭하지 않도록 하는 것이 하이퍼바이저형의 역할이기 때문에, 처리 오버헤드가 존재하지 않습니다.

  • 장점 : 별도의 Host OS가 없기 때문에 오버헤드가 적고, 하드웨어를 직접 제어하기 때문에 효율적으로 리소스를 사용할 수 있음.
  • 단점 : 자체적으로 머신에 대한 관리 기능이 없기 때문에 관리를 위한 컴퓨터나 콘솔이 필요함.

하이퍼바이저 가상화는 아래와같이 다시 전가상화(Full-Virtualization or Hardware Virtual Machine) 와 반가상화(Para-Virtualization)로 분류 됩니다.

2-1) 전가상화(Full-Virtualization)


그림 - CPU의 동작 레벨. 링0는 특권모드로 OS 커널이 동작한다.

전가상화는 하드웨어를 완전히 가상화 하는 방식으로 Hardware Virtual Machine 이라고도 불립니다.
하이퍼바이저를 구동하면 DOM0라고 하는 관리용 가상 머신이 실행되며, 모든 가상머신들의 하드웨어 접근이 DOM0을 통해서 이루어집니다.
즉, 모든 명령에 대해서 DOM0가 개입을 하게되는 형태입니다.

쉽게 말해 하이퍼바이저는 가상화된 OS가 뭐든지간에 각 OS가 내리는 명령어를 알아들을 수 있습니다.
예를들어 윈도우 에서 Add, 리눅스 에서 ADD, 맥에서 add라는 명령어를 내렸을때 하이퍼바이저가 “더해라”라고 번역 하여 명령어를 실행해주는 것입니다.
하이퍼바이저는 이러한 번역 역할 뿐만 아니라 가상화된 OS에게 자원을 할당해주는 역할도 담당합니다.

  • 장점 : 하드웨어를 완전히 가상화하기 때문에 Guest OS 운영체제의 별다른 수정이 필요 없음.
  • 단점 : 하이퍼바이저가 모든 명령을 중재하기 때문에 성능이 비교적 느림.
2-2) 반가상화(Para-Virtualization)


그림3 : 왼쪽은 반가상화 방식, 오른쪽은 전가상화 방식 (게스트가 하드웨어에 직접 접근할 수 있는지에 차이가 있음)

반가상화는 전가상화와 달리 하드웨어를 완전히 가상화 하지 않습니다.
전가상화의 가장큰 단점인 성능저하의 문제를 해결하기 위해 하이퍼콜(Hyper Call)이라는 인터페이스를 통해 하이퍼바이저에게 직접 요청을 날릴 수 있습니다.
쉽게 말하면 가상화된 각 OS들이 각각 다른 번역기를 갖고 있는 것입니다. 그 번역기는 각각 다른 OS에서 내리는 각각 다른 명령어를 “더해라”라고 번역해주게 되는 것입니다.

  • 장점 : 모든 명령을 DOM0를 통해 하이퍼바이저에게 요청하는 전가상화에비해 성능이 빠름.
  • 단점 : 하이퍼바이저에게 Hyper Call 요청을 할 수 있도록 각 OS의 커널을 수정해야하며 오픈소스 OS가 아니면 반가상화를 이용하기가 쉽지 않음.


그림4 : 왼쪽부터 차례로 전가상화, 반가상화, 호스트 OS형

3) 컨테이너형 가상화


그림 - 컨테이너형 가상화 기술

컨테이너형은 위에 언급된 방식과 달리 하드웨어를 가상화하는 방식이 아닙니다.
위의 두 방식과는 다르게 OS를 가상화하지 않고 소프트웨어를 바로 가상화하는 기술입니다. 프로세스를 격리시키기 때문에 가볍고 빠르게 동작합니다. CPU나 메모리는 프로세스가 필요한 만큼만 추가로 사용되기 때문에 성능적으로도 거의 손실이 없고 하나의 서버에 여러 개의 컨테이너를 실행하면 서로 영향을 주지 않고 독립적으로 실행되기 때문에, 마치 성능 좋고 가벼운 가상머신을 사용하는 느낌을 줄 수 있습니다.

  • 장점 : 컨테이너 가상화는 오버헤드가 적어 가볍고 빠른 장점이 있음.

핵심 요약

OS가상화는 컨테이너기반 가상화보다 더 높은 격리 레벨을 지원합니다. 이는 보안적인 측면에서 더욱 유리합니다.

또한 OS가상화의 커널을 공유하지 않는 장점 또한 있습니다. 커널을 공유하지 않는 만큼 멀티 OS가 가능하다는 것입니다. 커널을 공유하지 않아 멀티 OS가 불가능 하다는 것은 Linux위에 Window를 올릴 수 없다는 단점이 있는 것이죠. 그럼에도 왜 Docker를 쓰는 이유는 다음과 같다고 생각합니다.

  • 높은 성능
  • 뛰어난 이식성
  • 쉽게 Scale Out을 할 수 있는 유연성

Docker 주요 구성 요소

Docker는 컨테이너화된 애플리케이션을 생성하고 관리하는 데 사용되는 주요 도구 중 하나로, 여러 중요한 구성 요소로 이루어져 있습니다. 각 구성 요소는 Docker의 전체적인 기능성과 효율성에 기여합니다. 다음은 Docker의 주요 구성 요소들에 대한 설명입니다:

1) Docker Engine

Docker 엔진은 서버-클라이언트 형태의 기술로 Docker의 핵심이 되는 부분입니다. 이 엔진은 컨테이너를 생성 실행 및 관리하는 중앙 집중식 서비스를 제공합니다. Docker 엔진은 세 부분으로 구성됩니다:
  • Daemon (dockerd): Docker 데몬은 백그라운드에서 실행되며 컨테이너 관리를 담당하는 주요 서비스입니다. 이미지, 컨테이너, 네트워크, 볼륨의 생성과 관리를 책임집니다.
  • REST API: Docker 데몬과 통신하는 인터페이스로, 다양한 Docker 클라이언트와 프로그램들이 Docker 데몬과 통신할 수 있게 해줍니다.
  • Client (docker): 사용자가 명령어를 입력하여 Docker 데몬과 상호 작용할 수 있는 커맨드라인 인터페이스(CLI)입니다. Docker 클라이언트는 사용자의 명령을 API 요청으로 변환하여 Docker 데몬에 전달합니다.

2) Docker Images

Docker 이미지는 읽기 전용의 템플릿으로, 컨테이너를 생성하는 데 사용됩니다. 이미지는 애플리케이션과 그 모든 종속성을 포함하며, Dockerfile이라는 스크립트를 통해 구축됩니다. Docker 이미지는 Docker Hub와 같은 레지스트리에서 공유되고 관리될 수 있습니다.

3) Docker Containers

컨테이너는 이미지를 기반으로 실행되는 격리된 환경에서 애플리케이션을 포함하고 있습니다. 컨테이너는 이미지의 실행 가능한 인스턴스로, 자체 파일 시스템, 네트워킹 환경, 독립적인 프로세스 공간 등을 가집니다. 사용자는 이 컨테이너를 시작, 정지, 이동, 삭제할 수 있습니다.
Dockerfile Example
FROM komljen/nodejs
MAINTAINER Alen Komljen <alen.komljen@live.com>

ENV GHOST_VERSION 0.5.7
ENV APP_ROOT /data/app

RUN \
  curl -sLO http://ghost.org/archives/ghost-${GHOST_VERSION}.zip && \
  mkdir -p ${APP_ROOT} && \
  unzip -uo ghost-${GHOST_VERSION}.zip -d ${APP_ROOT} && \
  rm ghost-${GHOST_VERSION}.zip

RUN \
  cd ${APP_ROOT} && \
  npm install --production

COPY start.sh start.sh

VOLUME ["$APP_ROOT"]

RUN rm /usr/sbin/policy-rc.d
CMD ["/start.sh"]

EXPOSE 2368

* Dockerfile을 이용하여 Docker Image를 생성할 수 있습니다.

4. Docker Compose

Docker Compose는 여러 컨테이너를 정의하고 실행하기 위한 도구입니다. YAML 파일을 사용하여 서비스, 네트워크, 볼륨 등을 구성하며, 이 파일을 이용하여 여러 컨테이너로 구성된 애플리케이션을 관리할 수 있습니다.
Docker Compose Example
version: '3'

services:
planka:
  image: ghcr.io/plankanban/planka:latest
  restart: on-failure
  volumes:
    - user-avatars:/app/public/user-avatars
    - project-background-images:/app/public/project-background-images
    - attachments:/app/private/attachments
  ports:
    - 3000:1337
  environment:
    - BASE_URL=http://plank.example.com:3000
    - DATABASE_URL=postgresql://postgres@postgres/planka
    - SECRET_KEY=secret
    - DEFAULT_ADMIN_EMAIL=admin@example.com # Do not remove if you want to prevent this user from being edited/deleted
    - DEFAULT_ADMIN_PASSWORD=Password
    - DEFAULT_ADMIN_NAME=Admin
    - DEFAULT_ADMIN_USERNAME=admin

  depends_on:
    postgres:
      condition: service_healthy

postgres:
  image: postgres:14-alpine
  restart: on-failure
  volumes:
    - db-data:/var/lib/postgresql/data
  environment:
    - POSTGRES_DB=planka
    - POSTGRES_HOST_AUTH_METHOD=trust
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U postgres -d planka"]
    interval: 10s
    timeout: 5s
    retries: 5

volumes:
user-avatars:
project-background-images:
attachments:
db-data:

5. Docker Hub/Registry

Docker Hub는 Docker 이미지를 공유하고 배포할 수 있는 클라우드 기반 서비스입니다. 사용자는 이곳에서 이미지를 저장하거나 Docker 공식 이미지 뿐만 아니라 다른 사용자가 만든 이미지도 찾아 사용할 수 있습니다.

이 구성 요소들이 통합되어 Docker는 개발에서부터 배포까지 전 과정에서 컨테이너를 효율적으로 관리할 수 있는 강력한 도구를 제공합니다.

Kubernetes (쿠버네티스)

## 쿠버네티스란?
  • 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식 가능하고 확장 가능한 오픈 소스 플랫폼입니다.
  • 빠르게 성장하는 대규모의 에코시스템이 있습니다.
  • Kubernetes라는 이름은 조타수 또는 조종사를 의미하는 그리스어에서 유래했습니다.
  • 약자로서의 K8은 "K"와 "s" 사이의 8글자를 세어 만든 것입니다.
  • Google은 2014년에 Kubernetes 프로젝트를 오픈소스화했습니다. (2015년에 정식 release 했고 현재는 CNCF로 완전히 이관되었습니다.)

Planet Scale (확장성)

애플리케이션을 구성하는 컨테이너를 논리적 단위로 그룹화하여 쉽게 관리하고 검색할 수 있습니다. Kubernetes는 [15년간의 Google 프로덕션 워크로드 운영 경험]과 커뮤니티의 동급 최고의 아이디어 및 사례에 기반하여 구축되었습니다.

Never Outgrow (안정성)

Google이 일주일에 수십억 개의 컨테이너를 실행할 수 있는 것과 동일한 원리로 설계된 Kubernetes는 운영 팀을 늘리지 않고도 확장할 수 있습니다.

Run K8s Anywhere

쿠버네티스는 온프레미스, 하이브리드 또는 퍼블릭 클라우드 인프라를 자유롭게 활용할 수 있는 오픈 소스이므로 워크로드를 중요한 위치로 손쉽게 이동할 수 있습니다.
로컬에서 테스트하든 글로벌 엔터프라이즈를 운영하든, Kubernetes는 요구 사항이 아무리 복잡하더라도 애플리케이션을 일관되고 쉽게 제공할 수 있도록 유연성을 함께 확장합니다.

쿠버네티스의 특징

1) 오픈소스


  • 10만개 이상의 Github Star, 3500명 이상의 컨트리뷰터들

2) 엄청난 인기

CNCF의 서베이에 따르면 2016년 이후 2019년까지의 컨테이너 채택 상황은 다음과 습니다.


실제 쿠버네티스의 컨테이너 관리 툴 시장 점유율은 지난 2017년 약 50%에서 18년에는 58%, 그리고 2019년에는 78%로 크게 높아졌다. 컨테이너 관리 솔루션 분야의 표준으로 자리매김한 것입니다.
출처 : 컴퓨터월드(http://www.comworld.co.kr)

  • 150 이상의 커뮤니티
  • 개방성 (구글의 독창적인 엔지니어링은 물론, 지속적인 개발에 대한 구글의 무간섭 방식)

3) 무한한 확장성

  • 구글에서 실제로 사용하던 기술이기 때문에 실질적으로 1주일에 20억개정도의 컨테이너까지는 운영이 가능하다고 볼 수 있다.

4) 사실상의 표준

  • Docker도 Kunbernetes를 지원
  • AWS EKS, Azure AKS, Google GKE 등의 클라우드에서 쿠버네티스를 매니지드 서비스로 제공하고 있음

배포 환경의 변화

시간이 흐름에 따른 배포환경의 변화를 통해 쿠버네티스의 유용성이 왜 증가하였는지를 살펴보겠습니다.

1. 전통적인 배포

초기 조직에서는 애플리케이션을 물리 서버 상에서 운영하였습니다. 단일 물리 서버 상에서 여러 애플리케이션의 리소스 한계를 명확히 설정할 수 없었기 때문에, 리소스 할당에 관련된 문제가 발생하였습니다. 예를 들어, 하나의 서버에서 여러 애플리케이션을 실행할 경우, 어떤 애플리케이션 인스턴스가 모든 리소스를 점유하여 다른 애플리케이션의 성능이 저하될 수 있었습니다. 이 문제의 해결 방안으로, 각 애플리케이션을 서로 다른 물리 서버에서 실행할 수 있으나, 이 경우 리소스가 충분히 활용되지 못하고, 많은 물리 서버를 유지하기 위한 높은 비용이 발생하였습니다.

2. 가상화된 배포

이러한 문제를 해결하기 위해 가상화 기술이 도입되었습니다. 가상화는 단일 물리 서버의 CPU에서 여러 가상 시스템(VM)을 실행할 수 있게 함으로써, VM 간에 애플리케이션을 격리시키고, 서로 다른 애플리케이션 간의 정보 접근을 제한하여 일정 수준의 보안을 제공할 수 있게 합니다.
가상화를 통해 물리 서버의 리소스를 보다 효율적으로 활용하고, 애플리케이션을 손쉽게 추가하거나 업데이트할 수 있으며, 하드웨어 비용을 절감하여 더욱 향상된 확장성을 제공할 수 있습니다. 가상화를 이용해 일련의 물리 리소스를 가상 머신으로 구성된 클러스터로 전환할 수 있습니다.
각 VM은 가상화된 하드웨어 상에서 자체 운영 체제를 포함한 모든 구성 요소를 실행하는 하나의 완전한 머신으로 작동합니다.

3. 컨테이너 배포

컨테이너는 VM과 유사하나, 애플리케이션 간에 운영 체제(OS)를 공유하면서 격리 속성을 완화합니다. 이로 인해 컨테이너는 가벼운 것으로 간주됩니다. 컨테이너에는 자체 파일 시스템, CPU 점유율, 메모리, 프로세스 공간 등이 있으며, 기본 인프라와의 종속성이 없기 때문에 다양한 클라우드나 OS 배포판에 이식할 수 있습니다.

컨테이너는 다음과 같은 추가적인 혜택을 제공합니다.

  • 기민한 애플리케이션 생성과 배포: VM 이미지 사용에 비해 컨테이너 이미지 생성이 보다 쉽고 효율적입니다.
  • 지속적인 개발, 통합 및 배포: 안정적이고 주기적으로 컨테이너 이미지를 빌드 및 배포할 수 있으며, 이미지의 불변성 덕분에 빠르고 효율적으로 롤백할 수 있습니다.
  • 개발과 운영의 관심사 분리: 배포 시점이 아니라 빌드/릴리스 시점에 애플리케이션 컨테이너 이미지를 생성함으로써, 애플리케이션이 인프라스트럭처로부터 분리됩니다.
  • 가시성(observability): OS 수준의 정보에 국한되지 않고, 애플리케이션의 헬스와 기타 신호들을 확인할 수 있습니다.
  • 개발, 테스팅 및 운영 환경 간의 일관성: 랩탑에서도 클라우드에서와 동일하게 구동됩니다.
  • 클라우드 및 OS 배포판 간의 이식성: Ubuntu, RHEL, CoreOS, 온-프레미스, 주요 퍼블릭 클라우드 등 다양한 환경에서 구동됩니다.
  • 애플리케이션 중심 관리: 논리적인 리소스를 사용하여 OS 상에서 애플리케이션을 실행하는 수준으로 추상화 수준이 높아집니다.
  • 느슨하게 결합되고, 분산되고, 유연하며, 자유롭게 구성된 마이크로서비스: 애플리케이션은 단일 목적의 머신에서 모놀리식 스택으로 구동되지 않고, 더 작고 독립적인 단위로 나뉘어져 동적으로 배포되고 관리될 수 있습니다.
    • 리소스 격리: 애플리케이션 성능을 예측할 수 있습니다.
    • 리소스 사용량: 고효율 및 고집적 사용이 가능합니다.

쿠버네티스가 필요한 이유와 할 수 있는 것들

컨테이너는 애플리케이션을 포장하여 실행하는 매우 효율적인 방법을 제공합니다. 프로덕션 환경에서는 애플리케이션을 안정적으로 운영하기 위해 컨테이너의 관리 및 가동 중지 시간이 발생하지 않도록 주의 깊게 모니터링하는 것이 필수적입니다. 예컨대 컨테이너가 예기치 않게 중단되었을 경우, 다른 컨테이너를 신속히 재시작하는 등의 조치가 요구됩니다. 이러한 과정을 시스템적으로 자동화할 수 있다면, 관리의 효율성이 대폭 향상될 것입니다.

이러한 필요성을 충족시키기 위해 쿠버네티스가 매우 중요한 역할을 합니다. 쿠버네티스는 분산 시스템을 유연하게 운영할 수 있는 강력한 프레임워크를 제공하며, 애플리케이션의 확장, 장애 대응, 그리고 다양한 배포 전략을 지원합니다. 예를 들어, 쿠버네티스는 카나리아 배포와 같은 고급 배포 방식을 용이하게 관리할 수 있도록 돕습니다.

쿠버네티스는 다음과 같은 다양한 기능을 제공하여 사용자의 요구를 충족시킵니다.

  • 서비스 발견 및 로드 밸런싱: 쿠버네티스는 DNS 이름이나 자체 IP 주소를 통해 컨테이너를 외부에 노출할 수 있는 기능을 제공합니다. 이를 통해 컨테이너로의 트래픽이 증가할 경우, 쿠버네티스는 트래픽 분산 및 로드 밸런싱을 자동으로 수행하여 시스템의 안정적인 운영을 도모합니다.
  • 스토리지 오케스트레이션: 사용자는 쿠버네티스를 통해 로컬 저장소부터 공용 클라우드 공급자에 이르기까지 다양한 저장소 시스템을 자동으로 마운트하고 사용할 수 있습니다.
  • 자동화된 배포 및 롤백: 쿠버네티스를 활용하면 원하는 상태의 컨테이너 배포를 서술적으로 정의할 수 있으며, 시스템은 현재 상태를 사용자가 정의한 원하는 상태로 점진적으로 변경합니다. 이 과정은 새로운 컨테이너의 배포, 기존 컨테이너의 제거 및 업데이트 등을 포함할 수 있습니다.
  • 자동화된 자원 할당: 쿠버네티스는 컨테이너화된 작업을 위한 클러스터 노드의 자동 할당을 지원합니다. 사용자는 각 컨테이너에 필요한 CPU와 메모리(RAM) 요구사항을 명시할 수 있으며, 쿠버네티스는 이를 최적화하여 리소스 사용률을 극대화합니다.
  • 자동화된 복구: 쿠버네티스는 시스템의 자가 치유 기능을 지원하여 실패한 컨테이너를 자동으로 재시작하고, 문제가 있는 컨테이너를 교체하며, 정상 작동하지 않는 컨테이너를 종료시킵니다. 이러한 과정은 서비스가 준비되기 전까지 외부에 노출되지 않습니다.
  • 시크릿 및 구성 관리: 쿠버네티스를 통해 암호, OAuth 토큰, SSH 키와 같은 중요 정보를 안전하게 저장하고 관리할 수 있습니다. 이를 통해 컨테이너 이미지를 재구성하지 않고도 애플리케이션의 구성을 안전하게 배포 및 업데이트할 수 있습니다.

쿠버네티스가 아닌 것에 대하여

쿠버네티스는 전통적인, 모든 것을 일체로 포함하는 Platform as a Service(PaaS)와는 다릅니다. 쿠버네티스는 컨테이너 수준에서 작동하며, PaaS가 흔히 제공하는 배포, 스케일링, 로드 밸런싱과 같은 기능들을 지원합니다. 또한, 사용자가 로깅, 모니터링, 알림 솔루션을 통합할 수 있는 유연성을 제공합니다. 쿠버네티스는 모놀리식이 아니기 때문에, 이러한 기본 솔루션들은 선택적이며, 추가하거나 제거하기가 용이합니다. 쿠버네티스는 개발자 플랫폼을 구축하는 데 필요한 요소들을 제공하되, 필요한 경우 사용자에게 선택권과 유연성을 보장합니다.

쿠버네티스는 다음과 같은 특징을 갖고 있습니다:

  • 지원하는 애플리케이션 유형에 제한을 두지 않습니다. 쿠버네티스는 상태 비저장(stateless) 워크로드부터 상태 저장(stateful) 워크로드, 데이터 처리 워크로드에 이르기까지 매우 다양한 유형의 워크로드 지원을 목표로 합니다. 애플리케이션이 컨테이너에서 구동될 수 있다면, 쿠버네티스 상에서도 원활하게 동작할 것입니다.
  • 소스 코드 배포나 애플리케이션 빌드를 진행하지 않습니다. 지속적인 통합(CI), 지속적인 배포(CD) 워크플로우는 조직의 문화와 선호도, 기술적 요구사항에 따라 달라집니다.
  • 애플리케이션 수준의 서비스를 직접 제공하지 않습니다. 여기에는 미들웨어(예: 메시지 버스), 데이터 처리 프레임워크(예: Spark), 데이터베이스(예: MySQL), 캐시 또는 클러스터 스토리지 시스템(예: Ceph) 등이 포함됩니다. 이러한 구성요소들은 쿠버네티스 상에서 구동될 수 있으며, 쿠버네티스 상의 애플리케이션이 Open Service Broker와 같은 이식 가능한 메커니즘을 통해 접근할 수 있습니다.
  • 로깅, 모니터링, 경보 솔루션을 포함하지 않습니다. 쿠버네티스는 일부 통합 예시를 제공하거나, 메트릭 수집 및 노출을 위한 메커니즘을 제공할 수는 있습니다.
  • 기본 설정 언어나 시스템을 제하거나 요구하지 않습니다. 쿠버네티스는 선언적 API를 통해 선언적 명세의 다양한 형태를 지원합니다.
  • 머신 설정, 유지보수, 관리, 자동 복구 시스템을 포괄적으로 제공하거나 채택하지 않습니다.
  • 추가적으로, 쿠버네티스는 단순한 오케스트레이션 시스템이 아닙니다. 실제로, 쿠버네티스는 오케스트레이션 필요성을 제거합니다. 오케스트레이션은 정해진 워크플로우에 따라 작업을 수행하는 것을 의미합니다. 반면, 쿠버네티스는 독립적이고 조합 가능한 제어 프로세스로 구성되어 있으며, 이는 지속적으로 현재 상태를 원하는 상태로 변화시키는 작업을 수행합니다. 중앙집중식 제어가 필요하지 않으며, 이는 시스템을 더 사용하기 쉽고, 강력하며, 견고하고, 복원력 있으며, 확장 가능하게 만듭니다.

쿠버네티스 구성 및 설계(Architecture)

쿠버네티스의 주요 구성 요소

그림: Kubernetes cluster architecture

Kubernetes cluster architecture는 여러 개의 Componets와 Node로 구성된 분산 시스템입니다. 이 시스템은 컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화합니다. Kubernetes 클러스터는 크게 두 가지 유형의 리소스로 나뉩니다:

  • 컨트롤 플레인(Control Plane)워커 노드(Worker Nodes)

컨트롤 플레인 (Control Plane)

컨트롤 플레인은 클러스터의 전반적인 관리 및 조정을 담당합니다. 여기에는 클러스터의 상태 관리, 스케줄링, 구성 변경 등이 포함됩니다. 컨트롤 플레인은 다음과 같은 주요 컴포넌트로 구성됩니다:

  1. API 서버 (kube-apiserver)
    클러스터의 주요 관리 인터페이스로, 모든 커뮤니케이션은 API 서버를 통해 이루어집니다.
  2. 스케줄러 (kube-scheduler)
    새로 생성된 파드(Pods)를 워커 노드에 할당합니다.
  3. 컨트롤러 매니저 (kube-controller-manager)
    다양한 컨트롤러를 실행하여 클러스터 상태를 원하는 상태로 유지합니다. 예를 들어, 노드가 실패하면 자동으로 대체 리소스를 스케줄링합니다.
  4. 클라우드 컨트롤러 매니저 (cloud-controller-manager)
    클라우드 제공 업체의 API와 통신합니다.
  5. etcd
    모든 클러스터 데이터를 저장하는 경량의 분산 키-값 스토어입니다.

워커 노드 (Worker Nodes)

워커 노드는 실제로 애플리케이션 컨테이너를 실행하는 서버입니다. 각 워커 노드는 다음의 주요 컴포넌트를 포함합니다:

  1. kubelet: 각 노드에서 실행되는 에이전트로, API 서버와 통신하며 파드의 실행을 관리합니다.
  2. 컨테이너 런타임 (Docker, containerd 등): 컨테이너를 실행하기 위한 환경을 제공합니다.
  3. kube-proxy: 네트워크 프록시 및 로드 밸런서 역할을 하며, 컨테이너의 네트워크 규칙을 관리합니다.

클러스터 네트워킹

Kubernetes는 클러스터 내의 모든 컴포넌트 간 통신을 가능하게 하는 강력한 네트워킹 모델을 제공합니다. 모든 파드는 고유한 IP 주소를 가지며, 서로 통신할 수 있어야 합니다. 이를 위해 네트워크 플러그인을 사용하여 복잡한 네트워킹 요구 사항을 충족 시킵니다.

스토리지

Kubernetes는 퍼시스턴트 볼륨(Persistent Volumes, PVs)과 퍼시스턴트 볼륨 클레임(Persistent Volume Claims, PVCs)을 통해 스토리지를 관리합니다. 이를 통해 스토리지 리소스를 동적으로 프로비저닝하고, 파드에서 사용할 수 있게 합니다.

클러스터 보안

Kubernetes는 RBAC(Role-Based Access Control), 네트워크 폴리시, 시크릿 관리 등을 통해 클러스터 보안을 강화합니다. 이를 통해 민감한 데이터를 보호하고, 클러스터 리소스에 대한 접근을 제어합니다.
Kubernetes 클러스터 아키텍처는 이러한 컴포넌트와 개념을 기반으로 복잡한 컨테이너화된 애플리케이션의 배포와 운영을 단순화합니다. 클라우드 환경, 온프레미스, 또는 하이브리드 환경에서도 유연하게 구성할 수 있습니다.

쿠버네티스 오브젝트(Objects)

Pod

  • 가장 작은 배포 단위
  • 전체 클러스터에서 고유한 IP를 할당
  • 여러개의 컨테이너가 하나의 Pod에 속할 수 있음

ReplicaSet

  • 여러개의 Pod를 관리

Deployment

  • 배포 버전을 관리
  • 내부적으로는 ReplicaSet을 이용

Workloads

  • 다양한 워크로드가 있음

Services

Service-ClusterIP

Service-NordPort

Load Balancer

Ingress

일반적인 구성

기타 기본 오브젝트

  • Volume - Storage (EBS, NFS, ...)
  • Namespace
  • ConfigMap/Secret - 설정
  • ServiceAccount - 권한 계정
  • Role/ClusterRole - 권한 설정

Kakao Cloud Kubernetes

슬로우의 서비스는 카카오 클라우드에서 운영될 예정입니다.
따라서 카카오 클라우드에서 지원하는 쿠버네티스 서비스에 대해서 조금 살펴보도록 하겠습니다.

사용 목적 및 사례

사용자가 직접 Kubernetes 클러스터를 배포할 경우 Virtual Machine의 인스턴스를 준비하고, 마스터 노드와 워커 노드를 구성하고 지속적으로 마스터 노드를 관리해야 합니다. 하지만, 카카오클라우드의 Kubernetes Engine은 이러한 번거로운 과정을 클릭 몇 번으로 대신해 줍니다. 사용자는 별도로 Kubernetes 클러스터를 배포할 필요가 없으며, 수시로 변화하는 서비스 요구사항에 맞게 클러스터를 확장하고 삭제할 수 있습니다. 마스터 노드는 별도의 영역에서 관리되어 사용자가 관리할 필요가 없으며, 사용자는 자신의 VPC에 배포한 워커 노드와 애플리케이션에만 집중할 수 있습니다.

카카오클라우드의 Kubernetes Engine은 웹, 애플리케이션 등 모든 종류의 컨테이너 서비스를 지원합니다.

주요 특징

간편한 클러스터 관리

  • Kubernetes 클러스터를 효율적으로 관리하기 위한 최적화된 메뉴 구성, 기능과 노드 풀을 이용한 노드 그룹 관리 기능을 제공
  • VM 서비스와의 긴말한 연계로 다양한 VM 플레이버를 지원하고 손쉬운 인스턴스 관리가 가능

Multi-AZ로 고가용성 지원

  • Kubernetes Engine의 클러스터와 노드를 Multi-AZ에서 실행하여 높은 수준의 가용성을 제공
  • 클러스터와 노드가 여러 AZ(가용 영역)에서 실행되며, 특정 AZ에 문제가 발생해도 다른 AZ에서 정상적으로 실행되어 서비스 중단 없는 고가용성을 제공

다양한 서비스팩 연동

  • 카카오클라우드의 다른 Container Pack 서비스인 Container Registry와 함께 연동하여 사용
  • 내 클러스터에 Helm Chart와 컨테이너 이미지를 간단하게 배포

안전한 서비스 환경

  • 사용자의 VPC 환경에 노드를 배포하는 방식으로 논리적으로 분리된 사용자 네트워크에서 안전하게 클러스터를 운영
  • 클러스터의 제어 영역은 완전 관리되어 별도 운영 작업이 필요하지 않음

RBAC 기반 권한 관리

  • 역할 기반 접근 제어(RBAC)를 기반으로 프로젝트 권한을 가진 사용자가 프로젝트와 프로젝트 내 클러스터 리소스를 관리할 수 있도록 지원
  • 역할에 따라 목적과 역할에 맞게 클러스터를 구분 가능

주요 개념

클러스터

그림 : Kubernetes Engine의 클러스터 아키텍처
  • Kubernetes Engine은 클러스터 생성 삭제만 관여를 하는 것으로 보임
  • 클러스터 생성시 Control plane 및 워커 노드가 생성되어 kubectl / Kubernetes api 호출이 가능하다고 함 ()

노드 풀

노드 풀은 동일한 인스턴스 유형을 가지는 노드 그룹이며, Kubernetes Engine에서는 노드를 노드 풀 단위로 관리합니다. 클러스터를 만들 때 생성하는 노드 풀이 최초의 노드 풀이 됩니다. 이후 다른 인스턴스 유형을 가지는 추가 노드 풀을 클러스터에 추가할 수 있습니다. 노드 풀의 각 노드에는 노드 풀의 이름을 값으로 가지는 kakaoi.io/kke-nodepool이라는 Kubernetes 노드 레이블이 설정되어 있습니다.

  • 노드 풀 설정에서 노드 수를 조절하여 클러스터에서의 노드 풀 크기를 조절할 수 있으며, 노드 풀에서 특정 노드만 삭제하는 것은 불가능합니다.
  • 초기 노드 풀 생성 시 클러스터에 설정된 최신 Kubernetes 버전을 선택합니다. 이후 사용자는 각 노드 풀을 독립적으로 업데이트하고 관리할 수 있습니다.

<안내>
클러스터는 최소한 한 개 이상의 노드 풀을 유지하여야 합니다.

리소스 상태 정보

Kubernetes Engine에서 상태를 확인할 수 있는 리소스는 클러스터, 노드 풀, 노드입니다. 리소스 별 상태 정보는 다음과 같습니다.

클러스터 생명주기 및 상태

이미지. 클러스터 생명주기
클러스터의 생명주기

클러스터 상태설명분류
Provisioned클러스터 프로비저닝 완료Green
Pending클러스터 프로비저닝 준비 중Yellow
Provisioning클러스터 프로비저닝 중Yellow
Deleting클러스터 삭제 중Yellow
Failed사용자의 개입이 필요한 실패 상태Red

노드 풀 생명주기 및 상태

이미지. 클러스터 생명주기
노드 풀 생명주기

노드 풀 상태설명분류
Running노드 풀 정상 실행 중 (노드 상태와는 무관)Green
Running (Scheduling Disable)노드 풀의 모든 노드가 스케줄링 차단된 상태Green
ScalingUp노드 개수 확장 중Yellow
ScalingDown노드 개수 축소 중Yellow
Deleting노드 풀 삭제 중Yellow
Failed사용자의 개입이 필요한 실패 상태Red

노드 생명주기 및 상태

이미지. 클러스터 생명주기
노드 생명주기

노드 상태설명분류
Running노드가 준비되어 실행 중Green
Running (Scheduling Disable)해당 노드로 신규 스케줄링 차단된 상태 (이미 할당되어 실행 중인 파드와는 무관)Green
Provisioned노드 프로비저닝 완료Green
Deleted노드 삭제 완료Green
Pending노드 프로비저닝 준비 중Yellow
Provisioning노드 프로비저닝 중Yellow
Deleting노드 삭제 중Yellow
Failed사용자의 개입이 필요한 실패 상태Red

클러스터/노드 풀 생성 시 자동 생성 리소스

Kubernetes Engine에서 클러스터 혹은 노드 풀 생성 시 리소스는 자동 생성됩니다. 클러스터 삭제 시 리소스도 같이 삭제됩니다.

클러스터/노드 풀 생성 시 자동 생성 리소스

유형설명
인스턴스노드로 사용되는 VM 인스턴스
볼륨노드로 사용되는 VM 인스턴스에서 사용하거나 NFS Client Provisioner로 생성한 모든 볼륨
Security Group노드에 적용되는 Security Group

<주의>
자동 생성된 리소스(인스턴스, 볼륨, Security Group)는 이름 변경, 삭제 등의 설정 정보를 변경할 수 없습니다. 관련 리소스의 정보가 변경되면 Kubernetes Engine 서비스가 정상적으로 제공되기 어려우니, 주의하시기 바랍니다.

서비스 요금 및 쿼터


profile
슬로우플랫폼 기술블로그입니다.

0개의 댓글