들어가며

이 포스트의 범위

  • 이 포스트는 Kubernetes Patterns 1챕터를 읽고 정리한 내용입니다
  • “클라우드 네이티브가 뭔데?” 라는 질문에서 시작해서, Kubernetes의 핵심 개념들을 쉽게 풀어봤습니다

0. Contents


1. 왜 마이크로서비스인가?

마이크로서비스의 정의

  • 마이크로서비스는 큰 앱을 잘게 쪼개서 여러 개의 작은 서비스로 만드는 방식입니다
쇼핑몰 (모놀리스)하나의 거대한 앱쇼핑몰 (마이크로서비스)로그인 서비스결제 서비스배송 서비스상품 서비스
하나의 거대한 앱을 작은 서비스 여러 개로 쪼갠다
모놀리스마이크로서비스
개발한 팀이 전부팀별로 독립 개발
배포전체를 한꺼번에서비스별로 따로
장애하나 터지면 전체 down일부만 영향
복잡도개발은 단순, 규모가 커지면 복잡개발은 복잡, 운영은 유연

핵심: 개발 복잡성을 운영 복잡성과 맞바꾸는 것 — 그래서 Kubernetes가 필수입니다.


2. 좋은 앱을 만드는 4가지 설계 원칙

책의 강조점: 앱 자체의 품질

  • 책에서는 Kubernetes 패턴을 배우기 전에 앱 자체를 잘 만들어야 한다고 강조합니다

Clean Code

코드 품질과 유지보수 비용

  • 변수 이름 하나, 함수 하나하나가 나중에 다 유지보수 비용이 됩니다
  • 아무리 좋은 Kubernetes 환경이어도 코드가 쓰레기면 대규모 쓰레기가 될 뿐입니다

Domain-Driven Design (DDD)

DDD: 비즈니스 관점의 설계

  • 비즈니스 관점에서 소프트웨어를 설계하는 방법론입니다
  • ❌ “기술적으로 어떻게 만들지?”
  • ✅ “실제 쇼핑몰이 어떻게 돌아가지?” ← 이걸 먼저 생각

현실 세계에 가까운 구조의 효과

  • 현실 세계와 가까운 구조로 설계하면 → 나중에 컨테이너화와 자동화가 훨씬 쉬워집니다

Hexagonal Architecture

핵심 로직과 외부의 분리

  • 핵심 비즈니스 로직과 외부(DB, UI, 클라우드)를 분리하는 설계 방식입니다
외부DB, API, UI인터페이스연결 통로핵심 비즈니스 로직이게 중심!
외부와 핵심 로직 사이에 인터페이스를 둔다

분리의 효과

  • 외부가 바뀌어도 핵심 로직은 그대로
    • AWS → Azure 이전도 외부 연결만 바꾸면 끝!

12-Factor App + Microservices 원칙

현대 클라우드 앱의 표준 방법론

  • 현대 클라우드 앱의 표준이 된 방법론입니다
  • 세 가지를 목표로 합니다
목표의미
Scale (확장성)사용자 늘어도 잘 버팀
Resiliency (회복성)일부가 터져도 전체는 안 죽음
Pace of Change (변화 속도)빠르게 업데이트 가능

3. Distributed Primitives — Kubernetes의 기본 단위

Java/JVM과의 비교

  • Java/JVM과 비교하면 Kubernetes를 쉽게 이해할 수 있습니다
Java (로컬, 1대)Kubernetes (분산, 여러 대)
Class (설계도)Container Image
Object (실행)Container
JVMKubernetes
생성자 newInit Container
데몬 스레드DaemonSet
Spring IoCPod
ExecutorServiceCronJob

규모의 차이

  • Java = 방 하나에서 일하는 것
  • Kubernetes = 여러 건물에 걸쳐 팀이 협업하는 것 🏢🏢🏢
Deployment무중단 앱 배포CronJob주기적 작업 실행DaemonSet모든 노드에 1개씩ReplicaSetPod 복제본 유지StatefulSet상태 있는 앱Job일회성 작업ReplicationController레거시 Pod 관리ServicePod 접근 창구Horizontal PodAutoscaler수평 자동 확장Pod컨테이너 묶음Vertical PodAutoscaler리소스 자동 조정Pod DisruptionBudget가용성 보장Container(your code)앱이 실제 실행되는 곳Volume데이터 저장 공간ConfigMap설정 데이터Secret민감 데이터PersistentVolumeClaim영구 스토리지 요청Downward APIPod 메타데이터HostPath;EmptyDir노드/임시 스토리지

Kubernetes Distributed Primitives — Container를 중심으로 Pod, Volume, 각종 컨트롤러가 연결된 전체 구조


4. Container

