용량 버퍼 구성

용량 버퍼는 Kubernetes CapacityBuffer CustomResourceDefinition (CRD)을 사용하여 예비 클러스터 용량과 사전 프로비저닝된 사전 구성 용량의 일시정지된 상태를 사전에 관리하여 중요한 워크로드의 응답성과 안정성을 개선합니다. 용량 버퍼를 사용하면 클러스터 내에서 사용되지 않는 노드 용량의 특정 양을 명시적으로 정의할 수 있습니다. 이 예약된 용량은 포드 일정 계획 시간을 줄이는 데 도움이 됩니다.

우선순위가 높은 워크로드를 빠르게 수직 확장해야 하는 경우 새 워크로드는 노드 프로비저닝을 기다리지 않고 빈 용량을 즉시 사용할 수 있습니다. 이 접근 방식은 지연 시간을 최소화하고 수요가 급증하는 동안 리소스 경합을 방지합니다.

이 페이지에서는 용량 버퍼를 구성하는 방법(고정 복제본 버퍼, 리소스 한도 버퍼, 비율 기반 버퍼)을 제공합니다.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치했으면 gcloud components update 명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.
  • 활성 버퍼의 경우 버전 1.35.2-gke.1842000, 대기 버퍼의 경우 버전 1.36.0-gke.2253000 이상에서 GKE 클러스터를 만들거나 액세스합니다.
  • 표준 클러스터에서 노드 자동 프로비저닝을(를) 사용 설정합니다. Autopilot 클러스터에서는 노드 자동 프로비저닝이 이미 사용 설정되어 있습니다. 노드 자동 프로비저닝은 선택사항이지만 활성 버퍼에 권장되며 대기 버퍼에 필요합니다.

기본 Kubernetes 객체 만들기

CapacityBuffer를 구성하려면 필요한 모든 객체 (CapacityBuffer 자체 및 PodTemplate 또는 워크로드와 같은 추가 리소스)를 보유하는 네임스페이스가 필요합니다. PodTemplate과 CapacityBuffer는 동일한 네임스페이스에 있어야 합니다. 네임스페이스를 만들거나 default 네임스페이스를 비롯한 기존 네임스페이스를 사용할 수 있습니다.

구성하는 CapacityBuffer 유형에 따라 다음 중 하나도 필요합니다.

  • PodTemplate: 버퍼 용량의 단일 단위에 대한 리소스 요구사항을 정의합니다. CapacityBuffer 객체에 지정된 구성은 포드 템플릿을 참조합니다.
  • 워크로드: CapacityBuffer 객체에서 참조하는 기존 워크로드입니다. 이 가이드에서는 배포 객체를 워크로드 예시로 사용하지만 용량 버퍼는 다음 리소스 유형을 지원합니다.

    • 배포
    • ReplicaSet
    • StatefulSet
    • ReplicationController
    • 작업
    • scale 하위 리소스를 구현하는 CustomResourceDefinition (CRD)

이 섹션에서는 이러한 객체의 예를 제공합니다. 용량 버퍼로 구성하려는 워크로드가 이미 있는 경우 용량 버퍼 적용으로 진행합니다.

