kubectl apply 대 set: 리소스 업데이트에 적합한 명령어 선택

쿠버네티스 리소스 업데이트 관리를 위해 `kubectl apply`(선언적)와 `kubectl set`/`kubectl edit`(명령적) 간의 중요한 선택을 탐색합니다. 이 종합 가이드는 각 명령어가 어떻게 작동하는지, 근본적인 차이점은 무엇인지, 그리고 언제 효과적으로 사용해야 하는지를 분석합니다. 일관성과 GitOps를 위해 선언적 관리를 활용하는 방법을 배우고, 빠르고 임시적인 수정에 대한 명령적 명령어의 역할을 이해하십시오. 구성 드리프트를 방지하고 안정적이며 감사 가능한 쿠버네티스 배포를 보장하기 위한 모범 사례를 숙달하십시오.

32 조회수

kubectl apply 대 set: 리소스 업데이트를 위한 올바른 명령어 선택

컨테이너 오케스트레이션 플랫폼의 선두 주자인 쿠버네티스는 애플리케이션 수명 주기를 관리하기 위한 강력한 도구를 제공합니다. 이러한 관리의 핵심 측면에는 Deployment, Service, ConfigMap과 같은 기존 리소스를 업데이트하는 작업이 포함됩니다. kubectl은 이 목적을 위해 여러 명령어를 제공하지만, kubectl applykubectl set/kubectl edit 계열은 선언적 업데이트 대 명령형 업데이트라는 근본적으로 다른 두 가지 철학을 나타냅니다.

각 접근 방식을 언제 어떻게 사용할지 이해하는 것은 안정적이고 신뢰할 수 있으며 감사 가능한 쿠버네티스 배포를 유지하는 데 중요합니다. 이러한 명령어를 잘못 사용하면 구성 불일치, 디버깅 어려움, 운영상의 비일관성으로 이어질 수 있습니다. 이 문서는 kubectl apply, kubectl set, kubectl edit의 미묘한 차이점을 자세히 다루어 리소스 업데이트 전략에 대한 정보에 입각한 결정을 내릴 수 있는 지식을 제공할 것입니다.

핵심 과제: 리소스 상태 관리

쿠버네티스에서 실행 중인 Pod부터 네트워크 Service에 이르기까지 모든 구성 요소는 API 객체로 표현됩니다. 이러한 객체에는 YAML 또는 JSON 매니페스트 파일에 정의된 원하는 상태(desired state)와 클러스터 내 현재 상태를 반영하는 관찰된 상태(observed state)가 있습니다. 모든 kubectl 업데이트 명령어의 주요 목표는 이 두 상태를 일치시키는 것이지만, 일치시키는 방법은 상당히 다릅니다.

kubectl apply 이해하기: 선언적 접근 방식

kubectl apply는 쿠버네티스에서 선언적 리소스 관리의 초석입니다. 이 접근 방식에서는 로컬 구성 파일(또는 파일 디렉터리)에 리소스의 원하는 상태를 정의한 다음, 쿠버네티스에게 클러스터 상태가 해당 정의와 일치하도록 지시합니다.

kubectl apply 작동 방식 (3-Way 병합)

kubectl apply -f your-manifest.yaml을 실행하면 쿠버네티스는 정교한 3-Way 병합(three-way merge)을 수행합니다:

  1. 마지막 적용 구성 (Last Applied Configuration): kubectl apply를 사용하여 마지막으로 적용되었을 때의 리소스 상태입니다. 이 상태는 라이브 객체의 주석(kubectl.kubernetes.io/last-applied-configuration)에 저장됩니다.
  2. 라이브 구성 (Live Configuration): 쿠버네티스 API 서버에 있는 리소스의 현재 상태입니다.
  3. 새 구성 (New Configuration): your-manifest.yaml 파일에 정의된 상태입니다.

병합 알고리즘은 이 세 가지 버전을 비교하여 어떤 변경 사항을 만들어야 하는지 결정합니다. 이는 새 구성의 변경 사항을 우선시하면서 마지막 apply 이후 명령형으로 수정된 필드를 존중하면서 지능적으로 충돌을 처리합니다(아래에서 설명하듯이 이는 문제로 이어질 수 있음).

