cf) kubectl apply 명령어의 원리
kubectl apply
개념
kubectl apply는 선언적 방식(declarative approach)으로 Kubernetes 객체를 관리하는 명령어이다.- 내부적으로
apply는 아래 3가지 구성 요소를 비교하여 변경사항을 결정한다.
Local File- 사용자가 작성한 YAML 파일Live Object Configuration- 클러스터 내부에 존재하는 Object의 실시간 구성도Local File과 유사한 구성이지만,status필드와 같이 Kubernetes가 관리하는 runtime 필드들이 추가적으로 존재한다.- 해당 구성도는
ETCD에 존재한다.
Last Applied Configuration- 마지막으로apply를 적용했을 때의 스냅샷Local File의 구성이 JSON 형식으로 변환된 형태Live Object Configuration의annotation으로 저장된다.- 오직
kubectl apply를 사용할 떄만 저장되며,kubectl create, 나kubectl replace는 이 정보를 저장하지 않는다.
예시
Local File
# nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end-services
spec:
containers:
- name: nginx-container
image: nginx:1.18
Live Object Configuration (+ Last Applied Configuration)
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end-services
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Pod","metadata":{"name":"myapp-pod","labels":{"app":"myapp","type":"front-end-services"}},"spec":{"containers":[{"name":"nginx-container","image":"nginx:1.18"}]}}
spec:
containers:
- name: nginx-container
image: nginx:1.18
status:
conditions:
- lastProbeTime: null
status: "True"
type: Initialized
동작 원리
생성
- 오브젝트가 아직 존재하지 않는다면,
kubectl apply는 오브젝트를 새로 생성한다. - 생성될 때 Kubernetes 는
status를 포함한Live Object Configuration을 만든다. - 동시에,
Local File을 JSON 형태로 변환하여Last Applied Configuration으로 오브젝트의annotation에 저장한다.
수정
apply를 실행하면 아래 비교가 이루어진다.
-
수정:
Local File에 수정된 필드가 있다면,Live Object Configuration에는 수정되지 않았을 것이다. 그렇다면apply시Live Object Configuration이 업데이트 될 것이다.- 이후
Last Applied Configuration도 업데이트 된다.
-
삭제:
- 만약
Local File의 삭제된 필드가 있다면,Last Applied Configuration에는 존재할 것이다. 그렇다면apply시Live Object Configuration에서 해당 필드가 삭제될 것이다. - 이후
Last Applied Configuration에서도 삭제된 것이 업데이트 된다.
- 만약
정보
'삭제' 부분에서 잘 이해가 되지 않을 수 있다. (그냥 Local File에 없고 Live Object Configuration에 있는 필드는 삭제해버리면 되잖아 라는 의문이 들 수 있다)
하지만, 그렇게 되면 Kubernetes 입장에서는 그게 '사용자가 삭제한 필드인지', '시스템이 알아서 추가한 필드인지'를 구분할 수 없다.
예를들어 Live Object Configuration에는 status 필드나 metadata.creationTimestamp와 같은 필드도 존재한다. 이는 Kubernetes가 apply를 했을 때 자동으로 붙인 요소들이다.
만약 Last Applied Configuration이 없다면, 이러한 시스템이 관리하는 필드까지 삭제될 것이다.
이때문에, Kubernetes는 '사용자가 추가한 필드인지', '시스템이 추가한 필드인지'를 판단할 기준이 필요하고, 그 기준이 바로 Last Applied Configuration이다.
주의할 점
apply(declarative) 와create/replace(imperative)를 혼용하면 관리가 꼬일 수 있다.- 즉,
apply를 사용하기 시작했다면, 이후에도 계속apply로 관리하는 것이 좋다.
예시
| 상황 | 문제점 |
|---|---|
create로 만든 뒤 apply 실행 | apply는 비교 기준(Last Applied Configuration)이 없음 → “무엇이 변경됐는지” 몰라서 충돌/에러 가능 |
apply로 만든 뒤 replace 실행 | replace는 Live를 통째로 덮어써서, Last Applied Configuration가 삭제됨 → 이후 apply 시 diff 계산 불가 |
apply와 replace를 번갈아 씀 | Last Applied Configuration 내용이 실제 YAML과 불일치 → 삭제/갱신 판단이 꼬임 |