K8s_Cloudwave: K8s 기본 리소스

쿠버네티스란?

셀프 힐링

  • 쿠버네티스는 스스로 복구한다
  • Pod가 죽거나, 컨테이너가 비정상 종료되거나, 노드가 장애 나면
  • 사람이 직접 고치지 않아도 쿠버네티스가 자동으로 다시 맞춘다

선언 감시

  • Deployment, StatefulSet 같은 YAML 파일에 쓰여있는 Replica 수, 이미지 버전 등을 쿠버네티스는 계속 감시

현재 상태와 비교

  • 실제로 pod가 몇개 떠있고, 죽은 pod는 없는지 확인
  • Desired 상태와 Actual 상태가 다르다면 Pod 새로 생성하여 시작

쿠버네티스 사용 이유

  • API로 상태를 정의한다
  • “어떻게 할지”가 아니라 “어떤 상태여야 하는지”를 적는다

컨트롤플레인

  • 쿠버네트스의 두뇌
  • 구성요소
    • API 서버: API 요청에 응답하고 저장소에 기록. REST 서비스 제공
    • ETCD: 쿠버네티스의 기억장치 (Pod, Deployment, Service 같은 모든 상태 정보 저장)
    • 스케줄러: 새로 만들 Pod를 어느 노드에 올릴지 결정
    • 컨트롤러 매니저: 제어루프 사용해서 설정 상태를 유지하도록 함

노드

  • 실제 앱을 실행하는 시스템
  • 구성요소
    • 컨테이너 런타임: 컨테이너 실행 엔진
    • Kubelet: API 서버와 통신하며 노드의 컨테이너 관리
    • Kube-proxy: 앱의 구성요소에 따라 트래픽 분산

ETCD

  • 데이터를 분산해서 보관
  • 모든 데이터는 모든 노드에 동일하게 존재 (ETCD를 통해 모든 노드가 데이터 공유)
  • 모든 데이터는 리더에 먼저 쓰이고 나머지 노드에 복제
  • 내부구성은 각 노드에 ETCD가 각각 붙어있음 (노드 죽으면 ETCD 같이 죽음)
  • 외부구성은 노드와 ETCD가 떨어져있음 (노드 죽어도 ETCD 안죽음)

Pod

  • 쿠버네티스의 가장 작은 실행 단위
  • Pod : 컨테이너 = 1:1 비율 (종단 컨테이너는 1:N가능)
  • Pod는 무조건 노드안에 존재
  • 동일한 Pod 안에 있는 컨테이너는 네트워크 및 볼륨 공유 가능
  • Pod들은 공유 가능한 네트워크 주소 값을 갖음
  • 각각의 Pod는 개별 IP를 보유 (이걸 통해 LAN처럼 서로 통신이 무조건 가능)
  • Pod 내의 컨테이너가 여러개인 경우, 서로 다른 포트를 통해 서비스해야함
# Pod 생성하는 yml 파일 예시
apiVersion: v1              # 사용할 Kubernetes API 버전
kind: Pod                   # 생성할 리소스 종류
metadata:
  name: my-redis             # Pod 이름 
spec:                        # Pod의 원하는 상태(Desired State) 정의
  containers:                # Pod 안에서 실행될 컨테이너 목록
  - name: redis              # 컨테이너 이름 (Pod 내부에서 식별)
    image: redis:7.2         # 사용할 컨테이너 이미지 
    ports:
    - containerPort: 6379    # 컨테이너가 사용하는 포트

 

Pod 관련 핵심 명령어 (예시 파일 기반)

# redis가 실행중인 컨테이너에 bash로 접속후 프로세스를 조회
kbectl exec -it redis-pod -- bash

# Pod 이벤트 및 컨테이너 로그 확인
kubectl logs redis-pod

