K8s 서버 사이드 apply

(Server-Side Apply에서 넘어옴)

1 개요[ | ]

Server-Side Apply (SSA)
서버사이드 어플라이, 서버측 적용
  • 쿠버네티스 API 서버가 리소스 병합과 필드 소유권 추적을 수행하도록 하는 선언적 구성 방식
  • 각 필드의 매니저(field manager)를 서버가 기록하여 여러 작성자(사람/컨트롤러)가 같은 오브젝트를 안전하게 함께 관리할 수 있게 한다.
  • 클라이언트 로컬에서 병합하던 기존 Client-Side Apply(CSA)의 한계를 보완하고, 충돌 감지/해결과 dry-run(server) 검증, CRD 스키마 기반의 정확한 병합 전략을 제공한다.
  • 기존 CSA는 마지막으로 적용한 사람이 이전 변경을 덮어쓰기 쉬웠다(특히 여러 툴/사람이 같은 객체를 만질 때). SSA는 필드 단위 소유권 관리와 충돌 감지를 통해 이런 문제를 줄인다.
개념 설명
필드 매니저(Field Manager) SSA 요청 시 함께 전달하는 식별자(예: --field-manager). 해당 요청이 "의도"를 갖는 필드의 소유자 이름이 된다. 동일 매니저가 같은 필드를 다시 업데이트하면 충돌 없이 갱신된다.
managedFields 각 오브젝트의 .metadata.managedFields에 필드별 소유권과 마지막 작업이 기록된다. API 서버가 관리하는 필드이므로 수동 편집은 피해야 한다.
충돌(Conflict)과 강제 적용(Force) 다른 매니저가 소유한 필드를 바꾸면 충돌이 발생한다. 의도적으로 덮어쓸 때는 --force-conflicts로 강제할 수 있다(신중히 사용).
완전 지정 의도(Fully specified intent) SSA 매니페스트는 "내가 의견이 있는 필드만" 포함해도 된다. 서버가 기존 오브젝트와 병합해 최종 상태를 만든다.

2 사용 방법[ | ]

2.1 kubectl[ | ]

# 서버사이드 적용(기본 필드 매니저: kubectl)
$ kubectl apply -f deploy.yaml --server-side

# 필드 매니저 이름 지정
$ kubectl apply -f deploy.yaml --server-side --field-manager=team-a

# 충돌을 감지만 하고 결과를 미리 보기(dry-run=server)
$ kubectl apply -f deploy.yaml --server-side --dry-run=server

# 충돌을 강제로 덮어쓰기(주의)
$ kubectl apply -f deploy.yaml --server-side --force-conflicts

2.2 API/라이브러리[ | ]

  • kubernetes 클라이언트(특히 Go)는 SSA를 위한 Apply 호출을 제공하며, kubectl에 의존하지 않고 프로그램적으로 필드 매니저/의도를 전달할 수 있다.

3 병합(merge) 의미론[ | ]

SSA는 스키마 기반 병합을 사용한다. 특히 리스트 필드는 CRD 스키마의 x-kubernetes-list-type(atomic/map/set)과 x-kubernetes-list-map-keys에 따라 병합 동작이 달라진다.

  • atomic: 리스트 전체를 원자적으로 취급(통째로 치환).
  • map: 지정 키 집합으로 항목을 식별해 항목 단위 병합.
  • set: 순서를 무시하고 집합처럼 병합.

이 구조화 병합은 SSA의 기반 라이브러리(structured-merge-diff)로 구현된다.

4 Client-Side Apply와 비교[ | ]

항목 Client-Side Apply(CSA) Server-Side Apply(SSA)
병합 위치 클라이언트(로컬) 서버(API 서버)
충돌 감지 제한적(마지막 작성자 이슈) 필드 단위 소유권 기반 충돌 감지
dry-run 클라이언트 추정치 --dry-run=server 로 실제 서버 병합 검증
CRD 리스트 병합 제한적/수동 처리 필요 스키마(x-kubernetes-list-*) 기반 정밀 병합
필드 소유권 가시화 없음 managedFields로 추적/감사에 유리

5 모범 사례[ | ]

  • 각 툴/팀마다 명확한 --field-manager 이름을 사용한다(예: helm, gitops/argo, platform-team).
  • 변경 전에는 --dry-run=server로 결과를 점검한다(특히 운영 환경).
  • 다른 매니저가 소유한 필드는 가능하면 수정하지 않거나 소유권을 명확히 재조정한다. 불가피한 경우에만 --force-conflicts를 쓴다.
  • CRD를 설계할 때 리스트의 의미론을 x-kubernetes-list-type / …-map-keys로 명시해 SSA 병합이 올바르게 동작하도록 한다.

6 트러블슈팅[ | ]

“Apply failed with 1 conflict …”
다른 필드 매니저가 소유한 필드를 변경하려 할 때 발생. 같은 매니저로 최초 생성/적용을 일관되게 수행하거나, 소유자와 조정하라. 정말로 덮어써야 하면 --force-conflicts 사용을 검토.
managedFields가 너무 커진다
잦은 필드 변동/여러 매니저가 섞일 때 발생. 매니저 수를 줄이고, 불필요한 필드 갱신을 피한다.
클라이언트/서버 dry-run 차이
--dry-run=server만이 서버의 실제 검증/병합 경로를 거친다(권장).

7 같이 보기[ | ]

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}