쿠버네티스 클러스터 이해하기

artp·2025년 1월 9일

kubernetes

목록 보기
12/18
post-thumbnail

1. 쿠버네티스 클러스터(Kubernetes Cluster)란?

쿠버네티스 클러스터는 컨테이너화된 애플리케이션을 실행하고 관리하기 위한 하나의 시스템으로, 컨트롤 플레인노드(워커 머신)로 구성됩니다.

1.1 클러스터를 실행한다는 것은 쿠버네티스를 실행한다는 것입니다.

쿠버네티스를 설치하거나 클라우드 환경에서 서비스를 시작하면, 실제로는 하나의 클러스터가 생성됩니다.

클러스터 생성은 kubeadm과 같은 도구를 사용하거나 AWS EKS, Google GKE, Azure AKS와 같은 클라우드 제공자를 통해 수행할 수 있습니다. 즉, 쿠버네티스를 실행 중이라는 것은 곧 클러스터를 실행하고 있다는 뜻입니다.

1.2 클러스터는 노드의 집합입니다.

쿠버네티스 클러스터는 컨테이너화된 애플리케이션을 실행하는 노드의 집합입니다. 클러스터는 노드(서버들)를 묶어 컨테이너화된 애플리케이션을 실행, 관리, 배포하는 환경을 제공합니다.

  • 컨트롤 플레인(마스터 노드)은 이 노드 집합을 관리하며, 스케줄링, 상태 모니터링, 파드 배포, 자원 할당과 같은 작업을 수행합니다.

  • 노드(워커 노드)는 실제 애플리케이션을 실행합니다.

1.3 모든 클러스터는 최소 한 개 이상의 마스터 노드(컨트롤 플레인)와 워커 노드를 가집니다.

1.3.1 마스터 노드(컨트롤 플레인)

마스터 노드(컨트롤 플레인)는 클러스터를 관리하고 조율하며, 주요 컴포넌트로 Kube API Server, Scheduler, Controller Manager, etcd를 포함합니다.

1.3.2 워커 노드

워커 노드는 애플리케이션 워크로드를 실행합니다.

2. 클러스터 구성 요소

쿠버네티스 클러스터는 크게 컨트롤 플레인(Control Plane)과 노드(Node)라고 하는 두 영역으로 구성되어 있습니다.

2.1 컨트롤 플레인(Control Plane)

컨트롤 플레인은 클러스터를 관리하고 작업을 조율하는 핵심적인 역할을 합니다. 제어 영역이라고 할 수 있으며, 마스터 노드(Master Node)라고 부르기도 합니다.

2.1.1 컨트롤 플레인의 역할

컨트롤 플레인은 클러스터 상태를 관리하고 명령어를 처리하며, 애플리케이션이 원하는 상태를 유지하도록 조율합니다. 일반적으로 하나 이상의 마스터 노드로 구성되며, 다음 역할을 수행합니다.

  • 클러스터 상태를 지속적으로 모니터링하고 관리합니다.
  • 워커 노드에서 실행될 파드(Pod)의 배치를 결정합니다.
  • 클라이언트 요청을 처리하고 클러스터의 상태 데이터를 저장합니다.

2.1.2 컨트롤 플레인의 구성 요소

컨트롤 플레인은 여러 컴포넌트로 구성되며 각 컴포넌트는 클러스터 운영의 핵심 역할을 맡고 있습니다.
Kube API Server는 클라이언트 요청을 처리하며, Scheduler는 파드를 적절한 노드에 배치하고, Controller Manager는 클러스터 상태를 동기화하며, etcd는 모든 상태 데이터를 안전하게 저장합니다.

Kube API Server

  • 클러스터와의 모든 상호작용을 처리하는 진입점입니다.
  • 쿠버네티스 리소스와 클러스터의 상태 관리 및 동기화를 위한 API를 제공합니다.
  • 클라이언트(예: kubectl 명령어)와 통신하며, 클러스터의 상태를 관리합니다.
  • etcd에 데이터를 저장하며, 클러스터 전반의 상태를 조회하거나 업데이트하는 데 사용합니다.

Scheduler

  • 새롭게 생성된 파드를 감지하여 적절한 노드에 배치합니다.
  • 클러스터 내의 자원(CPU, 메모리 등)을 고려하여 최적의 노드를 선택하고 작업을 할당(클러스터 자원을 효율적으로 분배)합니다.