예시 Kubernetes 워크로드를 만들려면 다음 단계를 완료하세요.

  1. 다음 매니페스트를 namespace.yaml로 저장합니다.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: capacity-buffer-example
      labels:
        name: capacity-buffer-example
    

    이 매니페스트는 capacity-buffer-example이라는 네임스페이스를 만듭니다.

  2. 선택사항: 커스텀 ComputeClass로 용량 버퍼를 사용하려면 다음 매니페스트를 custom-compute-class.yaml로 저장합니다.

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: ccc-example
      namespace: capacity-buffer-example
    spec:
      # Buffers are also created according to these priorities
      priorities:
      - machineFamily: n4
      - machineFamily: n4d
      - machineFamily: c4
      - machineFamily: c4d
      nodePoolAutoCreation:
        enabled: true
    

    이 매니페스트는 GKE가 프로비저닝하는 노드의 컴퓨팅 우선순위를 정의하고 제어하는 커스텀 ComputeClass를 만듭니다. 자세한 내용은 커스텀 ComputeClass를 참조하세요.

  3. 다음 매니페스트를 buffer-pod-template.yaml로 저장합니다.

    apiVersion: v1
    kind: PodTemplate
    metadata:
      name: buffer-unit-template
      namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer
    template:
      spec:
        terminationGracePeriodSeconds: 0
        containers:
        - name: buffer-container
          image: registry.k8s.io/pause:3.9
          resources:
            requests:
              cpu: "1"
              memory: "1Gi"
            limits:
              cpu: "1"
              memory: "1Gi"
        # Optional: Using buffers with a custom ComputeClass /
        # controls the properties of the provisioned nodes.
        nodeSelector:
          cloud.google.com/compute-class: ccc-example
    

    이 매니페스트는 버퍼 용량의 단일 단위 (1 CPU 및 1Gi 메모리)에 대한 리소스 요구사항 을 정의하는 PodTemplate을 만듭니다. 이 구성은 GKE가 버퍼에 프로비저닝하는 용량 단위의 크기를 지정합니다. 예를 들어 이 PodTemplate을 사용하면 클러스터가 확장될 때 GKE는 사용 가능한 리소스가 1 CPU 및 1Gi 미만인 노드를 버퍼의 일부로 간주하지 않습니다.

  4. 다음 매니페스트를 sample-workload-deployment.yaml로 저장합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: critical-workload-ref
      namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer
    spec:
      replicas: 10
      selector:
        matchLabels:
          app: critical-workload
      template:
        metadata:
          labels:
            app: critical-workload
        spec:
          containers:
          - name: busybox
            image: busybox
            command: ["sleep", "3600"]
            resources:
              requests:
                cpu: 100m
          # Optional: Using buffers with a custom ComputeClass /
          # controls the properties of the provisioned nodes.
          nodeSelector:
            cloud.google.com/compute-class: ccc-example
    

    이 매니페스트는 10개의 복제본이 있는 샘플 배포를 만듭니다. 이는 다음 섹션의 비율 기반 버퍼 예시의 참조 객체입니다.

  5. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f namespace.yaml -f custom-compute-class.yaml -f buffer-pod-template.yaml -f sample-workload-deployment.yaml
    
  6. GKE에서 객체를 만들었는지 확인합니다.

    kubectl get podtemplate -n capacity-buffer-example
    kubectl get deployment critical-workload-ref -n capacity-buffer-example
    

    출력은 다음과 비슷합니다.

    NAME                   AGE
    buffer-unit-template   1m
    
    NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
    critical-workload-ref   10/10   10           10          1m
    

용량 버퍼 적용

이 섹션에서는 워크로드에 적용할 수 있는 다양한 유형의 용량 버퍼의 예를 제공합니다.

고정 복제본 버퍼 구성

고정 복제본으로 CapacityBuffer를 구성하면 PodTemplate을 기반으로 원하는 정확한 버퍼 단위 수를 지정합니다.

고정 복제본으로 버퍼를 만들려면 다음 단계를 완료하세요.

  1. 다음 매니페스트를 cb-fixed-replicas.yaml로 저장합니다.

    apiVersion: autoscaling.x-k8s.io/v1beta1
    kind: CapacityBuffer
    metadata:
      name: fixed-replica-buffer
      namespace: NAMESPACE
    spec:
      podTemplateRef:
        name: POD_TEMPLATE
      replicas: 3
      provisioningStrategy: "STRATEGY"
    

    다음을 바꿉니다.

    • NAMESPACE: 네임스페이스의 이름(예: capacity-buffer-example)
    • POD_TEMPLATE: 리소스 요구사항을 정의하는 PodTemplate(예: buffer-unit-template)
    • STRATEGY: 프로비저닝 전략("buffer.x-k8s.io/active-capacity"(기본값) 또는 "buffer.gke.io/standby-capacity")

    이 매니페스트는 특정 수의 버퍼 단위를 요청하기 위해 PodTemplate을 참조하는 CapacityBuffer 리소스를 만듭니다.

  2. 매니페스트를 적용합니다.

    kubectl apply -f cb-fixed-replicas.yaml
    
  3. GKE에서 용량 버퍼를 적용했는지 확인합니다.

    kubectl get capacitybuffer fixed-replica-buffer -n NAMESPACE
    

    상태의 replicas 필드에는 매니페스트에 정의한 복제본 수를 반영하는 3이 표시되어야 합니다. STATUS 필드에는 ReadyForProvisioning이 표시되어야 합니다.