비유: 붕어빵 틀과 붕어빵

  • 컨테이너 이미지 = 붕어빵 틀 🐟
  • 컨테이너 = 실제 붕어빵 🐟🐟🐟
  • 틀(이미지) 하나로 붕어빵(컨테이너)을 여러 개 찍어낼 수 있습니다

좋은 컨테이너 이미지의 8가지 조건

#조건의미
1Single concern딱 한 가지 역할만
2Owned by one team담당 팀 하나 + 독립 배포 주기
3Self-contained필요한 것을 다 들고 다님
4Immutable한번 만들면 수정 ❌, 새 버전 출시 ✅
5Defines resource requirementsCPU/메모리 필요량 미리 명시
6Well-defined APIs외부와 소통하는 창구가 명확
7Single Unix process컨테이너 하나 = 프로세스 하나
8Disposable언제든 만들고 없애도 OK

좋은 컨테이너는 레고 블록처럼 작고, 환경별로 설정만 바꿔서 재사용 가능해야 합니다.


5. Pod

개발 단위와 실행 단위

  • 마이크로서비스는 개발할 때는 컨테이너 이미지, 실행할 때는 Pod입니다
개발/빌드할 때컨테이너 이미지설계도, 틀실행할 때Pod실제로 살아서 돌아가는 것
개발할 때는 컨테이너 이미지, 실행할 때는 Pod

컨테이너 실행의 유일한 경로

  • Kubernetes에서 컨테이너를 실행하는 유일한 방법은 Pod를 통하는 것입니다

Pod의 3가지 핵심 특징

1. 스케줄링의 최소 단위

  • Pod 안에 컨테이너가 여러 개라면, 스케줄러는 모든 컨테이너의 자원을 합산해서 감당할 수 있는 서버를 찾습니다
Pod스케줄링의 최소 단위컨테이너 ACPU·메모리 요청+컨테이너 BCPU·메모리 요청합산스케줄러A + B 자원 합계로놓을 노드를 찾음노드 1남은 자원 < 합계노드 2남은 자원 ≥ 합계탈락Pod 전체 배치컨테이너를 나눠 다른 노드에 놓지 않는다
스케줄러는 Pod 안 컨테이너 자원을 합산해 노드를 고른다

2. 컨테이너들의 동거 보장 (Colocation)

  • 같은 Pod 안의 컨테이너끼리 소통하는 방법
방법설명속도
공유 파일시스템같은 폴더를 읽고 씀빠름 ⚡
localhost 네트워크내부망으로 통신빠름 ⚡
IPC프로세스간 직접 통신매우 빠름 ⚡⚡
PodContainerPython앱 실행 컨테이너ContainerJava앱 실행 컨테이너localhostDisk공유 파일시스템

같은 Pod 안의 컨테이너들은 localhost와 Disk를 공유한다

3. IP/포트 공유

  • Pod 안의 컨테이너들은 IP 주소와 포트를 공유합니다
  • 포트가 겹치면 충돌이 납니다
PodIP: 10.0.0.1컨테이너 A포트 8080✅컨테이너 B포트 8081✅컨테이너 C포트 8080❌ 충돌!포트가 겹치면 충돌
같은 Pod 안의 컨테이너는 IP와 포트를 함께 쓴다

사이드카 패턴

  • Pod 안에 메인 컨테이너 + 보조 컨테이너를 함께 두는 방식
Pod메인 앱 컨테이너 🚗사이드카 컨테이너 🏍️로그 수집, 모니터링 등
사이드카 패턴: 메인 컨테이너 옆에 보조 컨테이너를 둔다

6. Service

문제: 바뀌는 Pod IP

  • Pod는 언제든 죽고 다시 생깁니다
  • 그때마다 IP 주소가 바뀝니다

해결: Service

  • Service는 이 문제를 해결하는 고정 주소 + 대표 창구입니다
Service 없이Pod IP로 직접 접속사용자죽은 Pod10.0.0.1새 Pod10.0.0.5옛 주소로 접속 → 실패새 주소는 모름Pod가 다시 생기면 IP가 바뀐다Service 사용고정 주소 + 대표 창구사용자Service주소 고정Pod살아있음Pod살아있음죽은 Pod제외살아있는 Pod로만 나눠 보낸다
Pod IP는 바뀌어도 Service 주소는 그대로다
Service의 역할설명
고정 주소IP/포트가 절대 안 바뀜
서비스 디스커버리살아있는 Pod를 자동으로 찾아줌
로드 밸런싱여러 Pod에 트래픽을 골고루 분배

Service = 대표전화 📞 / Pod = 실제 상담원


7. Label

Label의 역할

  • 마이크로서비스로 쪼개면 Pod가 여러 개가 됩니다
  • 이 Pod들이 같은 앱에 속한다는 걸 표시하는 방법이 Label입니다

Label을 이용한 그룹 관리

  • Label로 Pod 그룹을 관리할 수 있습니다