이 프로세스는 동일한 매니페스트를 여러 번 적용해도 의도하지 않은 부작용 없이 동일한 클러스터 상태를 초래하는 멱등성(idempotency)을 보장합니다(다른 변경 사항이 발생하지 않았다고 가정할 때).

실용적인 예시: Deployment 적용

다음과 같은 deployment.yaml 파일이 있다고 가정해 봅시다.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-webapp
  labels:
    app: my-webapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-webapp
  template:
    metadata:
      labels:
        app: my-webapp
    spec:
      containers:
      - name: webapp-container
        image: nginx:1.21.0
        ports:
        - containerPort: 80

이 배포를 생성하거나 업데이트하려면 다음을 실행합니다.

kubectl apply -f deployment.yaml

나중에 deployment.yaml에서 imagenginx:1.22.0으로 변경하고 kubectl apply를 다시 실행하면, 쿠버네티스는 다른 설정을 유지하면서 배포를 업데이트하여 새 이미지를 사용하도록 합니다.

kubectl apply의 이점

  • 진실의 원천 (Source of Truth): 구성 파일이 클러스터의 원하는 상태에 대한 단일 진실의 원천이 됩니다. 이는 GitOps 원칙과 잘 맞습니다.
  • 감사 가능성 및 버전 제어: 변경 사항이 버전 제어 시스템(예: Git)에 추적되어 명확한 감사 추적 및 쉬운 롤백이 가능합니다.
  • 일관성: 환경(개발, 스테이징, 프로덕션) 전반의 일관성을 보장합니다.
  • 멱등성: 반복적인 apply 작업은 의도하지 않은 수정을 방지하며 동일한 결과를 가져옵니다.
  • 복잡한 업데이트: 여러 리소스 유형이나 많은 필드에 걸친 상당한 변경 사항을 처리합니다.

kubectl apply를 사용해야 하는 경우

  • 모든 리소스 생성 및 업데이트의 기본 방법.
  • CI/CD 파이프라인을 통해 애플리케이션을 배포할 때.
  • 코드로서의 인프라(Infrastructure-as-Code)를 관리할 때.
  • 일관된 구성을 보장하기 위해 팀과 협력할 때.

kubectl apply에 대한 팁 및 경고

  • 매니페스트 파일을 항상 원하는 상태로 최신 상태로 유지하십시오. kubectl set 또는 kubectl edit으로 수행된 변경 사항이 매니페스트 파일에 반영되지 않으면 다음 apply 시 덮어쓰여지거나 병합 충돌이 발생합니다.
  • 필드 관리자 (Field Managers): 쿠버네티스 1.16 이상에서는 서버 측 적용(SSA)이 도입되어 리소스의 각 필드를 책임지는 "필드 관리자"(kubectl 또는 컨트롤러 등)를 추적합니다. 이는 여러 소스가 동일한 리소스를 수정할 때 충돌을 방지하는 데 도움이 됩니다. 강력하지만 다양한 도구가 필드 관리에 어떻게 상호 작용하는지 인지해야 합니다.

kubectl setkubectl edit 이해하기: 명령형 접근 방식

kubectl setkubectl edit은 명령형 명령어 계열에 속합니다. 파일에 원하는 상태를 정의하는 대신, 특정 작업을 수행하거나 클러스터 내 라이브 객체를 수정하도록 쿠버네티스에 직접 지시합니다. 이 명령어들은 빠르고 임시적인 변경에 탁월하지만 몇 가지 주의 사항이 따릅니다.

kubectl set: 집중된 명령형 수정

kubectl set은 매니페스트 파일을 건드릴 필요 없이 리소스에 대한 특정하고 일반적인 수정을 수행하도록 설계되었습니다. 특정 필드를 수정하기 위한 여러 하위 명령어를 제공합니다.

kubectl set 작동 방식

kubectl set은 제공된 명령줄 인수를 기반으로 쿠버네티스 API 서버의 라이브 객체를 직접 수정합니다. 로컬 매니페스트 파일이나 last-applied-configuration 주석과는 상호 작용하지 않습니다.

실용적인 예시: 이미지 설정

my-webapp이라는 배포 내 컨테이너의 이미지를 업데이트하려면 다음을 수행합니다.

kubeclt set image deployment/my-webapp webapp-container=nginx:1.22.0