Label

  • 라벨은 쿠버네티스의 모든 리소스를 관리하기 쉽도록 도움
  • 셀렉터를 통해 리소스를 선택 가능
  • 리소스를 만들 때 뿐만 아니라 이미 만들어진 리소스의 라벨도 수정 가능
  • key/value 쌍임
# Label 생성을 위한 yml 파일 예시
apiVersion: v1
kind: Pod
metadata:
  name: goapp-pod
  labels:
    env: prod
    tier: backend
spec:
  containers:
  - image: dangtong/goapp
    name: goapp-container
    ports:
    - containerPort: 8080
      protocol: TCP

 

핵심 명령어

# yaml 파일을 이용해 pod 를 생성
kubectl apply -f ./goapp-with-label.yaml

# 생성된 POD를 조회
kubectl get po --show-labels

# Label 추가 (참고로 동일한 key를 중복해서는 라벨 추가 못함)
# 만약 env=web이었으면 기존 yml파일에서 키 중복이 일어남
kubectl label po goapp-pod app=web

# label 수정
kubectl label po goapp-pod app=api --overwrite

# Label 삭제
kubectl label po goapp-pod app-

Annotation

  • key/value 쌍이지만 라벨과 다르게 셀렉터 활용 불가능
  • 라벨보다 더 많은 정보 담을 수 있음
  • 주로 주석 역할로 쓰임
# Annotation 추가
kubectl annotate pod goapp-pod maker="dangtong" team="k8s-team"

# Annotation 확인
kubectl describe po goapp-pod

# Annotation 삭제
Kubectl annotate po goapp-pod maker- team-

Namespace

  • 클러스터 내에서 리소스 그룹을 격리하기 위한 역할
  • 리소스 이름은 Namespace 내에서는 고유해야함 (다른 네임스페이스면 이름 같아도 상관 X)
  • ResourceQuota를 사용해 CPU, 메모리 등의 자원제한 가능
  • Namespace 삭제시 내부의 모든 리소스 삭제

probe

  • probe는 판단만 함. 행동은 X
  • probe 결과 바탕으로 kubelet이 행동

Replication Controller

  • pod가 사라지면 새로운 노드에 pod 생성 (pod가 죽은 이유의 대부분은 해당 노드 문제여서 안전하게 새로운 노드에 생성함)
  • RC를 붙이지 않은 pod는 사라져도 생성 안됨
  • RC는 구닥다리 방식이라 이제 안씀

3가지 구성 요소

  • RC 내에 있는 pod 결정하는 라벨 셀렉터 사용
  • 실행해야 하는 pod의 원하는 수를 지정(replica 갯수 지정)
  • 새로운 pod 복제본 만들 때 필요한 pod 탬플릿

pod 템플릿 수정하면 반영되는 시점


ReplicaSet

  • RC 대체용
  • 일반적으로 Deployment 사용해서 RS 생성함
  • RC와 동일하게 동작하지만 pod 선택이 더 자유로움
  • RC는 지역적으로 멀리 떨어져있는 노드끼리 통신 X, 하지만 RS는 O


DaemonSet

  • 모든 노드에 pod를 1개씩 보장하는 컨트롤러
  • RC, RS는 노드의 갯수 컨트롤러임
  • 주로 노드마다 로그 수집, 모니터링 에이전트등이 필요할때 사용됨
  • RC, RS, DS 등 컨트롤러는 '노드'를 관리하는게 아니라 '생성한 pod'를 관리
# K8s 실제 컨트롤러 구성 사용 예시
[Control Plane]
 └─ kube-controller-manager
     ├─ ReplicaSet Controller
     ├─ DaemonSet Controller
     └─ Deployment Controller

[Node 1]
 ├─ web-pod (ReplicaSet 컨트롤러가 생성한 pod)
 └─ log-agent (DaemonSet 컨트롤러가 생성한 pod)
[Node 2]
 ├─ web-pod (ReplicaSet 컨트롤러가 생성한 pod)
 └─ log-agent (DaemonSet 컨트롤러가 생성한 pod)

 

  • RC/RS를 replica 3개로 설정했다면 이렇게만 생각함