# app=쇼핑몰인 Pod 전부 재시작
kubectl rollout restart deployment -l app=쇼핑몰
selectorapp=쇼핑몰kubectl rollout restartdeployment -l app=쇼핑몰app=쇼핑몰선택됨Pod 1app=쇼핑몰tier=frontendPod 2app=쇼핑몰tier=backendPod 3app=쇼핑몰tier=databaseapp=결제선택 안 됨Pod 4app=결제tier=apiPod 5app=결제tier=databaseReplicaSet·Service·모니터링도 이렇게 Label로 Pod를 찾는다 → Label 삭제는 위험
Label이 같은 Pod만 한 번에 골라 관리한다

Label 사용 시 주의사항

  • 추가는 언제든 쉽게 가능 ✅
  • 삭제는 매우 위험 ⚠️
    • ReplicaSet, Service, 모니터링 등 어디서 쓰이는지 파악하기 어려움
  • 미리 너무 많이 달지 말고, 필요한 것만 달기

Label = 인스타그램 해시태그 🏷️ — 단순 태그가 아니라 Kubernetes가 실제 Pod를 관리하는 데 핵심적으로 사용됩니다.


8. Annotation

Label과의 차이: 목적

  • Label과 비슷하지만 목적이 다릅니다
LabelAnnotation
목적검색/그룹핑/관리부가정보 저장
사용자사람기계/자동화 도구
검색 가능?✅❌
예시app=쇼핑몰빌드ID, Git 브랜치 등

Annotation에 저장하는 정보 예시

annotations:
  build-id: "12345"
  git-branch: "main"
  image-hash: "sha256:abc..."
  author: "김철수"
  timestamp: "2026-06-22"

Label = 책의 분류 태그 🏷️ / Annotation = 책 뒷면의 상세정보 📖


9. Namespace

Namespace의 정의

  • 하나의 Kubernetes 클러스터를 용도별로 나누는 칸막이입니다

Kubernetes 클러스터 = 하나의 큰 사무실 🏢

  • dev namespace → 개발팀 공간
  • testing namespace → QA팀 공간
  • production namespace → 운영팀 공간

주요 특징 정리

특징설명
이름 충돌 방지같은 이름을 Namespace별로 따로 쓸 수 있음
DNS 주소 구분my-app.production.svc.cluster.local
ResourceQuotaNamespace별로 CPU/메모리 한도 설정 가능
기본 격리 없음⚠️ 기본적으로 다른 Namespace 접근 가능 (별도 네트워크 정책 필요)

실제로 많이 쓰는 구성

비운영 클러스터개발·QA용dev namespacemy-apptesting namespacemy-appintegration namespacemy-app기본은 서로 접근 가능운영 클러스터성능 시험·운영용performance namespacemy-appproduction namespacemy-app같은 이름 my-app을Namespace마다 따로 둘 수 있다이름충돌 방지Namespace마다같은 이름 사용 가능DNS주소 구분my-app.production.svc.cluster.localQuota자원 한도Namespace별CPU·메모리 한도 설정다른 Namespace 접근을 막으려면 네트워크 정책, 완벽한 격리는 클러스터 분리
Namespace는 클러스터 안의 칸막이, 완전한 격리는 클러스터 분리

완벽한 격리가 필요하면 클러스터 자체를 분리해야 합니다.


10. 전체 흐름 정리

[ 개발 → 배포 → 운영 전체 흐름 ]
1. 개발팀이 Clean Code + DDD로 앱 설계
2. 컨테이너 이미지로 패키징 (단일 목적, 불변)
3. Kubernetes에 Pod로 배포
4. Service로 고정 주소 제공
5. Label로 Pod 그룹 관리
6. Namespace로 환경(dev/prod) 분리
7. Annotation으로 자동화 도구에 메타데이터 전달
개념한마디 요약비유
Container앱을 담는 도시락통붕어빵 틀/붕어빵 🍱
Pod컨테이너들의 묶음Spring IoC 컨텍스트
ServicePod의 고정 주소/대표창구대표전화 📞
LabelPod에 붙이는 태그인스타 해시태그 🏷️
Annotation기계가 읽는 메모장책 뒷면 상세정보 📖
Namespace클러스터를 나누는 칸막이사무실 부서 칸막이 🚧

마치며

1챕터의 핵심 메시지

  • 1챕터의 핵심 메시지는 단순합니다

“Kubernetes가 아무리 좋아도, 앱 자체가 잘 만들어져 있지 않으면 소용없다.”

정리와 다음 챕터

  • 좋은 그릇(Kubernetes)도 중요하지만, 담는 내용물(앱)이 먼저입니다
  • 다음 챕터부터는 본격적으로 Kubernetes 패턴들을 하나씩 살펴볼 예정입니다