Controller Manager

  • 여러 컨트롤러 프로세스를 관리하는 중앙 관리자 역할을 합니다.
  • 클러스터 상태와 원하는 상태를 비교하여 필요한 작업(파드 재생성, 디플로이먼트 업데이트 등)을 수행합니다.
  • 크게 두 가지 매니저, Kube Controller ManagerCloud Controller Manager로 나뉩니다.
    • Kube Controller Manager:
      클러스터 내부 리소스(Pod, Deployment, Service 등)를 관리하고, API 서버와 주기적으로 통신하여 현재 클러스터 상태와 etcd에 저장된 리소스의 상태를 비교합니다. 만약, etcd 리소스 상태에 변화가 있다면 이를 현재 클러스터 리소스에 반영함으로써 동기화합니다. 이렇게 변화를 감지하고 동기화하는 반복되는 과정을 reconcile이라고 부릅니다.

      Reconcile은 현재 상태와 원하는 상태 간의 차이를 분석해 이를 동기화하는 작업을 의미합니다.

    • Cloud Controller Manager:
      대표적인 클라우드 제공자들(AWS, AZURE 등)과 통신하고, 클라우드 제공자와의 통합을 처리합니다. 각각의 클라우드 환경에 맞춘 컨트롤러가 배정되어 클라우드 제공자들의 종속적인 기능들(로드 밸런싱, 스토리지 관리, 노드 관리, IP 주소 및 네트워킹 등)을 클러스터에서 수행하는 역할을 합니다.

etcd

  • 분산 키-값 저장소로, 클러스터의 모든 상태 데이터를 저장합니다.
  • 데이터의 일관성을 보장하며, 클러스터 복구 시 필수적인 역할을 합니다.
  • 클러스터 상태를 백업하고 복구하기 위해 가장 중요한 컴포넌트입니다.

2.2 노드(Node)

노드는 클러스터에서 실제로 애플리케이션 워크로드를 실행하는 서버입니다. 애플리케이션 컨테이너를 실행하는 역할을 한다고 하여 워커 노드(Worker Node)라고 부르기도 합니다.

노드의 기본 역할은 Container Runtime 위에서 파드(Pod)를 실행하는 것입니다. 이외에도 노드에는 클러스터와 통신하고 파드의 상태를 관리하는 데 필요한 여러 시스템 컴포넌트(kubelet, kube-proxy, Network Add-on)가 실행됩니다.

2.2.1 노드의 역할

  • 파드를 실행하고 관리하며, 클러스터의 실제 작업을 처리합니다.
  • 컨트롤 플레인의 명령에 따라 애플리케이션을 배포합니다.
  • 클러스터의 리소스(CPU, 메모리 등)를 제공하여 작업을 수행합니다.

2.2.2 노드의 구성 요소

Kubelet

Kubelet은 모든 노드에 설치되는 핵심 컴포넌트로, API 서버와 통신하며 노드에서 실행 중인 파드(Pod)와 컨테이너의 상태를 관리합니다.

  • 역할:
    • 파드의 생성, 시작, 중지와 같은 컨테이너 라이프사이클을 관리합니다.
    • 노드의 리소스 상태(CPU, 메모리)를 API 서버에 주기적으로 보고합니다.
    • 컨테이너 런타임(Container Runtime)과 상호작용하여 파드 내부의 컨테이너를 실행하고 관리합니다.
  • 특징:
    • Kubelet은 노드가 클러스터 내에서 정상적으로 동작하며, 클러스터와 원활히 통신할 수 있도록 보장합니다. 또한, 노드에 실행되는 모든 파드와 컨테이너를 모니터링하고 제어합니다.

CRI(Container Runtime Interface)

Kubelet이 다양한 컨테이너 런타임과 상호작용할 수 있도록 쿠버네티스가 자체적으로 제공하는 표준 인터페이스입니다.

  • 역할:

    • Kubelet과 컨테이너 런타임 간의 통신을 처리하여, 특정 런타임(Docker, containerd 등)에 의존하지 않고도 컨테이너를 효율적으로 관리할 수 있습니다.
    • Docker 외에도 containerd, CRI-O와 같은 다양한 컨테이너 런타임을 지원합니다.
  • 특징:

    • Docker에 대한 의존성을 줄이기 위해 설계되었으며, 컨테이너 런타임이 CRI 표준을 따르기만 하면 Kubelet과 호환 가능합니다.

Kube-proxy

Kube-proxy는 쿠버네티스 클러스터의 네트워킹 컴포넌트로, 파드 간의 통신서비스 네트워크 트래픽을 관리합니다.

  • 역할:
    • 네트워크 프록시: 클로스터 내에서 실행 중인 파드와 서비스 간의 통신을 라우팅합니다.
    • 로드 밸런서: 동일한 서비스에 속한 여러 파드로 트래픽을 분배합니다.
    • 오버레이 네트워크 구성: 클러스터 상의 모든 파드가 서로 통신할 수 있도록 네트워크 규칙을 설정합니다.
  • 특징:
    • 클러스터 내 모든 노드에 배포되며, 네트워크 연결을 보장하는 중요한 역할을 합니다.