리소스 한도 버퍼 구성

limits 필드를 사용하여 PodTemplate 크기를 기준으로 계산된 버퍼가 소비해야 하는 최대 리소스 양을 정의할 수 있습니다.

리소스 한도 버퍼를 만들려면 다음 단계를 완료하세요.

  1. 다음 매니페스트를 cb-resource-limits.yaml로 저장합니다.

    apiVersion: autoscaling.x-k8s.io/v1beta1
    kind: CapacityBuffer
    metadata:
      name: resource-limit-buffer
      namespace: NAMESPACE
    spec:
      podTemplateRef:
        name: POD_TEMPLATE
      limits:
        cpu: "5"
        memory: "5Gi"
      provisioningStrategy: "STRATEGY"
    

    다음을 바꿉니다.

    • NAMESPACE: 네임스페이스의 이름(예: capacity-buffer-example)
    • POD_TEMPLATE: 리소스 요구사항을 정의하는 PodTemplate(예: buffer-unit-template)
    • STRATEGY: 프로비저닝 전략("buffer.x-k8s.io/active-capacity"(기본값) 또는 "buffer.gke.io/standby-capacity")

    이 매니페스트는 총 5개의 CPU와 5GiB 메모리 한도가 있는 CapacityBuffer 리소스를 만듭니다. 이전 단계의 PodTemplate 예시를 사용하는 경우 각 단위를 1 CPU 및 1Gi 메모리로 정의하면 5 개의 버퍼 단위가 생성됩니다.

  2. 매니페스트를 적용합니다.

    kubectl apply -f cb-resource-limits.yaml
    
  3. GKE에서 용량 버퍼를 적용했는지 확인합니다.

    kubectl get capacitybuffer resource-limit-buffer -n NAMESPACE
    

    CapacityBuffer 상태를 확인합니다. replicas 필드에는 정의한 한도에서 파생된 값이 표시되어야 합니다. 이전 섹션의 PodTemplate 예시를 사용하는 경우 정의된 한도 내에 맞는 최대 단위 수이므로 5 버퍼 단위가 표시되어야 합니다.

비율 기반 버퍼 구성

비율 기반 버퍼를 구성하면 기존 확장 가능한 워크로드의 비율을 기반으로 버퍼 크기가 동적으로 조정됩니다. 비율 기반 용량 버퍼 는 확장 하위 리소스를 구현하는 배포, StatefulSet, ReplicaSet 또는 작업과 같은 Kubernetes 확장 가능한 객체에만 지원됩니다. 포드 템플릿에는 replicas 필드가 없으므로 비율 기반 버퍼를 정의할 수 없습니다.

일반적으로 비율 기반 버퍼보다는 고정 복제본 또는 리소스 한도 전략으로 시작하는 것이 좋습니다. 워크로드가 낮은 수 또는 0으로 확장되는 경우 비율 기반 버퍼는 안전 여유가 활성 포드에 비례하여 확장되므로 갑작스러운 확장에는 덜 반응합니다. 매우 낮은 복제본 수로 확장되지 않는 대규모 배포에 주로 유용합니다.

