반응형

Kubernetes YAML 작성법 썸네일

쿠버네티스 운영의 90%는 YAML 작성이다. 문법부터 Pod / ReplicaSet / Deployment 작성 예시, 롤아웃 전략까지 한번에 정리한다.

들어가며

쿠버네티스에서 모든 리소스는 YAML(또는 JSON)로 정의된다. kubectl apply -f xxx.yaml 하나로 클러스터 상태를 변경하는 그 순간, YAML이 "진실의 단일 소스(Single Source of Truth)" 역할을 한다.

이 글에서는 두 단계로 나눠서 정리한다.

  1. YAML 문법 — 처음 보는 사람을 위한 기본 표현
  2. 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.labelsspec.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. labelsselector 불일치

ReplicaSet / Deployment에서 가장 많이 하는 실수다.

selector:
  matchLabels:
    app: myapp
template:
  metadata:
    labels:
      app: nginx

위 예시는 selector는 app: myapp 을 찾는데 Pod template은 app: nginx 로 생성되므로 매칭이 되지 않는다. selector와 template label은 반드시 맞춰야 한다.

11-3. createapply 혼용

kubectl create -f 는 최초 생성에는 직관적이지만, 이미 존재하는 리소스에 다시 적용하면 충돌이 날 수 있다. 반복 적용과 Git 관리까지 고려하면 일반적으로 kubectl apply -f 를 기본으로 두는 편이 낫다.


마무리

쿠버네티스 YAML은 처음에는 들여쓰기 한 칸 어긋났을 뿐인데도 cryptic 한 에러를 뱉어낸다. 다음 두 가지 습관이 큰 도움이 된다.

  1. VS Code + Red Hat YAML 확장으로 스키마 자동 검증
  2. **kubectl explain {kind}.{field}** 로 필드 의미를 즉석에서 확인

YAML이 길어 보여도 결국 4대 필드(apiVersion / kind / metadata / spec) 의 반복이다. 이 골격이 익으면 나머지는 빠르게 따라온다.


다음 글

다음 글에서는 로컬에서 바로 실습할 수 있는 Minikube 기반 Kubernetes Hands-on 환경 구성을 정리한다.