Kubernetes and Cloud Native Associate (KCNA) #2 Kubernetes Fundamentals 1: 아키텍처와 핵심 리소스
#1에서 시험 구조를 잡았으니, 이번 글부터는 출제 범위로 들어갑니다. 첫 도착지는 Kubernetes Fundamentals입니다. 이 도메인 하나가 KCNA 출제 비중의 **46%**로 거의 절반을 차지하므로, 여기서 점수를 확보하면 합격선의 절반을 채우는 셈입니다. 분량이 큰 만큼 두 편으로 나누어, 이번 #2에서는 클러스터 아키텍처와 핵심 리소스를, 다음 #3에서는 API,컨테이너,스케줄링을 다루겠습니다.
이 글이 묻는 핵심은 단순합니다. 쿠버네티스 클러스터가 어떤 부품으로 이루어져 있고, 각 부품이 무슨 일을 하는가, 그리고 어떤 리소스가 어떤 문제를 푸는가입니다. KCNA는 이 두 가지를 역할 매칭 형태로 집요하게 묻습니다.
클러스터의 큰 그림: control plane과 worker node #
쿠버네티스 클러스터는 두 종류의 노드로 나뉩니다. control plane은 클러스터 전체의 두뇌이고, worker node는 실제로 컨테이너(Pod)를 돌리는 일꾼입니다. 이 역할 분담이 Domain 1의 출발점이며, KCNA는 “어떤 컴포넌트가 control plane에 있고 어떤 컴포넌트가 worker node에 있는가"를 자주 묻습니다.
| 구분 | 위치 | 하는 일 |
|---|---|---|
| control plane | 관리 노드 | 클러스터의 desired state를 결정하고 유지. 사용자 요청 처리, 스케줄링, 상태 조정 |
| worker node | 작업 노드 | control plane의 결정에 따라 실제 Pod를 실행하고 네트워크를 연결 |
작은 클러스터에서는 control plane과 worker가 한 노드에 함께 있을 수 있지만, 프로덕션에서는 control plane을 별도 노드로 분리하고 여러 대로 다중화해 가용성을 높입니다. 실무 트랙 #1에서 minikube로 띄운 단일 노드 클러스터도 내부적으로는 이 두 역할을 모두 한 노드에서 수행한 것입니다.
Control plane 구성 요소 #
control plane은 단일 프로그램이 아니라 여러 컴포넌트의 묶음입니다. 각 컴포넌트의 역할을 한 줄로 분류할 수 있어야 합니다.
kube-apiserver: 모든 통신의 관문 #
kube-apiserver는 클러스터의 정문입니다. kubectl, 컨트롤러, kubelet 등 모든 구성 요소는 서로 직접 대화하지 않고 반드시 apiserver를 거쳐 통신합니다. apiserver는 REST API를 노출하고, 들어온 요청을 인증,인가,검증한 뒤 클러스터 상태 저장소에 기록합니다. apiserver는 클러스터에서 유일하게 etcd에 직접 접근하는 컴포넌트이기도 합니다.
etcd: 클러스터 상태 저장소 #
etcd는 클러스터의 모든 상태를 담는 key-value 저장소입니다. 어떤 Pod가 어디에 떠 있는지, 어떤 Deployment가 몇 개의 복제본을 원하는지 같은 클러스터의 desired state와 current state가 전부 etcd에 들어 있습니다. etcd는 분산 합의 알고리즘(Raft)으로 일관성을 보장하며, etcd가 손상되면 클러스터의 기억 전체가 사라지므로 백업이 운영의 핵심입니다.
kube-scheduler: Pod 배치 결정 #
kube-scheduler는 아직 노드에 배정되지 않은 새 Pod를 보고, 어느 worker node에 올릴지를 결정합니다. 노드의 가용 자원(CPU,메모리), 노드 셀렉터, affinity,anti-affinity, taint,toleration 같은 제약을 종합해 최적의 노드를 고릅니다. scheduler는 배치를 결정할 뿐, 실제 실행은 해당 노드의 kubelet이 담당합니다.
kube-controller-manager: reconciliation loop #
kube-controller-manager는 여러 컨트롤러를 한 프로세스로 묶어 돌리는 컴포넌트입니다. 각 컨트롤러는 desired state와 current state를 끊임없이 비교하고, 둘이 어긋나면 현재 상태를 원하는 상태에 맞추는 reconciliation loop를 실행합니다. 예를 들어 ReplicaSet 컨트롤러는 “복제본 3개"라는 선언과 실제 떠 있는 Pod 수를 비교해, 모자라면 새로 만들고 남으면 제거합니다.
cloud-controller-manager: 클라우드 연동 #
cloud-controller-manager는 쿠버네티스를 특정 클라우드 제공자(AWS,GCP,Azure 등)와 이어주는 컴포넌트입니다. LoadBalancer 타입 Service를 위한 클라우드 로드밸런서 생성, 노드 생명주기 관리, 클라우드 스토리지 연동 같은 클라우드 종속 로직을 본체에서 분리해 담당합니다. 온프레미스 클러스터에서는 사용하지 않을 수 있습니다.
컴포넌트가 죽으면 무슨 일이 생기는가 #
KCNA가 좋아하는 각도입니다. 컴포넌트별 장애 영향을 알면 역할을 거꾸로 확인할 수 있습니다.
| 컴포넌트 | 장애 시 영향 |
|---|---|
| kube-apiserver | 모든 통신 중단. kubectl 명령,신규 배포,상태 조회 불가. 단 이미 떠 있는 Pod는 계속 실행 |
| etcd | 클러스터 상태 읽기,쓰기 불가. apiserver가 사실상 마비. 데이터 손상 시 복구가 가장 치명적 |
| kube-scheduler | 신규 Pod가 노드에 배정되지 못하고 Pending에 머무름. 기존 Pod는 영향 없음 |
| kube-controller-manager | reconciliation 중단. 장애 노드의 Pod 재생성,복제본 보정 등이 멈춤 |
| kubelet (worker) | 해당 노드의 Pod가 관리되지 않음. 노드가 NotReady로 표시되고 Pod가 다른 노드로 옮겨질 수 있음 |
핵심은 control plane이 멈춰도 이미 실행 중인 Pod는 당장 죽지 않는다는 점입니다. control plane은 변경과 조정을 담당하므로, 멈추면 새 작업이 막힐 뿐 기존 작업은 한동안 굴러갑니다.
Worker node 구성 요소 #
worker node는 control plane의 결정을 받아 실제 컨테이너를 실행합니다. 세 가지 구성 요소를 기억하면 됩니다.
kubelet: 노드 에이전트 #
kubelet은 각 worker node에서 돌아가는 에이전트입니다. apiserver로부터 “이 노드에 이런 Pod를 띄워라"라는 지시를 받아, 컨테이너 런타임에 실행을 요청하고 Pod가 정상인지 지속적으로 보고합니다. liveness,readiness probe를 실행해 컨테이너 건강 상태를 점검하는 것도 kubelet의 일입니다. kubelet은 노드 위 Pod의 실행을 보장하는 책임자입니다.
kube-proxy: Service 네트워킹 #
kube-proxy는 각 노드에서 Service 네트워킹을 구현합니다. Service로 들어온 트래픽을 뒤에 있는 Pod들로 분산하기 위해, 노드의 iptables(또는 IPVS) 규칙을 관리합니다. 덕분에 클라이언트는 개별 Pod의 IP를 몰라도 Service의 안정적인 가상 IP로 요청을 보낼 수 있습니다. 실제 패킷 전달은 커널의 규칙이 처리하고, kube-proxy는 그 규칙을 최신 상태로 유지합니다.
컨테이너 런타임: 실제 컨테이너 실행 #
컨테이너 런타임은 이미지를 내려받아 컨테이너를 실제로 띄우는 소프트웨어입니다. 오늘날 표준은 containerd이며, CRI-O도 널리 쓰입니다. kubelet은 이 런타임들과 **CRI(Container Runtime Interface)**라는 표준 인터페이스로 대화하므로, 런타임을 교체해도 kubelet 쪽 코드는 그대로입니다. CRI,런타임의 상세는 Domain 2를 다루는 #4에서 더 파고들겠습니다.
선언형 모델: 원하는 상태를 선언하면 맞춰진다 #
쿠버네티스를 관통하는 사상이 선언형(declarative) 모델입니다. 사용자는 “이 작업을 이렇게 하라"라는 명령 절차를 일일이 지시하지 않습니다. 대신 “최종적으로 이런 상태이기를 원한다"라는 desired state를 YAML 매니페스트로 선언하고, 쿠버네티스가 알아서 그 상태로 맞춥니다.
- desired state. 사용자가 원하는 상태. 예: “nginx Pod 3개가 항상 떠 있어야 한다”
- current state. 지금 실제 클러스터의 상태. 예: “현재 nginx Pod가 2개 떠 있다”
- reconciliation loop. 컨트롤러가 둘을 끊임없이 비교해, 차이가 있으면 current를 desired에 맞추는 과정. 위 예에서는 부족한 1개를 새로 생성
이 모델 덕분에 노드가 죽어 Pod가 사라져도 컨트롤러가 차이를 감지해 다른 노드에 Pod를 다시 띄웁니다. 사용자가 복구 절차를 명령하지 않아도 시스템이 스스로 원하는 상태로 돌아오는 자가 치유가 여기서 나옵니다. 명령형(imperative)으로 kubectl run을 직접 칠 수도 있지만, 실무와 시험 모두 선언형 매니페스트를 기준으로 삼습니다.
핵심 워크로드 리소스 #
이제 무엇을 선언하는지로 넘어갑니다. 워크로드 리소스는 계층 구조를 이루며, 위로 갈수록 더 많은 일을 자동으로 처리합니다.
Pod: 최소 배포 단위 #
Pod는 쿠버네티스가 배포하고 스케줄링하는 최소 단위입니다. 컨테이너를 직접 노드에 띄우는 것이 아니라, 항상 Pod라는 껍데기 안에 담아 띄웁니다. 하나의 Pod 안에는 컨테이너가 하나 이상 들어갈 수 있으며, 같은 Pod 안의 컨테이너들은 네트워크(같은 IP)와 스토리지 볼륨을 공유합니다. 보조 컨테이너를 함께 두는 사이드카 패턴이 이 구조 위에서 동작합니다.
다만 Pod를 직접 만들어 운영하는 일은 드뭅니다. Pod 하나만 띄우면, 그 Pod가 죽었을 때 아무도 다시 살려주지 않기 때문입니다. 그래서 보통은 상위 리소스가 Pod를 대신 관리합니다.
ReplicaSet: 복제본 수 유지 #
ReplicaSet은 지정한 개수의 동일한 Pod가 항상 떠 있도록 보장하는 리소스입니다. “복제본 3개"를 선언하면 ReplicaSet 컨트롤러가 reconciliation loop로 Pod 수를 감시해, 하나가 죽으면 새로 만들고 의도치 않게 늘어나면 제거합니다. ReplicaSet은 label selector로 자신이 관리할 Pod를 식별합니다.
Deployment: ReplicaSet 관리 + 롤링 업데이트 #
Deployment는 ReplicaSet을 한 단계 위에서 관리하는 리소스이며, 실무에서 가장 많이 쓰는 워크로드 리소스입니다. 복제본 유지는 ReplicaSet에 위임하고, 그 위에 버전 관리 기능을 더합니다. 새 이미지로 업데이트하면 Deployment가 새 ReplicaSet을 만들어 Pod를 점진적으로 교체하는 롤링 업데이트를 수행하고, 문제가 생기면 이전 ReplicaSet으로 되돌리는 롤백도 지원합니다.
ReplicaSet vs Deployment #
KCNA가 즐겨 묻는 비교입니다. 둘의 경계를 명확히 해 두어야 합니다.
| 리소스 | 책임 | 직접 사용 |
|---|---|---|
| ReplicaSet | 복제본 수 유지(스케일 보장) | 거의 직접 쓰지 않음. Deployment가 내부적으로 생성,관리 |
| Deployment | ReplicaSet 관리 + 롤링 업데이트,롤백,버전 이력 | 실무 표준. 무상태 워크로드 배포에 사용 |
한 문장으로 정리하면, Deployment는 ReplicaSet을 관리하고 ReplicaSet은 Pod를 관리합니다. 업데이트와 롤백이 필요하면 Deployment, 단순 복제본 보장만 보면 ReplicaSet입니다. 무상태가 아니라 안정적 식별자와 순서가 필요한 워크로드는 StatefulSet을 쓰지만, 이 비교는 #3에서 다루겠습니다. Deployment의 실습은 실무 트랙 #4에서 확인할 수 있습니다.
Service: Pod 집합의 안정적 진입점 #
Pod는 죽고 다시 태어날 때마다 IP가 바뀝니다. 그래서 Pod의 IP를 직접 가리키면 통신이 금세 끊깁니다. Service는 여러 Pod 앞에 변하지 않는 가상 IP와 DNS 이름을 두어, 뒤의 Pod가 바뀌어도 클라이언트가 같은 주소로 접근하게 해 주는 리소스입니다. Service는 label selector로 자신이 트래픽을 보낼 Pod 집합을 식별하고, 그 Pod들로 요청을 분산합니다.
Service에는 노출 범위에 따라 세 가지 주요 타입이 있습니다.
- ClusterIP. 클러스터 내부에서만 접근 가능한 기본 타입. 내부 서비스 간 통신에 사용
- NodePort. 각 노드의 특정 포트를 열어 클러스터 외부에서 노드 IP로 접근하게 함
- LoadBalancer. 클라우드 제공자의 외부 로드밸런서를 붙여 인터넷에 노출. cloud-controller-manager가 실제 LB를 생성
Service 타입의 차이도 자주 출제됩니다. 내부 전용이면 ClusterIP, 외부 노출이면 NodePort 혹은 LoadBalancer로 분류해 두면 됩니다. Service의 실습은 실무 트랙 #5에 정리되어 있습니다.
Namespace와 label/selector #
Namespace: 클러스터의 논리 분할 #
Namespace는 하나의 물리 클러스터를 여러 논리 공간으로 나누는 리소스입니다. 팀별,환경별(dev,staging,prod)로 리소스를 격리하고, 같은 이름의 리소스를 서로 다른 Namespace에 둘 수 있게 합니다. ResourceQuota,RBAC을 Namespace 단위로 걸어 자원과 권한을 분리하기도 합니다. kube-system 같은 기본 Namespace에는 쿠버네티스 자체 구성 요소가 들어 있습니다. 다만 Namespace는 어디까지나 논리적 구획이며, 노드 같은 클러스터 전역 리소스는 Namespace에 속하지 않습니다.
label과 selector: 라벨 기반 그룹핑 #
label은 리소스에 붙이는 key-value 꼬리표이며(예: app=nginx, env=prod), selector는 그 라벨로 리소스 집합을 골라내는 질의입니다. 쿠버네티스의 연결은 대부분 이 라벨 기반으로 이루어집니다. ReplicaSet이 관리할 Pod를 고를 때도, Service가 트래픽을 보낼 Pod를 고를 때도 모두 selector가 라벨을 보고 대상을 묶습니다. 이름이 아니라 라벨로 느슨하게 연결하는 이 방식이 쿠버네티스의 유연성을 만듭니다.
시험 포인트: 컴포넌트 역할 매칭 #
Domain 1에서 가장 자주 나오는 형태가 “이 일을 하는 컴포넌트는 무엇인가” 또는 **“이 컴포넌트의 역할은 무엇인가”**를 묻는 매칭 문항입니다. 아래 한 줄 요약을 외워 두면 상당수 문항이 풀립니다.
| 컴포넌트 / 리소스 | 한 줄 역할 |
|---|---|
| kube-apiserver | 모든 통신의 관문. 유일하게 etcd에 직접 접근 |
| etcd | 클러스터 상태를 담는 key-value 저장소 |
| kube-scheduler | 새 Pod를 어느 노드에 올릴지 결정 |
| kube-controller-manager | desired와 current를 맞추는 reconciliation loop |
| cloud-controller-manager | 클라우드 제공자 연동(LB,노드,스토리지) |
| kubelet | 노드 에이전트. Pod 실행 보장과 상태 보고 |
| kube-proxy | Service 네트워킹(iptables/IPVS) 구현 |
| 컨테이너 런타임 | 이미지를 받아 컨테이너를 실제로 실행(containerd) |
| Pod | 최소 배포 단위. 컨테이너 하나 이상을 담는 껍데기 |
| ReplicaSet | 복제본 수 유지 |
| Deployment | ReplicaSet 관리 + 롤링 업데이트,롤백 |
| Service | Pod 집합의 안정적 진입점. label selector로 연결 |
| Namespace | 클러스터의 논리 분할 |
정리 #
이번 글에서 잡은 것:
- 클러스터는 control plane(두뇌)과 worker node(일꾼)로 나뉜다. 어떤 컴포넌트가 어느 쪽에 있는지가 시험 포인트
- control plane. kube-apiserver(관문), etcd(상태 저장소), kube-scheduler(배치 결정), kube-controller-manager(reconciliation), cloud-controller-manager(클라우드 연동)
- worker node. kubelet(노드 에이전트), kube-proxy(Service 네트워킹), 컨테이너 런타임(containerd)
- 선언형 모델. desired state를 선언하면 reconciliation loop가 current state를 맞춘다. 자가 치유의 근거
- 워크로드 계층. Deployment가 ReplicaSet을 관리하고 ReplicaSet이 Pod를 관리. 업데이트,롤백이 필요하면 Deployment
- Service는 label selector로 Pod 집합에 안정적 진입점을 제공(ClusterIP,NodePort,LoadBalancer), Namespace는 클러스터를 논리적으로 나눈다
다음: Kubernetes Fundamentals 2 #
아키텍처와 핵심 리소스를 잡았으니, 이제 그 위에서 동작하는 메커니즘으로 들어갑니다.
#3 Kubernetes Fundamentals 2: API, 컨테이너, 스케줄링에서는 쿠버네티스 API와 오브젝트 구조, 컨테이너와 이미지의 기초, 그리고 scheduler가 노드를 고르는 기준(자원 요청,셀렉터,affinity,taint,toleration)까지 정리하겠습니다. 함께 보면 좋은 실무 글로는 K8s 실무 트랙 #1이 클러스터 구조를 손으로 확인하는 출발점입니다.