비율 기반 버퍼를 만들려면 다음 단계를 완료하세요.

  1. 다음 매니페스트를 cb-percentage-based.yaml로 저장합니다.

    apiVersion: autoscaling.x-k8s.io/v1beta1
    kind: CapacityBuffer
    metadata:
      name: percentage-buffer
      namespace: NAMESPACE
    spec:
      scalableRef:
        apiGroup: apps
        kind: Deployment
        name: SCALABLE_RESOURCE_NAME
      percentage: 20
      provisioningStrategy: "STRATEGY"
    

    다음을 바꿉니다.

    • NAMESPACE: 네임스페이스의 이름
    • SCALABLE_RESOURCE_NAME: 확장 가능한 리소스의 이름(예: critical-workload-ref)
    • STRATEGY: 프로비저닝 전략("buffer.x-k8s.io/active-capacity"(기본값) 또는 "buffer.gke.io/standby-capacity")

    이 매니페스트는 참조된 리소스의 복제본의 20% 에 해당하는 버퍼 크기를 요청하는 CapacityBuffer 리소스를 만듭니다. 이전 섹션의 배포 예시를 사용하는 경우 복제본 값은 10으로 설정됩니다.

  2. 매니페스트를 적용합니다.

    kubectl apply -f cb-percentage-based.yaml
    
  3. GKE에서 용량 버퍼를 적용했는지 확인합니다.

    kubectl get capacitybuffer percentage-buffer -n NAMESPACE
    

    CapacityBuffer 상태를 확인합니다. replicas 필드에는 비율 계산에서 파생된 값이 표시되어야 합니다. 이전 섹션의 배포 예시를 사용하는 경우 배포에 정의된 10개의 복제본의 20% 인 2 버퍼 단위가 표시되어야 합니다.

  4. 배포를 최대 20개의 복제본으로 수동으로 확장하여 동적 확장을 테스트합니다.

    kubectl scale deployment critical-workload-ref -n NAMESPACE --replicas=20
    

    CapacityBuffer 컨트롤러가 반응하고 버퍼를 4개의 복제본으로 자동 확장합니다.

대기 버퍼 동작 맞춤설정

주석을 사용하여 대기 버퍼가 시작되고 새로고침되는 방식을 맞춤설정할 수 있습니다. CapacityBuffer 리소스의 metadata.annotations 필드에 이러한 주석을 추가합니다.

  • buffer.gke.io/standby-capacity-init-time: 노드가 생성된 후 일시정지되기 전에 활성 상태로 유지되는 시간입니다. 형식은 기간 문자열 (예: 5m 또는 1h)입니다. 기본값은 5m입니다.
  • buffer.gke.io/standby-capacity-refresh-frequency: 일시정지된 노드가 새로고침되는 빈도입니다. 기본값은 1d입니다.

다음 예시는 대기 버퍼의 동작을 맞춤설정하기 위한 이러한 선택적 필드가 포함된 매니페스트를 보여줍니다.

apiVersion: autoscaling.x-k8s.io/v1beta1
kind: CapacityBuffer
metadata:
  name: customized-standby-buffer
  namespace: my-namespace
  annotations:
    buffer.gke.io/standby-capacity-init-time: "15m"
    buffer.gke.io/standby-capacity-refresh-frequency: "12h"
spec:
  podTemplateRef:
    name: buffer-unit-template
  replicas: 3
  provisioningStrategy: "buffer.gke.io/standby-capacity"

대기 버퍼에 이미지 미리 로드

대기 노드가 재개될 때 워크로드 시작 시간을 단축하려면 DaemonSet를 사용하여 컨테이너 이미지를 미리 로드할 수 있습니다. DaemonSet는 노드가 일시정지되기 전 시작 기간 동안 실행됩니다.

DaemonSet를 사용하여 이미지를 미리 로드하려면 다음 단계를 완료하세요.

  1. 다음 매니페스트를 image-puller-daemonset.yaml로 저장합니다.

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: image-prefetch-daemonset
      namespace: NAMESPACE
    spec:
      selector:
        matchLabels:
          name: image-prefetch
      template:
        metadata:
          labels:
            name: image-prefetch
        spec:
          tolerations:
          - key: "buffer.gke.io/standby-node-suspended"
            operator: "Exists"
          initContainers:
          - name: image-puller
            image: IMAGE_NAME
            command: ["sh", "-c", "true"]
          containers:
          - name: pause
            image: registry.k8s.io/pause:3.9
    

    다음을 바꿉니다.

    • NAMESPACE: DaemonSet의 네임스페이스(예: capacity-buffer-example)
    • IMAGE_NAME: 미리 로드할 이미지의 이름(예: your-app-image:latest)
  2. DaemonSet 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f image-puller-daemonset.yaml
    
  3. DaemonSet가 생성되었는지 확인합니다.

    kubectl get daemonset image-prefetch-daemonset -n NAMESPACE
    
  4. 용량 버퍼가 생성되고 프로비저닝할 준비가 되었는지 확인합니다.

    kubectl get capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
    

    상태를 확인합니다. STATUS 필드에는 ReadyForProvisioning이 표시되어야 합니다.

