TIL

kubectl apply 내부 동작 원리 (feat. create랑 섞어 쓰면 안 되는 이유)

하얀잔디 2026. 5. 7. 11:35

 kubectl apply가 내부적으로 어떻게 굴러가는지, 왜 다른 명령어랑 섞어 쓰면 피곤해지는지 정리해 봄.

 

1. 무지성 덮어쓰기가 아님: 3-way 비교 (3방향 병합)

 

apply를 실행하면 쿠버네티스는 그냥 기존 설정을 덮어쓰는 게 아니라, 다음 3가지를 싹 다 비교해서 무엇을 추가/수정/삭제할지 결정함.

  • Local (로컬 구성 파일): 내가 방금 로컬에서 작성하거나 수정한 YAML 파일
  • Live (라이브 오브젝트): 현재 쿠버네티스 클러스터 메모리에 올라가서 돌고 있는 실제 상태
  • Last applied (마지막으로 적용된 구성): 이전에 마지막으로 apply 쳤을 때의 상태

 

2. 'Last applied (마지막으로 적용된 구성)'이 왜 필요할까?

 

이게 없으면 "사용자가 의도적으로 필드를 지웠는지" 파악을 못함.

  • 예를 들어, 로컬 YAML 파일에서 특정 라벨(label) 한 줄을 지우고 apply를 날렸다고 가정해 봄.
  • 단순히 로컬이랑 라이브만 비교하면 이게 원래 없던 건지, 지운 건지 알 수가 없음.
  • 이때 쿠버네티스는 'Last applied'를 쓱 보고 "어? 예전엔 이 라벨이 있었는데 지금 로컬(Local)엔 없네? 아, 일부러 지운 거구나!" 하고 파악함.
  • 그제서야 실제 운영 중인 라이브(Live) 구성에서도 해당 라벨을 깔끔하게 날려줌.

 

3. 그럼 'Last applied'는 어디에 저장됨?

내 로컬 PC 어딘가에 숨어있는 게 아님.

  • 쿠버네티스 클러스터 안에 있는 라이브 오브젝트의 어노테이션(Annotation) 영역에 JSON 형태로 찰싹 붙어서 저장됨.
  • (kubectl.kubernetes.io/last-applied-configuration 이라는 긴 이름으로 저장됨)

 

4. create랑 apply 절대 섞어 쓰지 말자

 

  • kubectl create나 replace 같은 명령형 접근 방식은 방금 말한 '마지막으로 적용된 구성(어노테이션)'을 생성하지 않음.
  • 처음에 create로 리소스를 띄워놓고, 나중에 YAML 파일 수정해서 apply로 덮어씌우려고 하면?
  • 비교할 '과거 기록(Last applied)'이 없기 때문에 꼬이기 시작함. 필드 삭제나 변경 사항이 제대로 추적 안 돼서 엉뚱하게 동작하거나 예상치 못한 충돌(Conflict)이 발생할 수 있음.

 

 

 결론

  1. apply는 Local, Live, Last applied 3가지를 비교해서 똑똑하게 리소스를 업데이트함.
  2. 'Last applied' 기록이 있어야만 사용자가 '삭제'한 필드를 정상적으로 추적할 수 있음.
  3. create는 이 기록을 안 남기니까, 리소스 관리할 때 선언형(apply)으로 갈 거면 처음부터 끝까지 쭉 apply만 쓰자. 혼용 금지!