Kubernetes YAML 작성법 완전 가이드

쿠버네티스 운영의 90%는 YAML 작성이다. 문법부터 Pod / ReplicaSet / Deployment 작성 예시, 롤아웃 전략까지 한번에 정리한다.
들어가며
쿠버네티스에서 모든 리소스는 YAML(또는 JSON)로 정의된다. kubectl apply -f xxx.yaml 하나로 클러스터 상태를 변경하는 그 순간, YAML이 "진실의 단일 소스(Single Source of Truth)" 역할을 한다.
이 글에서는 두 단계로 나눠서 정리한다.
- YAML 문법 — 처음 보는 사람을 위한 기본 표현
- Kubernetes YAML 작성법 — Pod, ReplicaSet, Deployment의 4대 필드와 롤아웃/롤백 전략
1. YAML 기본 문법
1-1. 기본 형식 — Key: Value
YAML은 Key: Value 쌍으로 이루어진 데이터 표현 방식이다.
Key: Value
Key2: Value2
1-2. 배열(List)
- (하이픈)으로 구분해 표현한다.
Fruits:
- Orange
- Apple
- Banana
Vegetables:
- Carrot
- Cauliflower
- Tomato
1-3. 딕셔너리(Dictionary)
키-값 입력 전 들여쓰기를 동일한 깊이로 맞춘다.
Banana:
Calories: 105
Fat: 0.4 g
Carbs: 27 g
Grapes:
Calories: 62
Fat: 0.3 g
Carbs: 16 g
1-4. 배열 + 딕셔너리 조합
가장 자주 등장하는 패턴이다.
Fruits:
- Banana:
Calories: 105
Fat: 0.4 g
Carbs: 27 g
- Grape:
Calories: 62
Fat: 0.3 g
Carbs: 16 g
1-5. 차(Car) 정보로 보는 종합 예시
Car:
- Color: Blue # 리스트 아이템
Model: # 딕셔너리
Name: Corvette
Year: 1995
Transmission: Manual
Price: $20,000
- Color: Red
Model:
Name: Mustang
Year: 2010
Transmission: Auto
Price: $25,000
YAML은 결국 들여쓰기 기반의 Key-Value 데이터 구조다. 표기법보다 중요한 것은 같은 깊이의 항목을 같은 들여쓰기 레벨로 맞추는 습관이다.
1-6. 딕셔너리 vs 배열 — 헷갈리는 차이
- 딕셔너리: 속성 순서 상관없음.
- 배열/리스트: 정렬된 컬렉션이므로 순서가 의미를 가진다.
# 두 표현은 동일 (딕셔너리)
Banana:
Calories: 105
Fat: 0.4 g
Carbs: 27 g
---
Banana:
Calories: 105
Carbs: 27 g
Fat: 0.4 g
# 두 표현은 서로 다름 (리스트)
Fruits:
- Orange
- Apple
- Banana
---
Fruits:
- Orange
- Banana
- Apple
데이터 구조 작업 시 이 차이는 의외의 버그를 만든다. 리스트의 순서를 함부로 바꾸지 말자.
2. Kubernetes YAML — 4대 최상위 필드
쿠버네티스 정의 파일은 항상 4개의 최상위 필드를 포함한다.
apiVersion:
kind:
metadata:
spec:
2-1. apiVersion
리소스를 만들 때 사용하는 API 버전. kind에 따라 어떤 apiVersion을 써야 하는지 정해져 있다.
| kind | apiVersion |
|---|---|
| Pod | v1 |
| Service | v1 |
| ReplicaSet | apps/v1 |
| Deployment | apps/v1 |
2-2. kind
만들고 싶은 리소스 종류 (Pod, Service, ReplicaSet, Deployment 등).
2-3. metadata
리소스에 대한 "이름표". 딕셔너리 형태이며, 라벨(labels)이 가장 중요하다.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
라벨은 향후 필터링, 셀렉터 매칭, 모니터링 그룹핑의 키가 된다. 처음부터 의미 있는 라벨을 붙여두자.
2-4. spec
리소스 종류에 따라 들어가는 내용이 달라진다. Pod라면 컨테이너 명세, Deployment라면 템플릿 + replicas 등을 정의.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers: # List / Array
- name: nginx-container # 첫 번째 컨테이너
image: nginx # Docker Hub 이미지
spec 필드의 정확한 형식은 리소스마다 다르므로 **kubectl explain {kind}.spec** 또는 공식 문서를 참고하자.
3. Pod 정의 예시 — 컨테이너 1개 / 2개
컨테이너 1개
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
컨테이너 2개
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
tier: front-end
spec:
containers:
- name: nginx
image: nginx
- name: busybox
image: busybox
Pod 생성: kubectl create -f pod-definition.yml
또는 권장 방식: kubectl apply -f pod-definition.yml
YAML 작성을 도와주는 IDE
VS Code에서 좌측 Extensions 탭으로 이동하여 "YAML" 검색 후 RedHat이 게시한 확장 프로그램을 설치하면 자동완성, 스키마 검증, 인덴트 오류 표시까지 지원된다.
작성 전 빠른 체크
- 탭(tab) 대신 공백 2칸 또는 4칸으로 들여쓰기한다.
metadata.labels와spec.selector.matchLabels가 서로 맞는지 확인한다.apiVersion은 리소스 종류마다 다르다. 헷갈리면kubectl explain <kind>로 확인한다.- 실무에서는 한 번 생성하고 끝내기보다
kubectl apply -f로 반복 적용 가능한 형태를 선호한다.
4. ReplicationController YAML
apiVersion: v1
kind: ReplicationController
metadata: # ReplicationController 메타데이터
name: myapp-rc
labels:
app: myapp
type: front-end
spec: # ReplicationController 스펙
template:
metadata: # Pod용 메타데이터
name: myapp-pod
labels:
app: myapp
type: front-end
spec: # Pod용 스펙
containers:
- name: nginx-container
image: nginx
replicas: 3
- template 섹션 내부에 생성할 Pod 명세를 그대로 넣는다 (apiVersion, kind 제외).
- 현재는 ReplicationController 대신 ReplicaSet 사용을 권장한다.
5. ReplicaSet YAML
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-rs
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector: # ReplicationController 와의 핵심 차이
matchLabels:
type: front-end
ReplicationController와 거의 같지만 selector 섹션이 추가된 점이 결정적인 차이다.
- ReplicaSet은 selector 의 라벨 조건에 매칭되는 Pod 개수를 유지한다.
- 이미 떠 있는 Pod 라도 라벨이 매칭되면 관리 대상에 포함된다.
kubectl 로 ReplicaSet 갯수 조정 (Scale)
# 1) YAML 파일 수정 후 replace
kubectl replace -f replicaset-definition.yaml
# 2) 명령어로 즉시 스케일
kubectl scale --replicas=6 -f replicaset-definition.yaml
kubectl scale --replicas=6 replicaset myapp-replicaset
# ex) kubectl scale replicaset myapp-replicaset --replicas=4
6. Deployment YAML
Deployment는 ReplicaSet 보다 상위 객체다. ReplicaSet의 모든 기능 + 무중단 배포(Rolling Update), 롤백, 버전 히스토리를 제공한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
모든 객체 한 번에 보기
kubectl get all
7. Rollout & Versioning — 배포 프로세스
디플로이먼트에서는 모든 배포 및 롤링 업데이트를 롤아웃(Rollout) 이라고 한다.
# 진행 중인 롤아웃 상태 확인
kubectl rollout status deployment/<deployment_name>
# 롤아웃 히스토리
kubectl rollout history deployment/<deployment_name>
7-1. Recreate 전략
- 기존 Deployment 모두 제거 → 새 버전 배포
- Application Downtime 발생
- 기본 전략 ❌
7-2. Rolling Update 전략 (기본)
- 다수 앱을 하나씩 새 버전으로 교체
- Downtime 없음
- Kubernetes의 기본 배포 전략
8. apply / set image — 변경 적용
# YAML 변경 후 일괄 적용 (권장)
kubectl apply -f deployment.yaml
# 컨테이너 이미지만 즉시 변경
kubectl set image deployment/<deployment_name> nginx-container=nginx:1.9.1
⚠️kubectl set image는 편하지만 현재 클러스터의 명세만 바꾸고 YAML 파일은 갱신되지 않는다. Git 관리하는 YAML과 클러스터 상태가 어긋나면 추적이 어려워지므로, 가능하면 YAML을 수정한 뒤apply하자.
9. Rollback — 문제가 생겼을 때
kubectl rollout undo deployment/<deployment_name>
이전 ReplicaSet으로 즉시 되돌아간다.
10. 한 장 요약
| 분류 | 명령어 |
|---|---|
| 생성 | kubectl create -f <정의 파일> |
| 조회 | kubectl get deployments |
| 갱신 | kubectl apply -f <정의 파일> <br> kubectl set image deployment/<name> nginx=nginx:1.9.1 |
| 상태 | kubectl rollout status deployment/<name> <br> kubectl rollout history deployment/<name> |
| 롤백 | kubectl rollout undo deployment/<name> |
💡 예전에는 kubectl --record 로 CHANGE-CAUSE를 남기는 방식이 자주 쓰였지만, 최신 Kubernetes에서는 해당 방식이 더 이상 권장되지 않는다. 변경 이력은 Git 커밋, PR, Argo CD/Flux 같은 GitOps 도구, 또는 명시적인 annotation으로 추적하는 편이 더 안전하다.
kubectl annotate deployment/myapp-deployment \
kubernetes.io/change-cause="Update nginx image to 1.25"
11. 자주 하는 실수
11-1. 들여쓰기 오류
YAML은 중괄호가 아니라 들여쓰기로 구조를 표현한다. containers 아래의 - name 위치가 한 칸만 어긋나도 완전히 다른 구조가 된다.
11-2. labels 와 selector 불일치
ReplicaSet / Deployment에서 가장 많이 하는 실수다.
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: nginx
위 예시는 selector는 app: myapp 을 찾는데 Pod template은 app: nginx 로 생성되므로 매칭이 되지 않는다. selector와 template label은 반드시 맞춰야 한다.
11-3. create 와 apply 혼용
kubectl create -f 는 최초 생성에는 직관적이지만, 이미 존재하는 리소스에 다시 적용하면 충돌이 날 수 있다. 반복 적용과 Git 관리까지 고려하면 일반적으로 kubectl apply -f 를 기본으로 두는 편이 낫다.
마무리
쿠버네티스 YAML은 처음에는 들여쓰기 한 칸 어긋났을 뿐인데도 cryptic 한 에러를 뱉어낸다. 다음 두 가지 습관이 큰 도움이 된다.
- VS Code + Red Hat YAML 확장으로 스키마 자동 검증
- **
kubectl explain {kind}.{field}** 로 필드 의미를 즉석에서 확인
YAML이 길어 보여도 결국 4대 필드(apiVersion / kind / metadata / spec) 의 반복이다. 이 골격이 익으면 나머지는 빠르게 따라온다.
다음 글
다음 글에서는 로컬에서 바로 실습할 수 있는 Minikube 기반 Kubernetes Hands-on 환경 구성을 정리한다.
'Cloud > Kubernetes' 카테고리의 다른 글
| Minikube로 로컬 Kubernetes(K8s) 환경 실습하기 — Pod 생성부터 배포까지 (0) | 2026.06.05 |
|---|---|
| Kubectl 핵심 명령어 정리 — 실무에서 자주 쓰는 것 위주 (0) | 2026.05.08 |
| Kubernetes 아키텍처 완전 정복 — Master/Worker 노드 구조 (0) | 2026.05.04 |
| 컨테이너 구조 및 쿠버네티스 아키텍처 이해 (0) | 2024.02.03 |