이 명령어는 my-webapp 배포 내의 webapp-container에 대한 image 필드를 직접 수정합니다. 이전에 kubectl applymy-webapp을 관리했다면, 이 변경은 로컬 deployment.yaml과 라이브 클러스터 상태 사이에 "불일치(drift)"를 생성합니다.

기타 일반적인 kubectl set 명령어:

  • kubectl set resources: 리소스 요청/제한을 설정합니다.
  • kubectl set env: 환경 변수를 추가하거나 업데이트합니다.
  • kubectl set selector: 리소스의 선택기를 수정합니다.

kubectl edit: 대화형 명령형 수정

kubectl edit을 사용하면 구성된 기본 텍스트 편집기(예: vi, nano)를 사용하여 클러스터의 라이브 리소스 객체의 모든 필드를 직접 수정할 수 있습니다.

kubectl edit 작동 방식

kubectl edit <리소스 유형>/<리소스 이름>을 실행하면 다음이 발생합니다.

  1. kubectl이 API 서버에서 라이브 리소스의 현재 YAML 정의를 가져옵니다.
  2. 로컬 텍스트 편집기에서 해당 정의를 엽니다.
  3. 원하는 변경 사항을 만들고 파일을 저장합니다.
  4. kubectl은 수정된 정의를 API 서버로 다시 보내 변경 사항을 적용하려고 시도합니다. 구문 오류나 유효하지 않은 필드가 있으면 변경 사항이 거부됩니다.

kubectl set과 마찬가지로 kubectl edit도 라이브 객체에서 직접 작동하며 로컬 매니페스트 파일이나 last-applied-configuration 주석을 업데이트하지 않습니다.

실용적인 예시: 배포 편집

편집기에서 my-webapp 배포를 열려면 다음을 사용합니다.

kubeclt edit deployment/my-webapp

편집기가 라이브 배포의 YAML 표현과 함께 열립니다. 그런 다음 replicas, image와 같은 필드를 변경하거나 새 주석/레이블을 추가할 수 있습니다. 편집기를 저장하고 닫으면 kubectl이 해당 변경 사항을 적용하려고 시도합니다.

kubectl setkubectl edit의 이점

  • 속도: 개발 환경에서 빠르고 일회성 수정 또는 디버깅에 탁월합니다.
  • 유연성: 리소스의 모든 필드를 직접 수정할 수 있습니다 (edit 사용 시).
  • 임시 변경: 매니페스트 파일이 즉시 준비되지 않았거나 사소한 변경을 위해 파일을 만들고 싶지 않을 때 유용합니다.

kubectl set/kubectl edit을 사용해야 하는 경우

  • 개발/스테이징 클러스터에서의 디버깅: 복제본 수를 일시적으로 늘리거나 이미지를 변경하여 수정을 테스트하는 경우.
  • 비프로덕션 환경에서 작고 중요하지 않은 임시 변경 사항.
  • 리소스 정의 탐색: kubectl edit은 리소스의 전체 라이브 YAML을 확인하는 편리한 방법입니다.

kubectl setkubectl edit에 대한 경고

  • 구성 불일치: set 또는 edit으로 수행된 변경 사항은 로컬 매니페스트 파일에 반영되지 않습니다. 매니페스트 파일에서 다음 kubectl apply를 실행하면 이러한 명령형 변경 사항이 덮어쓰여지거나 충돌이 발생합니다.
  • 감사 가능성 부족: 이러한 변경 사항은 버전 제어에 추적되지 않으므로 누가 언제 무엇을 변경했는지 파악하기 어려워 디버깅 및 규정 준수를 방해합니다.
  • 비멱등성: 동일한 명령형 변경을 반복적으로 수행하면 초기 상태를 알 수 없을 때 예상치 못한 동작으로 이어질 수 있습니다.
  • 오류 위험: (특히 edit을 사용하는) 수동 편집은 구문 오류나 유효하지 않은 구성을 도입할 가능성을 높입니다.

주요 차이점: kubectl applykubectl set/kubectl edit

핵심적인 차이점을 요약하면 다음과 같습니다.