3. API 리소스와 오브젝트

쿠버네티스에서 모든 작업은 API 리소스와 오브젝트를 중심으로 이루어집니다.
API 리소스는 클러스터에서 관리되는 리소스의 종류를 정의하며, 오브젝트는 이 API 리소스를 구체화한 실제 인스턴스입니다.

3.1 API 리소스란?

API 리소스는 쿠버네티스가 관리할 수 있는 리소스의 설계도(템플릿)입니다.

  • 예를 들어, Pod, Service, Deployment, ConfigMap, Secret 등이 모두 API 리소스입니다.
  • 각 API 리소스는 쿠버네티스 API에서 제공하며, 클러스터에서 지원하는 모든 작업은 이 API 리소스를 기반으로 이루어집니다.

3.1.1 API 리소스의 주요 특징

1. 유형 정의

  • API 리소스는 쿠버네티스 클러스터에서 사용되는 리소스 유형을 정의합니다.
    • 예: Pod 리소스는 컨테이너화된 애플리케이션의 실행 단위를 정의합니다.
    • 예: Service 리소스는 네트워크 접근성을 제공합니다.

2. 명세화

  • API 리소스는 사용자가 원하는 리소스의 상태를 선언적으로 정의할 수 있습니다. 이를 통해 클러스터는 실제 상태와 원하는 상태를 비교하여 자동으로 동기화합니다.

3. 명령어 지원

  • kubectl api-resources 명령어를 사용하면 쿠버네티스 클러스터에서 지원하는 API 리소스 목록을 확인할 수 있습니다.

  • kubectl explain <리소스 이름> 명령어를 사용하면 특정 리소스의 상세 정보를 확인할 수 있습니다.

3.2 오브젝트란?

오브젝트는 API 리소스를 인스턴스화한 실제 객체를 의미합니다.
API 리소스가 설계도라면, 오브젝트는 이 설계도를 기반으로 클러스터에 생성된 구체적인 리소스입니다.

3.2.1 오브젝트의 주요 특징

1. 구성 요소

모든 오브젝트는 다음과 같은 기본 구성 요소를 가집니다:

  • apiVersion: 오브젝트가 속하는 API 그룹과 버전
  • kind: 생성하려는 API 리소스 유형 (예: Pod, Service 등)
  • metadata: 이름, 네임스페이스, 레이블 등 오브젝트를 식별하는 정보
  • spec: 오브젝트가 가져야 할 원하는 상태 (Desired State)

apiVersion, kind, metadata모든 쿠버네티스 오브젝트에 반드시 포함되는 루트 키입니다. 단, spec은 API 리소스 종류에 따라 다른 속성으로 대체되기도 합니다.

2. 생성과 관리

오브젝트는 YAML 또는 JSON 파일로 정의되며, kubectl apply 명령어로 클러스터에 적용할 수 있습니다.

  • 예: kubectl apply -f pod.yaml
  • 해당 명령어는 YAML 파일의 내용을 클러스터에 적용해 새로운 오브젝트를 생성하거나 기존 오브젝트를 업데이트합니다.

3. 클러스터 상태와 동기화

쿠버네티스는 사용자가 정의한 오브젝트의 상태를 클러스터에서 지속적으로 모니터링하고 동기화합니다.
예를 들어, 사용자가 3개의 Pod를 정의하면 클러스터는 항상 3개의 Pod가 실행되도록 보장합니다.

3.3 YAML 파일과 오브젝트

쿠버네티스에서 YAML 파일오브젝트를 정의하고 클러스터에 적용하는 데 사용되는 주요 수단입니다. YAML 파일을 통해 사용자는 쿠버네티스 리소스의 원하는 상태를 선언적으로 정의할 수 있습니다.

3.3.1 YAML 파일의 기본 구조

쿠버네티스 YAML 파일은 일반적으로 다음과 같은 기본 루트 키를 포함합니다.

1. apiVersion:

  • 리소스가 속하는 API 그룹과 버전을 지정합니다.
  • 예: v1, apps/v1
apiVersion: apps/v1

2. kind:

  • 생성하려는 리소스의 유형을 지정합니다.
  • 예: Pod, Service, Deployment
kind: Deployment

3. metadata

  • 리소스의 이름과 네임스페이스, 레이블 등 식별 정보를 포함합니다.
  • 예:
metadata:
  name: spring-server-pod
  namespace: default