용량 버퍼 상태 및 성능 모니터링

kubectl 명령어와 Cloud Monitoring 측정항목을 사용하여 용량 버퍼의 상태와 상태를 모니터링할 수 있습니다.

CapacityBuffer 리소스 상태 확인

용량 버퍼의 상태를 확인하고 워크로드를 수신할 준비가 되었는지 확인하려면 다음 단계를 완료하세요.

  1. 클러스터의 모든 용량 버퍼의 상태를 가져옵니다.

    kubectl get capacitybuffer -A
    
  2. 특정 버퍼의 세부 상태, 조건, 이벤트 로그를 검사합니다.

    kubectl describe capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
    

일시정지된 대기 버퍼 노드 식별

대기 버퍼 VM은 사전 프로비저닝되지만 비용 절감을 위해 일시정지된 상태로 유지됩니다. 이러한 일시정지된 노드는 커스텀 조건이 있으므로 인식할 수 있습니다. 일시정지된 노드 인스턴스를 감사하려면 다음 명령어를 실행합니다.

kubectl get nodes -o custom-columns='NAME:.metadata.name,SUSPENDED:.status.conditions[?(@.type=="Suspended")].status'

True 상태는 대기 VM이 일시정지되었음을 나타냅니다. False 또는 <none> 상태는 활성 상태의 실행 중인 노드를 나타냅니다.

Cloud Monitoring으로 성능 모니터링

용량 버퍼의 성능을 모니터링하려면 Cloud Monitoring에서 다음 리소스를 모니터링하세요.

  • 반응 지연 시간 (cluster_autoscaler/reaction_time_milliseconds): CapacityBuffer 보류 중인 수요를 기반으로 클러스터 자동 확장 처리가 확장 결정을 내리는 데 걸리는 시간을 추적합니다.
  • 클러스터 자동 확장 처리 로그: "Capacity pod processor injecting ..."과 같은 로그 항목을 검색하여 활성 버퍼 포드 교체 이벤트를 관찰합니다.

용량 버퍼 삭제

워크로드에 더 이상 용량 버퍼가 필요하지 않으면 CapacityBuffer 객체를 삭제합니다. 이렇게 하면 자리표시자 포드가 삭제되고 클러스터 자동 확장 처리가 노드를 축소할 수 있습니다.

kubectl delete capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE

CAPACITY_BUFFER_NAME을 삭제할 CapacityBuffer의 이름으로 바꿉니다.

문제 해결

다음 섹션에는 용량 버퍼의 일반적인 문제를 해결하는 방법에 대한 정보가 포함되어 있습니다.

청구 모델로 인해 용량 버퍼가 준비되지 않음

포드 기반 청구 모델(포드당 결제)을 사용하는 워크로드에 CapacityBuffer를 만드는 경우 용량 버퍼는 프로비저닝할 준비가 되지 않습니다.

이 문제를 식별하려면 CapacityBuffer 상태를 확인하세요.

kubectl describe capacitybuffer BUFFER_NAME -n NAMESPACE

상태가 FalseReadyForProvisioning 유형의 조건을 찾습니다.

이 문제를 해결하려면 CapacityBuffer가 노드 기반 청구와 호환되는 워크로드 또는 PodTemplate을 참조하는지 확인하세요.

커스텀 확장 가능한 리소스의 권한 오류

scalableRef 필드를 사용하여 커스텀 확장 가능한 객체와 함께 작동하도록 CapacityBuffer를 구성하는 경우 클러스터 자동 확장 처리에 필요한 권한이 없으면 버퍼를 확장하지 못할 수 있습니다.

이 문제를 해결하려면 다음 예와 같이 ClusterRoleClusterRoleBinding을 만들어 필요한 권한을 수동으로 부여하세요.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: custom-scale-getter
rules:
- apiGroups: ["api.example.com"]
  resources: ["customreplicatedresources/scale"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ca-custom-scale-getter
subjects:
- kind: User
  name: "system:cluster-autoscaler"
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: custom-scale-getter

RBAC 구성에 대한 자세한 내용은 Kubernetes RBAC 문서를 참조하세요.

다음 단계