[쿠버네티스] 쿠버네티스의 노드란? + 각 노드의 주요 구성, 흐름도
쿠버네티스 아키텍처는 컨테이너화된 워크로드를 안정적이고 적응 가능한 환경을 제공하기 위해, 여러 서버와 클러스터에 분산된 컴포넌트들이 함께 동작하는 집합입니다.
쿠버네티스 노드는 크게 2가지로 구분됩니다.
- 마스터 노드
- 워커 노드
쿠버네티스의 전체적인 구성도는 다음과 같습니다.
마스터 노드
쿠버네티스의 클러스터 전체를 관리하는 역할을 담당합니다. 여러 대로 이루어진 클러스터 안의 노드의 리소스 사용 상황을 확인하고 컨테이너를 가동할 노드를 자동으로 선택합니다.
마스터 노드의 주요 구성
- etcd: 고가용성을 갖춘 분산 key-value 스토어
- kube-apiserver: Kubernetes API를 노출하는 컴포넌트 kubectl로부터 리소스를 조작하라는 지시를 받음
- kube-scheduler: 노드를 모니터링하고 컨테이너를 배치할 적절한 노드를 선택
- kube-controller-manager: 리소스를 제어하는 컨트롤러를 실행
kube-apiserver
쿠버네티스 클러스터의 중앙 집중식 진입점(API 게이트웨이) 역할
- 중앙 통신 허브:이를 통해 클러스터 내부의 컴포넌트들이 일관된 방식으로 상호작용할 수 있습니다.
- 모든 클러스터 구성 요소(노드, 파드, 서비스 등)와 사용자 또는 외부 애플리케이션의 요청은 kube-apiserver를 통해 전달됩니다.
- RESTful API 제공:사용자는 kubectl이나 다른 클라이언트를 통해 API 서버에 명령을 전송합니다.
- kube-apiserver는 RESTful 인터페이스를 제공하여 클러스터 리소스의 생성, 읽기, 업데이트, 삭제(CRUD) 작업을 수행할 수 있게 합니다.
- 상태 관리: 클러스터의 현재 상태와 원하는 상태에 대한 정보를 etcd와 같은 백엔드 데이터 스토어에 저장하고, 이를 기반으로 클러스터 전반의 상태를 유지합니다.
요약하면, kube-apiserver는 쿠버네티스 클러스터의 "뇌" 역할을 하며, 모든 요청의 중앙 통제와 클러스터 상태 관리 등의 핵심 기능을 수행합니다.
etcd
etcd는 분산 키-값 저장소(distributed key-value store)로, 쿠버네티스 클러스터의 중요한 상태 정보와 구성 데이터를 영속적으로 저장하는 역할을 합니다.
- 클러스터 상태 저장소:
- 쿠버네티스의 모든 상태 정보(예: 파드, 서비스, 노드, 설정 등)가 etcd에 저장되며, 클러스터의 현재 상태와 원하는 상태를 관리하는 기준 데이터로 사용됩니다.
- 분산 및 고가용성:
- etcd는 분산 시스템으로 설계되어, 여러 노드에 데이터가 복제되므로 하나의 노드에 문제가 발생해도 데이터의 일관성과 가용성을 유지할 수 있습니다.
- 강력한 일관성:
- etcd는 분산 환경에서도 데이터의 일관성을 보장하기 위해 Raft 알고리즘을 사용합니다. 이를 통해 모든 클라이언트가 동일한 최신 데이터를 조회할 수 있도록 합니다.
- 빠른 읽기/쓰기 성능:
- 경량화된 설계와 효율적인 프로토콜 덕분에 빠른 읽기 및 쓰기 성능을 제공하며, 쿠버네티스의 실시간 클러스터 상태 변경에 신속하게 대응할 수 있습니다.
- 보안:
- 오직 kube-apiserver에서만 접근할 수 있습니다.
요약하면, etcd는 쿠버네티스 클러스터의 "데이터 뱅크" 역할을 하며, 클러스터의 모든 중요한 상태와 구성을 안전하고 일관되게 저장하는 핵심 컴포넌트입니다.
kube-scheduler
kube-scheduler는 쿠버네티스 클러스터에서 새로운 파드를 워커 노드에 배치하는 역할을 담당합니다.
- 파드 스케줄링:
- 클러스터 내에 아직 노드에 할당되지 않은 파드를 감지하고, 해당 파드의 요구 사항(리소스, 라벨, 제약 조건 등)을 고려하여 가장 적합한 노드를 선택합니다.
- 리소스 및 제약 조건 고려:
- 각 노드의 CPU, 메모리 등 리소스 사용 상황을 평가하고, 파드가 원활하게 실행될 수 있도록 리소스가 충분한 노드를 할당합니다.
- 또한, 노드 간의 Affinity/Anti-Affinity, Taints/Tolerations, 노드 셀렉터 등의 제약 조건을 검토하여 적합한 노드를 결정합니다.
- 클러스터 부하 분산:
- 클러스터 전체의 부하와 리소스 활용률을 고려하여 파드를 분산 배치함으로써, 특정 노드에 부하가 집중되지 않도록 합니다.
- 결과 반영:
- 선택한 노드 정보를 API 서버에 전달하여 파드 스케줄링을 완료하고, 이후 kubelet이 해당 노드에서 파드를 실행하도록 합니다.
요약하면, kube-scheduler는 쿠버네티스 클러스터의 리소스와 제약 조건을 기반으로 파드를 적절한 노드에 배치하여, 클러스터의 효율적인 운영과 안정성을 보장하는 중요한 역할을 수행합니다.
kube-controller-manager
kube-controller-manager는 쿠버네티스 클러스터의 원하는 상태(desired state)를 유지하기 위해 여러 컨트롤러(제어 루프)를 실행하는 핵심 컴포넌트입니다. 주요 역할은 다음과 같습니다:
- 상태 유지:
- 클러스터의 상태를 지속적으로 모니터링하며, 실제 상태(actual state)와 원하는 상태(desired state) 간의 차이가 발생하면 이를 수정하는 작업을 수행합니다.
- 다양한 컨트롤러 실행:
- 노드 컨트롤러: 노드의 상태를 감시하고, 장애 노드를 감지하여 적절한 조치를 취합니다.
- 레플리케이션 컨트롤러/레플리카셋 컨트롤러: 지정된 수의 파드가 항상 실행되도록 보장하여, 만약 파드가 종료되면 새로운 파드를 생성합니다.
- 엔드포인트 컨트롤러: 서비스와 파드 간의 연결 정보를 관리합니다.
- 서비스 계정 컨트롤러: 클러스터 내에서 서비스 계정과 관련 토큰을 자동으로 생성 및 관리합니다.
- 여러 컨트롤러가 하나의 프로세스로 함께 동작합니다. 대표적인 컨트롤러는 다음과 같습니다:
- 자동화된 복구 및 관리:
- 클러스터 내의 다양한 리소스들이 항상 설정된 원하는 상태를 유지하도록 자동화된 작업(예: 파드 재생성, 노드 상태 업데이트 등)을 수행합니다.
요약하면, kube-controller-manager는 쿠버네티스 클러스터의 '자동 복구 관리자'라고 할 수 있으며, 여러 컨트롤러를 통해 클러스터 리소스의 상태를 지속적으로 감시하고, 필요한 변경 사항을 자동으로 적용하여 클러스터의 안정성을 보장합니다.
워커 노드
마스터에 의해 명령을 받고 실제 워크 로드를 생성해서 서비스하는 컴포넌트
API 서버의 요청을 Kubelet을 통해 수행
워커 노드 주요 구성
- kubelet
- kube-proxy
- cAdvisor
kubelet
kubelet은 쿠버네티스 클러스터의 각 워커 노드에서 실행되는 에이전트
- 파드와 컨테이너 관리: kubelet은 컨트롤 플레인에서 내려준 파드 사양(PodSpec)을 기반으로 해당 노드에서 컨테이너를 생성, 시작, 중지하는 작업을 담당합니다.
- 상태 보고: 노드와 파드의 상태 정보를 주기적으로 컨트롤 플레인(API 서버)에 보고하여 클러스터 전체의 상태를 모니터링할 수 있도록 합니다.
- 컨테이너 런타임과의 연동: Docker, containerd 등과 같은 컨테이너 런타임과 상호작용하여 컨테이너의 실행 및 관리 작업을 수행합니다.
- 헬스 체크 및 자가 복구: 컨테이너의 상태를 지속적으로 체크하여 문제가 발생할 경우 재시작하는 등의 복구 작업을 진행합니다.
kube-proxy
kube-proxy는 쿠버네티스 클러스터 내에서 네트워킹과 로드밸런싱 역할을 담당
- 서비스 트래픽 라우팅: 클러스터 내에서 생성된 서비스(Service)가 가상 IP(ClusterIP)를 통해 접근될 때, 해당 트래픽을 실제로 요청을 처리할 파드(백엔드 엔드포인트)로 라우팅합니다.
- 네트워크 프록시 기능: 각 워커 노드에서 실행되며, 서비스에 대한 접근 요청을 감지하고 이를 적절한 파드로 전달합니다. 이를 위해 iptables, IPVS 등 다양한 기술을 활용합니다.
- 로드 밸런싱: 여러 파드가 동일한 서비스의 백엔드로 존재할 경우, 들어오는 트래픽을 분산시켜 부하를 균등하게 분배합니다.
즉, kube-proxy는 클러스터 내의 네트워크 통신이 원활하게 이루어지도록 도와주며, 서비스와 파드 간의 연결 및 로드 밸런싱을 관리하는 중요한 역할을 수행합니다.
cAdvisor
cAdvisor (Container Advisor) 는 실행 중인 컨테이너들의 리소스 사용량과 성능 지표를 모니터링하는 데 중요한 역할을 합니다.
- 노드 내부 컨테이너 모니터링: 워커 노드에 있는 cAdvisor는 해당 노드에서 실행 중인 모든 컨테이너의 CPU, 메모리, 네트워크, 파일 시스템 등의 리소스 사용량을 실시간으로 수집합니다.
- 데이터 수집 및 제공: 수집된 메트릭은 로컬 웹 UI나 API를 통해 제공되며, 이를 통해 운영자는 각 컨테이너의 상태를 모니터링하고, 리소스 사용 패턴을 분석할 수 있습니다.
- kubelet과의 통합: cAdvisor는 kubelet 내부에 통합되어 실행되는 경우가 많아, kubelet은 수집된 메트릭을 API 서버로 전달하거나, 클러스터 수준의 모니터링 시스템(Prometheus 등)과 연동할 수 있도록 합니다.
- 성능 분석 및 문제 탐지: 워커 노드의 cAdvisor를 통해 컨테이너별로 리소스 사용량의 급증이나 이상 징후를 감지하여, 성능 병목 현상이나 시스템 문제를 조기에 파악할 수 있습니다.
요약하면, 쿠버네티스 워커 노드의 cAdvisor는 해당 노드에서 실행 중인 컨테이너들의 리소스 사용과 성능을 모니터링하여, 클러스터의 효율적인 운영과 문제 해결에 기여하는 중요한 컴포넌트입니다.
흐름도
❓ 사용자가 새로운 Nginx Pod을 생성할 때, 어떤 과정을 통해 생길까?
- 사용자 요청 및 API 서버 전달
- 사용자가 kubectl apply 또는 kubectl create 명령어로 nginx Pod의 YAML 파일을 제출하면, 이 요청은 kubectl을 통해 kube-apiserver에 전달됩니다.
- API 서버는 요청을 인증, 인가 및 검증한 후, nginx Pod의 정의(스펙)를 etcd에 저장하여 클러스터의 상태 변경을 기록합니다.
- Pod 생성 및 상태 변경
- etcd에 새로운 nginx Pod의 정의가 저장되면, 쿠버네티스 클러스터의 각 구성 요소들이 이 변화를 감지합니다.
- 만약 이 Pod가 Deployment나 ReplicaSet의 일부로 생성된다면, 해당 컨트롤러(예: Deployment 컨트롤러)가 원하는 복제 수와 실제 상태를 맞추기 위해 Pod 생성 요청을 관리합니다.
- 스케줄링
- kube-scheduler는 아직 노드에 할당되지 않은 nginx Pod를 감지하고, 클러스터 내의 각 워커 노드의 리소스 상황 및 스케줄링 제약 조건(라벨, affinity, taints 등)을 고려하여 적절한 노드를 선택합니다.
- 선택된 노드 정보는 API 서버를 통해 Pod 스펙에 업데이트됩니다.
- Pod 실행
- 스케줄링이 완료되면, 선택된 워커 노드의 kubelet이 해당 Pod의 스펙을 받아 실행 준비를 시작합니다.
- kubelet은 지정된 컨테이너 런타임(Docker, containerd 등)과 상호작용하여 nginx 이미지를 로컬에 pull하고, 컨테이너를 생성 및 실행합니다.
- 동시에 cAdvisor(통합되어 있거나 별도로 실행되는 경우)는 이 컨테이너의 리소스 사용량을 모니터링합니다.
- 건강 상태 확인
- Pod 내에 liveness 및 readiness 프로브가 설정되어 있다면, kubelet이 주기적으로 컨테이너의 상태를 체크합니다.
- readiness 프로브가 성공하면, nginx Pod는 서비스의 엔드포인트로 등록되어 트래픽을 받을 준비가 됩니다.
- 클러스터 상태 업데이트
- 실행 중인 Pod의 상태 정보는 kubelet이 주기적으로 kube-apiserver에 보고하고, 이를 통해 etcd에 최신 상태가 반영됩니다.
- 클러스터의 다른 컨트롤러나 모니터링 도구도 이 상태 정보를 활용하여 클러스터 전반의 상태를 관리합니다.
❓ 워커 노드에 있는 pod 하나가 정상적인 역할을 하지 못할 때 어떤 일들이 일어날까?
- Pod 내부에서 상태 감지
- Pod 내 컨테이너에 설정된 liveness 또는 readiness 프로브가 실패하면, 해당 컨테이너가 제대로 동작하지 않고 있음을 kubelet이 감지합니다.
- 컨테이너 런타임의 상태:Docker나 containerd와 같은 런타임도 컨테이너의 상태(크래시, 메모리 누수 등)를 감지합니다.
- kubelet의 상태 보고
- 워커 노드의 kubelet은 감지한 Pod의 이상 상태 정보를 정기적으로 kube-apiserver에 보고합니다.
- 보고된 상태에는 Pod의 현재 상태(예: CrashLoopBackOff, Unhealthy 등)와 노드의 상태 정보가 포함됩니다.
- API 서버를 통한 상태 갱신
- kube-apiserver는 kubelet으로부터 전달받은 정보를 바탕으로 클러스터의 상태를 업데이트합니다.
- 이때, etcd에 저장된 상태 정보도 함께 갱신되어 쿠버네티스의 "단일 원천(Source of Truth)"이 최신 상태를 반영합니다.
- 컨트롤러의 개입
- 만약 해당 Pod가 Deployment나 ReplicaSet에 의해 관리되고 있다면, 컨트롤러는 지정된 원하는 Pod 수와 실제 실행 중인 Pod 수를 비교합니다.
- Pod 하나가 비정상 상태로 판단되면, 컨트롤러는 이를 '실패' 또는 '종료'된 것으로 간주하고, 새로운 Pod를 생성하여 원하는 상태를 맞추려 시도합니다.
- 만약 문제의 원인이 노드 자체에 있다면, 노드 컨트롤러가 해당 노드를 불안정한 상태로 표시하여, 새로운 스케줄링 시 다른 노드에 Pod를 할당할 수 있도록 합니다.
- 만약 해당 Pod가 Deployment나 ReplicaSet에 의해 관리되고 있다면, 컨트롤러는 지정된 원하는 Pod 수와 실제 실행 중인 Pod 수를 비교합니다.
- 새로운 Pod의 스케줄링 및 실행
- 새로운 Pod가 생성되면, kube-scheduler가 클러스터 내의 적절한 워커 노드를 선택하여 스케줄링합니다.
- 선택된 노드의 kubelet은 새로 생성된 Pod를 받아 컨테이너 런타임을 통해 실행합니다.
- 모니터링 및 반복
- 복구된 Pod의 상태도 지속적으로 liveness 및 readiness 프로브를 통해 모니터링되며, 정상 동작 여부가 확인되면 클러스터는 원하는 상태를 유지합니다.
참고:
https://pearlluck.tistory.com/136
https://www.youtube.com/playlist?list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c
[따배쿠] 쿠버네티스 시리즈
www.youtube.com