"이 템플릿의 Pod가 클러스터 전체에 총 3개 있으면 됨" / 노드단위가 아님!

Deployments

  • Pod와 RS가 만들어짐
  • 객체이고 모든 히스토리를 보관하며 롤백이 가능함
  • 버전 2개를 동시에 띄우는 배포기법들은 모드 Sticky Session이 필요

Recreate:

  • 재가동임. 사용하고 있던 버전을 그냥 내렸다가 새로운 버전으로 올리는거임
  • 쉽지만 변경시간동안 멈춤 그리고 리소스 하나씩 새 버전으로 변경

Ramped:

  • 구버전과 새버전을 한번에 띄워서 트래픽 분산시킴 (조금씩 갈아탐)
  • 기존 버전에서 세션이 끊기거나 새로운 사람들이 버전 2로 연결됨
  • 시스템 자원이 많으면 maxserge를 많이 키워서 빠르게 버전 변경 가능
  • 롤아웃/롤백 오래걸리고 복잡

Blue/Green:

  • 새 버전에 필요한 리소스를 전부 업데이트하고 모두 준비 후 기존 버전에서 새 버전으로 바로 연결 (한번에 갈아탐)
  • 리소스가 2배나 필요해서 현장에서는 잘 안씀
  • 버전 자주 변경되는 프론트서비스에 적합
  • 롤아웃/롤백 간단하고 금방함

canary:

  • Blue/Green에서 한번에 변경하는게 아닌 10프로만 보내보고 위험 없으면 모두 옮김
  • 리스크 감소
  • 롤백이 빠르지만 롤아웃이 느림

A/B testing:

  • 모바일이냐 ,데스크탑이냐처럼 서로 다른 웹 화면을 띄어야하는 경우 사용
  • 지능형(모바일 or 데스크탑 중 어디로 연결할지) 로드밸런서가 필수

shadow:

  • v1에 있던 요청이 v2로 복제되는거임
  • 요청 필터 가능
  • 2배의 리소스 사용함

배포 기법 정리

  • 다운타임 허용 된다? Recrate
  • Recreate와 Ramped는 Deployment 기능에 설정으로 포함 되어 있음
  • Recreate와 Ramped 배포는 일반적으로 적용하기 쉬움
  • Blue/Green 배포는 동일한 서버에서 버전이 변경되는 서비스를 로드하는 프론트에 적합
  • Blue/Green과 Shadow는 리소스 2배 필요해서 비쌈
  • Canary와 A/B Testing는 리스크를 줄이고 싶을때 좋음
Recreate, Rolling Update: Deployment의 기본 배포 전략
Blue/Green과 Canary 배포: Deployment 외 트래픽 제어 구성을 통해 구현 가능
A/B Testing과 Shadow 배포: Deployment 기능으로는 지원되지 않는다.
# A/B Testing, Shadow는 Deployment가 아니라 Load Balancer같은 얘들이 담당한다.

Stateless App

  • 서버가 “사용자 기억”을 안 함
  • 그래서 쿠키와 세션을 사용
  • 세션은 Redis 같은 외부 저장소 사용
  • 서버 죽어도 서비스 유지 가능

Stateful App

  • 상태를 직접 보유 (ex: DB, Redis)
  • 상태를 직접 들고 있기 때문에 재시작·재배포에 민감

'K8s' 카테고리의 다른 글

K8s_Cloudwave: ConfigMap & Secret  (0) 2026.01.12
k8s_cloudwave: 볼륨  (1) 2026.01.09
K8s_Cloudwave: Terraform 활용 EKS 생성  (0) 2026.01.09
K8s-Cloudwave: 로컬 K8s 생성  (0) 2026.01.08
K8s-Cloudwave: 쿠버네티스 기초  (0) 2026.01.08