기능 kubectl apply (선언적) kubectl set/kubectl edit (명령형)
접근 방식 파일에 원하는 상태를 정의하면 쿠버네티스가 조정합니다. 라이브 객체 또는 특정 필드를 직접 조작합니다.
진실의 원천 로컬 구성 파일 (예: Git 저장소). 라이브 클러스터 객체 자체 (일시적).
멱등성 예. 동일한 파일을 적용하면 동일한 결과가 나옵니다. 아니요, 본질적으로 그렇지 않습니다. 각 명령어는 명시적인 동작입니다.
감사 가능성 높음 (Git, last-applied-configuration에 변경 사항 추적). 낮음 (버전 제어 없음, 변경 사항이 클러스터에 즉시 적용됨).
충돌 관리 3-Way 병합, last-applied-configuration 주석 사용. 직접 덮어쓰기 (set의 경우) 또는 대화형 병합 (edit의 경우).
사용 사례 프로덕션 배포, CI/CD, GitOps, 팀 협업. 빠른 수정, 디버깅, 비프로덕션 환경에서의 임시 변경.
불일치 위험 낮음, 파일이 최신 상태로 유지되는 한. 높음, 소스 파일과의 구성 불일치를 유발할 가능성이 매우 높음.

올바른 명령어 선택: 모범 사례

프로덕션 환경 및 협업 팀의 경우 선택은 명확합니다.

  • 쿠버네티스 리소스 관리를 위해 항상 kubectl apply(또는 이를 기반으로 구축된 Argo CD 또는 Flux CD와 같은 GitOps 도구)를 선호하십시오. 이렇게 하면 클러스터 상태가 버전 제어되고, 감사 가능하며, 일관성이 유지됩니다.
  • 쿠버네티스 매니페스트 파일을 단일 진실의 원천으로 취급하십시오. 리소스 구성에 대한 모든 변경 사항은 이상적으로 이러한 파일에서 시작되어 버전 제어 시스템에 커밋되어야 합니다.

kubectl setkubectl edit과 같은 명령형 명령어는 다음 용도로 보류해야 합니다.

  • 개발/스테이징 클러스터에서의 임시 디버깅 또는 테스트. 이들을 사용한다면, 변경 사항을 되돌리거나 변경 사항을 즉시 소스 매니페스트 파일에 반영하여 새 상태를 반영하도록 해야 합니다.
  • 일시적인 상태를 나타내지 않는 일회성, 임시 작업 (예: 배포를 잠시 일시 중지하는 작업).

하이브리드 접근 방식 (주의해서 사용)

어떤 시나리오에서는 프로덕션에서 무언가를 빠르게 긴급 수정해야 할 수도 있습니다. 일반적으로 권장되지는 않지만, kubectl edit을 사용해야 한다면 다음을 수행해야 합니다.

  1. 구성 불일치의 영향을 이해하십시오.
  2. kubectl get <리소스> -o yaml > new-manifest.yaml을 실행하여 변경 사항을 즉시 캡처하십시오.
  3. 해당 변경 사항을 가능한 한 빨리 버전 제어된 매니페스트 파일에 통합하십시오.

경고: 소스 매니페스트를 업데이트하지 않고 프로덕션에서 정기적으로 kubectl edit 또는 kubectl set을 사용하면 실제 구성이 팀이 생각하는 것과 크게 벗어나는 관리 불가능하고 복구 불가능한 클러스터 상태로 이어질 것입니다.

결론

kubectl apply, kubectl set, kubectl edit은 모두 쿠버네티스 클러스터와 상호 작용하는 강력한 도구입니다. 그러나 이들은 서로 다른 목적을 가지며 리소스 관리에 대한 뚜렷한 철학을 구현합니다. kubectl apply의 선언적 특성과 kubectl setkubectl edit의 명령형 특성을 이해함으로써 보다 안정적이고 신뢰할 수 있으며 유지 관리가 용이한 쿠버네티스 배포로 이어지는 모범 사례를 채택할 수 있습니다.

거의 모든 영구적인 리소스 관리를 위해, 특히 프로덕션 환경에서는 kubectl apply를 채택하고 구성 파일을 버전 제어하십시오. 임시적인 문제 해결을 위해 명령형 명령어를 보류하고, 중요한 변경 사항은 신속하게 선언적 매니페스트에 다시 반영되도록 하십시오. 이러한 규율은 원활한 운영과 쿠버네티스 환경 내 원활한 협업에 매우 중요할 것입니다.