이 페이지에서는 트래픽이 많은 이벤트 중에 새 노드가 시작될 때까지 기다리지 않고 워크로드가 빠르게 확장할 수 있도록 Google Kubernetes Engine(GKE) 클러스터에서 추가 컴퓨팅 용량을 예약하는 방법을 설명합니다. 이 안내를 따라 일관된 사용 기준에 따라서나 특정 이벤트에 앞서 컴퓨팅 오버헤드를 예약할 수 있습니다.
예비 용량 프로비저닝이 유용한 이유
GKE Autopilot 클러스터와 노드 자동 프로비저닝이 포함된 표준 클러스터는 기존 노드에 새 포드를 실행할 용량이 없으면 새 노드를 만듭니다. 각 새 노드를 부팅하는 데 약 80~120초가 걸립니다. GKE는 노드가 시작될 때까지 기다린 후 새 노드에 대기 중인 포드를 배치하며, 포드는 그 다음에 부팅될 수 있습니다. 또는 표준 클러스터에서 새 포드를 실행하는 데 필요한 추가 용량이 있는 새 노드 풀을 수동으로 만들 수 있습니다. 이 페이지는 Autopilot 또는 노드 자동 프로비저닝과 같은 노드 자동 확장 메커니즘을 사용하는 클러스터에 적용됩니다.
경우에 따라 확장 이벤트 중에 포드가 더 빠르게 부팅되도록 할 수 있습니다. 예를 들어 인기 있는 라이브 서비스 멀티플레이어 게임의 새로운 확장을 출시하는 경우, 게임 서버 포드의 부팅 시간이 빨라지면 출시일에 로그인하는 플레이어의 큐 타임이 단축될 수 있습니다. 또 다른 예로 전자상거래 플랫폼을 운영하는데 한시적으로 반짝 세일을 계획하는 경우 판매 기간 동안 트래픽 버스트가 발생할 수 있습니다.
예비 용량 프로비저닝은 포드 버스팅과 호환되므로 다른 포드에서 해당 용량을 사용할 수 있고 아직 사용되지 않는 경우 포드에서 해당 노드의 다른 포드에서 요청한 리소스를 일시적으로 사용할 수 있습니다. 버스팅을 사용하려면 리소스 한도를 리소스 요청보다 높게 설정하거나 리소스 한도를 설정하지 않습니다. 자세한 내용은 GKE에서 포드 버스팅 구성을 참조하세요.
GKE에서 예비 용량 프로비저닝 작동 방식
예비 용량을 프로비저닝하려면 Kubernetes PriorityClasses 및 자리표시자 포드를 사용할 수 있습니다. PriorityClass를 사용하면 일부 워크로드가 다른 워크로드보다 우선순위가 낮음을 GKE에 알릴 수 있습니다. 우선순위가 낮은 PriorityClass를 사용하는 자리표시자 포드를 배포하고 예약해야 하는 컴퓨팅 용량을 요청할 수 있습니다. GKE는 자리표시자 포드를 수용하기 위해 새 노드를 만들어 클러스터에 용량을 추가합니다.
프로덕션 워크로드가 확장되면 GKE는 우선순위가 낮은 자리표시자 포드를 삭제하고 그 자리에 프로덕션 포드(더 높은 우선순위 PriorityClass 사용)의 새 복제본을 예약합니다. 우선순위 수준이 다른 낮은 우선순위의 포드가 여러 개 있는 경우 GKE는 우선순위가 가장 낮은 포드를 먼저 제거합니다.
용량 프로비저닝 방법
사용 사례에 따라 다음 방법 중 하나로 GKE 클러스터에 추가 용량을 프로비저닝할 수 있습니다.
- 일관된 용량 프로비저닝: 배포를 사용하여 클러스터에서 지속적으로 실행되는 우선순위가 낮은 특정 수의 자리표시자 포드를 만듭니다. GKE가 프로덕션 워크로드를 실행하기 위해 이러한 포드를 제거하면 배포 컨트롤러는 GKE가 제거된 우선순위가 낮은 포드를 다시 만들 수 있는 용량을 더 많이 프로비저닝하도록 합니다. 이 방법은 배포를 삭제할 때까지 여러 확장 및 축소 이벤트 간에 일관된 용량 오버헤드를 제공합니다.
- 단일 사용 용량 프로비저닝: 작업을 사용하여 특정 기간 동안 우선순위가 낮은 특정 수의 동시 자리표시자 포드를 실행합니다. 이 시간이 경과하거나 GKE가 모든 작업 복제본을 삭제하면 예약된 용량을 사용할 수 없습니다. 이 메서드는 특정 기간 동안 특정한 사용 가능한 용량을 제공합니다.
가격 책정
GKE Autopilot에서는 배포한 우선순위가 낮은 워크로드를 포함하여 실행 중인 포드의 리소스 요청에 대한 요금이 청구됩니다. 자세한 내용은 Autopilot 가격 책정을 참조하세요.
GKE Standard에서는 포드가 해당 용량을 사용하는지 여부에 관계없이 GKE가 프로비저닝하는 기본 Compute Engine VM에 대한 요금이 청구됩니다. 자세한 내용은 Standard 가격 책정을 참조하세요.
시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우
gcloud components update
를 실행하여 최신 버전을 가져옵니다.
- GKE Autopilot 클러스터 또는 노드 자동 프로비저닝이 사용 설정된 GKE Standard 클러스터가 있는지 확인합니다.
- 용량 프로비저닝에 적합한 값을 선택할 수 있도록 용량 프로비저닝의 고려사항을 읽어보세요.
PriorityClass 만들기
용량 프로비저닝 방법에 설명된 방법 중 하나를 사용하려면 먼저 다음 PriorityClass를 만들어야 합니다.
- 기본 PriorityClass: 포드 사양에서 다른 PriorityClass를 명시적으로 설정하지 않는 모든 포드에 할당된 전역 기본 PriorityClass입니다. 이 기본 PriorityClass가 있는 포드는 더 낮은 PriorityClass를 사용하는 포드를 제거할 수 있습니다.
- 낮은 PriorityClass: GKE에서 가능한 가장 낮은 우선순위로 설정된 기본이 아닌 PriorityClass입니다. 이 PriorityClass가 있는 포드는 PriorityClass가 더 높은 포드를 실행하도록 제거될 수 있습니다.
다음 매니페스트를
priorityclasses.yaml
로 저장합니다.apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: -10 preemptionPolicy: Never globalDefault: false description: "Low priority workloads" --- apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: default-priority value: 0 preemptionPolicy: PreemptLowerPriority globalDefault: true description: "The global default priority."
이 매니페스트에는 다음 필드가 포함됩니다.
preemptionPolicy
: PriorityClass를 사용하는 포드가 우선순위가 더 낮은 포드를 제거할 수 있는지 여부를 지정합니다.low-priority
PriorityClass는Never
를 사용하고default
PriorityClass는PreemptLowerPriority
를 사용합니다.value
: PriorityClass를 사용하는 포드의 우선순위입니다.default
PriorityClass는0
을 사용합니다.low-priority
PriorityClass는-10
을 사용합니다. Autopilot에서는default
PriorityClass 우선순위보다 작은 값으로 이 값을 설정할 수 있습니다.Standard에서 이 값을
-10
미만으로 설정하면 해당 PriorityClass를 사용하는 포드가 새 노드 만들기를 트리거하지 않고 Pending 상태로 유지됩니다.적절한 우선순위 값을 결정하는 데 도움이 필요하면 우선순위 선택을 참조하세요.
globalDefault
: GKE 사양에서 포드가 PriorityClass를 명시적으로 설정하지 않는 포드에 PriorityClass를 할당할지 여부를 지정합니다.low-priority
PriorityClass는false
를 사용하고default
PriorityClass는true
를 사용합니다.
매니페스트 적용
kubectl apply -f priorityclasses.yaml
추가 컴퓨팅 용량 프로비저닝
다음 섹션에서는 단일 이벤트에 대해 또는 시간 경과에 따라 일관적으로 용량을 프로비저닝하는 예시를 보여줍니다.
일관된 용량 프로비저닝에 배포 사용
다음 매니페스트를
capacity-res-deployment.yaml
로 저장합니다.apiVersion: apps/v1 kind: Deployment metadata: name: capacity-res-deploy spec: replicas: 10 selector: matchLabels: app: reservation template: metadata: labels: app: reservation spec: priorityClassName: low-priority terminationGracePeriodSeconds: 0 containers: - name: ubuntu image: ubuntu command: ["sleep"] args: ["infinity"] resources: requests: cpu: 500m memory: 500Mi
이 매니페스트에는 다음 필드가 포함됩니다.
spec.replicas
: 요구사항에 맞게 이 값을 변경합니다.spec.resources.requests
: 요구사항을 충족하도록 CPU 및 메모리 요청을 변경합니다. 용량 크기 선택의 안내에 따라 적절한 요청 값을 결정할 수 있습니다.spec.containers.command
및spec.containers.args
: GKE에서 제거할 때까지 활성 상태로 유지하도록 포드에 지시합니다.
매니페스트 적용
kubectl apply -f capacity-res-deployment.yaml
포드 상태를 가져옵니다.
kubectl get pods -l app=reservation
모든 복제본이
Running
상태가 될 때까지 기다립니다.
단일 이벤트 용량 프로비저닝에 작업 사용
다음 매니페스트를
capacity-res-job.yaml
로 저장합니다.apiVersion: batch/v1 kind: Job metadata: name: capacity-res-job spec: parallelism: 4 backoffLimit: 0 template: spec: priorityClassName: low-priority terminationGracePeriodSeconds: 0 containers: - name: ubuntu-container image: ubuntu command: ["sleep"] args: ["36000"] resources: requests: cpu: "16" restartPolicy: Never
이 매니페스트에는 다음 필드가 포함됩니다.
spec.parallelism
: 용량을 예약하기 위해 동시에 실행할 작업 수로 변경합니다.spec.backoffLimit: 0
: 작업 컨트롤러가 삭제된 작업을 다시 만들지 못하도록 합니다.template.spec.resources.requests
: 요구사항을 충족하도록 CPU 및 메모리 요청을 변경합니다. 고려사항의 안내에 따라 적절한 값을 결정하세요.template.spec.containers.command
및template.spec.containers.args
: 추가 용량이 필요한 기간(초) 동안 작업이 활성 상태로 유지되도록 지시합니다.
매니페스트 적용
kubectl apply -f capacity-res-job.yaml
작업 상태를 가져옵니다.
kubectl get jobs
모든 작업이
Running
상태가 될 때까지 기다립니다.
용량 프로비저닝 및 제거 테스트
용량 프로비저닝이 예상대로 작동하는지 확인하려면 다음을 수행합니다.
터미널에서 용량 프로비저닝 워크로드의 상태를 확인합니다.
배포의 경우 다음 명령어를 실행합니다.
kubectl get pods --label=app=reservation -w
작업의 경우 다음 명령어를 실행합니다.
kubectl get Jobs -w
새 터미널 창을 열고 다음을 수행합니다.
다음 매니페스트를
test-deployment.yaml
로 저장합니다.apiVersion: apps/v1 kind: Deployment metadata: name: helloweb labels: app: hello spec: replicas: 5 selector: matchLabels: app: hello tier: web template: metadata: labels: app: hello tier: web spec: containers: - name: hello-app image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 ports: - containerPort: 8080 resources: requests: cpu: 400m memory: 400Mi
매니페스트 적용
kubectl apply -f test-deployment.yaml
원래 터미널 창에서 GKE는 다음 예시와 비슷하게 일부 용량 프로비저닝 워크로드를 종료하여 새 복제본을 예약합니다.
NAME READY STATUS RESTARTS AGE capacity-res-deploy-6bd9b54ffc-5p6wc 1/1 Running 0 7m25s capacity-res-deploy-6bd9b54ffc-9tjbt 1/1 Running 0 7m26s capacity-res-deploy-6bd9b54ffc-kvqr8 1/1 Running 0 2m32s capacity-res-deploy-6bd9b54ffc-n7zn4 1/1 Running 0 2m33s capacity-res-deploy-6bd9b54ffc-pgw2n 1/1 Running 0 2m32s capacity-res-deploy-6bd9b54ffc-t5t57 1/1 Running 0 2m32s capacity-res-deploy-6bd9b54ffc-v4f5f 1/1 Running 0 7m24s helloweb-85df88c986-zmk4f 0/1 Pending 0 0s helloweb-85df88c986-lllbd 0/1 Pending 0 0s helloweb-85df88c986-bw7x4 0/1 Pending 0 0s helloweb-85df88c986-gh8q8 0/1 Pending 0 0s helloweb-85df88c986-74jrl 0/1 Pending 0 0s capacity-res-deploy-6bd9b54ffc-v6dtk 1/1 Terminating 0 2m47s capacity-res-deploy-6bd9b54ffc-kvqr8 1/1 Terminating 0 2m47s capacity-res-deploy-6bd9b54ffc-pgw2n 1/1 Terminating 0 2m47s capacity-res-deploy-6bd9b54ffc-n7zn4 1/1 Terminating 0 2m48s capacity-res-deploy-6bd9b54ffc-2f8kx 1/1 Terminating 0 2m48s ... helloweb-85df88c986-lllbd 0/1 Pending 0 1s helloweb-85df88c986-gh8q8 0/1 Pending 0 1s helloweb-85df88c986-74jrl 0/1 Pending 0 1s helloweb-85df88c986-zmk4f 0/1 Pending 0 1s helloweb-85df88c986-bw7x4 0/1 Pending 0 1s helloweb-85df88c986-gh8q8 0/1 ContainerCreating 0 1s helloweb-85df88c986-zmk4f 0/1 ContainerCreating 0 1s helloweb-85df88c986-bw7x4 0/1 ContainerCreating 0 1s helloweb-85df88c986-lllbd 0/1 ContainerCreating 0 1s helloweb-85df88c986-74jrl 0/1 ContainerCreating 0 1s helloweb-85df88c986-zmk4f 1/1 Running 0 4s helloweb-85df88c986-lllbd 1/1 Running 0 4s helloweb-85df88c986-74jrl 1/1 Running 0 5s helloweb-85df88c986-gh8q8 1/1 Running 0 5s helloweb-85df88c986-bw7x4 1/1 Running 0 5s
이 출력은 새 배포가 Pending에서 Running으로 변경되는 데 5초가 걸렸음을 보여줍니다.
용량 프로비저닝 고려사항
일관된 용량 프로비저닝
- 필요한 자리표시자 포드 복제본 수와 각 복제본의 요청 크기를 평가합니다. 낮은 우선순위 복제본은 해당 워크로드가 우선순위가 낮은 워크로드가 예약한 용량에 적합할 수 있도록 최소한 가장 큰 프로덕션 워크로드와 동일한 용량을 요청해야 합니다.
- 대규모로 많은 양의 프로덕션 워크로드를 운영하는 경우 자리표시자 포드의 리소스 요청을 하나의 워크로드만이 아닌 여러 프로덕션 워크로드를 실행하는 데 충분한 용량을 프로비저닝하는 값으로 설정하는 것이 좋습니다.
일회성 용량 프로비저닝
- 추가 용량이 필요한 시간까지 자리표시자 작업이 지속될 기간을 설정합니다. 예를 들어 24시간 게임 출시일 동안 추가 용량을 원하는 경우 시간을 86,400초로 설정합니다. 이렇게 하면 프로비저닝된 용량이 필요 이상으로 지속되지 않습니다.
- 유지보수 기간을 용량 예약과 동일한 기간으로 설정합니다. 이렇게 하면 노드 업그레이드 중에 우선순위가 낮은 작업이 제거되는 것을 방지합니다. 또한 워크로드 수요가 많을 것으로 예상되면 유지보수 기간을 설정하는 것이 좋습니다.
- 대규모로 많은 양의 프로덕션 워크로드를 운영하는 경우 자리표시자 작업의 리소스 요청을 하나의 워크로드만이 아닌 여러 프로덕션 워크로드를 실행하는 데 충분한 용량을 프로비저닝하는 값으로 설정하는 것이 좋습니다.
용량은 단일 확장 이벤트에 대해서만 프로비저닝됩니다. 용량을 수직 확장 후 사용하면 축소되어 다른 확장 이벤트에 더 이상 사용할 수 없습니다. 여러 수직 확장 및 축소 이벤트가 예상되는 경우 일관된 용량 예약 메서드를 사용하고 필요에 따라 예약 크기를 조정합니다. 예를 들어 이벤트 전에 포드 요청을 더 크게 만들고 그 이후에 더 적게나 0으로 설정할 수 있습니다.
우선순위 선택
PriorityClass의 우선순위를 0 미만으로 설정할 수 있습니다.
요구사항이 다른 워크로드에 사용할 여러 PriorityClass를 클러스터에서 정의할 수 있습니다. 예를 들어 PriorityClass를 단일 사용 용량 프로비저닝에 대해서는 -10 우선순위로 만들고 일관적인 용량 프로비저닝에 대해서는 PriorityClass를 -9 우선순위로 만들 수 있습니다. 그런 다음 우선순위가 -9인 PriorityClass를 사용하여 일관된 용량을 프로비저닝할 수 있으며, 특별 이벤트에 더 많은 용량을 원하면 -10 우선순위인 PriorityClass를 사용하는 새 작업을 배포할 수 있습니다. GKE는 우선순위가 가장 낮은 워크로드를 먼저 제거합니다.
또한 다른 PriorityClasses를 사용하여 실제 작업을 수행하는 우선순위가 낮은 비프로덕션 워크로드를 프로덕션 워크로드보다는 낮지만 자리표시자 포드보다는 높은 우선순위로 실행할 수 있습니다. 예를 들면 -5입니다.
용량 크기 선택
수직 확장할 때 자리표시자 워크로드의 복제본 수 및 리소스 요청을 프로덕션 워크로드에 필요할 수 있는 용량 이상으로 설정할 수 있습니다.
프로비저닝된 총 용량은 배포하는 자리표시자 포드 수와 각 복제본의 리소스 요청을 기반으로 합니다. 수직 확장할 때 자리표시자 포드에 GKE에서 프로비저닝한 것보다 더 많은 용량이 필요한 경우 GKE에서 더 많은 용량을 프로비저닝할 수 있을 때까지 일부 프로덕션 워크로드가 Pending
으로 유지됩니다.