4. spec:

  • 리소스의 원하는 상태를 정의합니다.
  • 예: Pod의 컨테이너 이미지, Service의 노출 방식 등을 명세합니다.
spec:
  containers:
    - name: spring-container # 컨테이너의 이름
      image: spring-server:1.0 # 사용할 Docker 이미지
      imagePullPolicy: IfNotPresent # 이미지 풀 정책, 이미지가 로컬에 없으면 레지스트리에서 원격으로 가져옴
      ports:
        - containerPort: 8080 # 컨테이너가 내부적으로 사용하는 포트(문서화)

3.3.2 예시: spring-deployment.yaml

# spring-deployment.yaml
apiVersion: apps/v1
kind: Deployment

metadata:
  name: spring-deployment # Deployment 이름, 클러스터 내에서 유일해야 함
  namespace: default

# Deployment의 세부 사항 정의
spec:
  replicas: 5 # 생성할 Pod(레플리카)의 개수 (5개의 Pod 생성)
  selector:
    matchLabels:
      app: backend-app # 이 Deployment가 관리할 Pod를 선택하는 기준 (라벨 매칭)

  # 생성할 Pod의 템플릿 정의
  template:
    metadata:
      labels:
        app: backend-app # 생성된 Pod에 추가할 라벨 (selector와 매칭)
    spec:
      containers:
        - name: spring-container # 컨테이너의 이름
          image: spring-server:1.0 # 사용할 Docker 이미지
          imagePullPolicy: IfNotPresent # 이미지 풀 정책, 이미지가 로컬에 없을 때만 새로 가져옴
          ports:
            - containerPort: 8080 # 컨테이너가 내부적으로 사용하는 포트
  • apiVersion
    • apps/v1은 Deployment 리소스의 API 버전을 나타냅니다.
  • kind
    • Deployment는 생성하려는 리소스가 Deployment임을 의미합니다.
  • metadata
    • name은 Deployment의 이름이고, namespace는 Deployment가 속할 네임스페이스를 지정합니다. 기본값은 default입니다.
  • spec
    • replicas:
      • 생성할 Pod(레플리카)의 개수를 지정합니다. 이 예제에서는 5개의 Pod가 생성됩니다.
      • Deployment는 지정된 개수의 Pod가 항상 실행되도록 보장합니다.
    • selector:
      • 이 Deployment가 관리할 Pod를 선택하는 기준을 정의합니다.
      • matchLabels 필드에 지정된 라벨(app: backend-app)을 가진 Pod를 선택합니다.
    • template:
      • Deployment가 생성할 Pod의 템플릿을 정의합니다.
      • Pod 템플릿은 metadataspec으로 구성됩니다.
  • template.metadata
    • 생성된 Pod에 추가할 라벨을 정의합니다.
    • 이 예제에서는 app: backend-app 라벨이 추가됩니다. 이 라벨은 selector와 일치해야 합니다.
  • template.spec
    • containers: Pod에 포함될 컨테이너를 정의합니다.
      • name: 컨테이너의 이름
      • image: 컨테이너에서 실행될 Docker 이미지
      • imagePullPolicy:
        • Docker 이미지를 가져오는 정책을 지정합니다.
        • IfNotPresent: 로컬에 이미지가 없을 때만 새로 가져옵니다.
      • ports:
        • 컨테이너가 사용하는 네트워크 포트를 정의합니다.
        • 이 예제에서는 컨테이너 내부적으로 8080 포트를 사용합니다.

예시 작동 방식 설명:

  1. Deployment는 클러스터 내에서 5개의 Pod를 생성합니다.
  2. 생성된 Pod는 spring-server:1.0 이미지를 기반으로 실행됩니다.
  3. selectortemplate.metadata.labels가 일치하도록 Pod가 생성되어 Deployment가 해당 Pod를 관리할 수 있습니다.
  4. Deployment는 Pod가 중단되거나 삭제되더라도 항상 5개의 Pod가 실행되도록 상태를 유지합니다.

3.3.3 YAML 파일을 클러스터에 적용

1. YAML 파일 생성

위와 같은 YAML 파일을 spring-server.yaml이라는 이름으로 저장합니다.

2. kubectl 명령어로 적용

kubectl apply 명령어를 사용하여 클러스터에 YAML 파일을 적용합니다.

$ kubectl apply -f spring-server.yaml

3. 적용 결과 확인

Pod가 정상적으로 생성되었는지 확인합니다.

$ kubectl get pod my-pod

4. YAML 파일 수정 및 업데이트

YAML 파일을 수정한 후, 동일한 kubectl apply 명령어를 실행하면 리소스가 업데이트됩니다.

profile
donggyun_ee

0개의 댓글