여러 머신 유형에 워크로드 마이그레이션

이 가이드에서는 애플리케이션에 다운타임을 일으키지 않고도 Google Kubernetes Engine (GKE) 클러스터에서 실행되는 워크로드를 같은 클러스터 내의 새로운 노드 집합으로 마이그레이션하는 방법을 보여줍니다. 이러한 마이그레이션은 머신 유형이 다른 노드에 워크로드를 이전하려는 경우에 유용할 수 있습니다.

배경

노드 풀은 머신 유형(CPU 및 메모리) 승인 범위를 포함하여 모두 동일한 구성을 갖는 머신의 하위 집합입니다. 노드 풀은 클러스터 내의 노드 하위 집합을 나타냅니다. 컨테이너 클러스터는 하나 이상의 노드 풀을 포함할 수 있습니다.

Compute Engine 클러스터의 머신 프로필을 변경해야 할 경우, 새 노드 풀을 만들고 작업 부하를 새 노드 풀로 이전할 수 있습니다.

다운타임 없이 작업 부하를 마이그레이션하려면 다음 작업이 필요합니다.

  • 기존 노드 풀을 예약 불가능으로 표시합니다.
  • 기존 노드 풀에서 실행되는 작업 부하를 배출합니다.
  • 기존 노드 풀을 삭제합니다.

GKE 클러스터의 클러스터 조정 시스템인 Kubernetes는 기존 노드 풀을 배출하면서 삭제된 Pod를 자동으로 새로운 노드 풀로 다시 예약합니다.

목표

  • GKE 클러스터 만들기
  • 샘플 웹 애플리케이션을 클러스터에 배포합니다.
  • 새 노드 풀을 만듭니다.
  • 다운타임 없이 Pod를 새 노드 풀로 마이그레이션합니다.

시작하기 전에

다음 단계에 따라 Kubernetes Engine API를 사용 설정합니다.
  1. Google Cloud Console에서 Kubernetes Engine 페이지로 이동합니다.
  2. 프로젝트를 만들거나 선택합니다.
  3. API 및 관련 서비스가 사용 설정될 때까지 기다립니다. 몇 분 정도 걸릴 수 있습니다.
  4. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

이 가이드에 사용된 다음 명령줄 도구를 설치합니다.

  • gcloud는 Kubernetes Engine 클러스터를 만들고 삭제하는 데 사용됩니다. gcloudGoogle Cloud SDK에 포함되어 있습니다.
  • kubectl은 Kubernetes Engine에서 사용되는 클러스터 조정 시스템인 Kubernetes를 관리하는 데 사용됩니다. gcloud를 사용하여 kubectl을 설치할 수 있습니다.
    gcloud components install kubectl

GitHub에서 샘플 코드를 클론합니다.

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/migrating-node-pool

gcloud 명령줄 도구의 기본값 설정

gcloud 명령줄 도구에 프로젝트 IDCompute Engine 영역 옵션을 입력하는 시간을 절약하려면 기본값을 설정하면 됩니다.
gcloud config set project project-id
gcloud config set compute/zone compute-zone

GKE 클러스터 만들기

첫 번째 단계는 애플리케이션 워크로드를 실행하도록 컨테이너 클러스터를 만드는 것입니다. 다음 명령어는 기본 머신 유형을 사용하고 5개의 노드가 있는 새 클러스터를 만듭니다(e2-medium).

gcloud container clusters create migration-tutorial --num-nodes=5

복제된 애플리케이션 배포 실행

다음 매니페스트는 샘플 웹 애플리케이션 컨테이너 이미지의 복제본 6개의 배포를 설명합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 6
  selector:
    matchLabels:
      app: hello-app
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app
        image: gcr.io/google-samples/hello-app:1.0

이 매니페스트를 배포하려면 다음을 실행합니다.

kubectl apply -f node-pools-deployment.yaml

다음을 실행하여 시작된 포드 목록을 검색할 수 있습니다.

kubectl get pods
출력:
NAME                   READY     STATUS    RESTARTS   AGE
web-2212180648-80q72   1/1       Running   0          10m
web-2212180648-jwj0j   1/1       Running   0          10m
web-2212180648-pf67q   1/1       Running   0          10m
web-2212180648-pqz73   1/1       Running   0          10m
web-2212180648-rrd3b   1/1       Running   0          10m
web-2212180648-v3b18   1/1       Running   0          10m

대형 머신 유형으로 노드 풀 만들기

기본적으로 GKE는 모든 새 클러스터의 default-pool 노드 풀을 만듭니다.

gcloud container node-pools list --cluster migration-tutorial
출력:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  e2-medium      100           1.16.13-gke.401

다른 머신 유형 또는 다른 인증 범위와 같은 다른 구성의 인스턴스를 사용하려면 새로운 노드 풀을 만들어야 합니다.

다음 명령어는 larger-pool이라는 새 노드 풀을 만듭니다. 이 노드 풀에는 e2-highmem-2머신 유형의 높은 메모리 인스턴스가 5개 있습니다.

gcloud container node-pools create larger-pool \
  --cluster=migration-tutorial \
  --machine-type=e2-highmem-2 \
  --num-nodes=5

이제 컨테이너 클러스터에 노드 풀 두 개가 포함됩니다.

gcloud container node-pools list --cluster migration-tutorial
출력:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  e2-medium      100           v1.16.13-gke.401
larger-pool   e2-highmem-2   100           v1.16.13-gke.401

GKE 클러스터에 추가된 새 노드 풀 인스턴스를 볼 수 있습니다.

kubectl get nodes
출력:
NAME                                                STATUS    AGE       VERSION
gke-migration-tutorial-default-pool-56e3af9a-059q   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready     40m       v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready     4m        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready     4m        v1.16.13-gke.401

워크로드 마이그레이션

새 노드 풀을 생성한 뒤에도 워크로드는 여전히 default-pool에서 실행됩니다. Kubernetes는 포드가 실행 중이고 사용 가능한 상태일 때 포드를 다시 예약하지 않습니다.

다음 명령어를 실행하여 Pod가 실행 중인 노드를 확인합니다 (NODE 열 참조).

kubectl get pods -o=wide
출력:
NAME                          READY     STATUS    IP         NODE
web-2212180648-80q72          1/1       Running   10.8.3.4   gke-migration-tutorial-default-pool-56e3af9a-k6jm
web-2212180648-jwj0j          1/1       Running   10.8.2.5   gke-migration-tutorial-default-pool-56e3af9a-0ng4
web-2212180648-pf67q          1/1       Running   10.8.4.4   gke-migration-tutorial-default-pool-56e3af9a-lkrv
web-2212180648-pqz73          1/1       Running   10.8.2.6   gke-migration-tutorial-default-pool-56e3af9a-0ng4
web-2212180648-rrd3b          1/1       Running   10.8.4.3   gke-migration-tutorial-default-pool-56e3af9a-lkrv
web-2212180648-v3b18          1/1       Running   10.8.1.4   gke-migration-tutorial-default-pool-56e3af9a-p9j4

이러한 Pod를 새로운 노드 풀로 마이그레이션하기 위해서는 다음 단계를 수행해야 합니다.

  1. 기존 노드 풀 차단: 이 작업은 기존 노드 풀(default-pool)에 있는 노드를 예약 불가능으로 표시합니다. 이를 예약 불가능으로 표시한 다음에는 Kubernetes가 이러한 노드에 대한 새 Pod 예약을 중지합니다.

  2. 기존 노드 풀 배출: 이 작업은 기존 노드 풀(default-pool)의 노드에서 실행 중인 워크로드를 정상적으로 제거합니다.

위 단계를 수행하면 기존 노드 풀에서 실행 중인 Pod가 정상적으로 종료되고 Kubernetes가 이를 다른 사용 가능한 노드에 다시 예약합니다. 이 경우 사용 가능한 유일한 노드는 larger-pool 노드 풀에 있습니다.

Kubernetes가 애플리케이션을 정상적으로 종료하도록 하려면, 컨테이너가 SIGTERM 신호를 처리해야 합니다. 이 신호를 사용하면 클라이언트에 대한 활성 연결을 닫고 데이터베이스 트랜잭션을 깨끗한 방식으로 커밋하거나 중단할 수 있습니다. Pod 매니페스트에서 spec.terminationGracePeriodSeconds 필드를 사용하여 Kubernetes가 Pod의 컨테이너를 중지하기 전에 대기해야 하는 시간을 지정할 수 있습니다. 기본값은 30초입니다. pod 종료에 대한 자세한 내용은 Kubernetes 문서를 참조하세요.

먼저 default-pool의 노드를 차단합니다. 다음 명령어를 실행하여 이 노드 풀에 있는 노드 목록을 가져올 수 있습니다.

kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool

그런 다음 이전 명령어에서 얻은 이름인 NODE로 대체된 kubectl cordon NODE를 실행해 각 노드를 차단합니다. 다음 명령어는 각 노드의 작업을 반복하고 예약 불가능으로 표시합니다.

for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl cordon "$node";
done
출력:
node "gke-migration-tutorial-default-pool-56e3af9a-059q" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-0ng4" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-k6jm" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-lkrv" cordoned
node "gke-migration-tutorial-default-pool-56e3af9a-p9j4" cordoned

이제 노드 목록에서 default-pool 노드가 SchedulingDisabled 상태로 변경된 것을 확인할 수 있습니다.

kubectl get nodes
출력:
NAME                                                STATUS                     AGE       VERSION
gke-migration-tutorial-default-pool-56e3af9a-059q   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-0ng4   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-k6jm   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-lkrv   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-default-pool-56e3af9a-p9j4   Ready,SchedulingDisabled   1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-2rhk    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-4bb2    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-7fl0    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-cx9q    Ready                      1h        v1.16.13-gke.401
gke-migration-tutorial-larger-pool-b8ec62a6-hs6p    Ready                      1h        v1.16.13-gke.401

그런 다음 각 노드에서 Pod를 정상적으로 배출합니다. 배출을 수행하려면 각 노드에서 Pod를 제거하는 kubectl drain 명령어를 사용합니다.

NODEkubectl cordon 명령어에 전달된 동일한 이름 목록으로 대체하여 kubectl drain --force NODE를 실행할 수 있습니다.

다음 셸 명령어는 할당된 정상 종료 시간 10초를 사용하여 Pod를 제거하는 방식으로 default-pool에서 각 노드를 반복하여 배출합니다.

for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=10 "$node";
done

이 명령어가 완료되면 이제 Pod가 larger-pool 노드에서 실행되는 것을 볼 수 있습니다.

kubectl get pods -o=wide
출력:
NAME                   READY     STATUS    IP         NODE
web-2212180648-3n9hz   1/1       Running   10.8.9.4   gke-migration-tutorial-larger-pool-b8ec62a6-cx9q
web-2212180648-88q1c   1/1       Running   10.8.7.4   gke-migration-tutorial-larger-pool-b8ec62a6-2rhk
web-2212180648-dlmjc   1/1       Running   10.8.9.3   gke-migration-tutorial-larger-pool-b8ec62a6-cx9q
web-2212180648-hcv46   1/1       Running   10.8.5.4   gke-migration-tutorial-larger-pool-b8ec62a6-hs6p
web-2212180648-n0nht   1/1       Running   10.8.6.4   gke-migration-tutorial-larger-pool-b8ec62a6-7fl0
web-2212180648-s51jb   1/1       Running   10.8.8.4   gke-migration-tutorial-larger-pool-b8ec62a6-4bb2

이전 노드 풀 삭제

Kubernetes가 web 배포의 모든 Pod를 larger-pool로 다시 예약한 다음에는 default-pool이 더 이상 필요하지 않으므로 안전하게 삭제할 수 있습니다. 다음 명령어를 실행하여 default-pool을 삭제합니다.

gcloud container node-pools delete default-pool --cluster migration-tutorial

이 작업이 완료되면 컨테이너 클러스터에 단일 노드 풀인 larger-pool만 있어야 합니다.

gcloud container node-pools list --cluster migration-tutorial
출력:
NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
larger-pool   e2-highmem-2   100           1.16.13-gke.401

삭제

이 가이드에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

  • 컨테이너 클러스터 삭제: 이 단계에서 컴퓨팅 인스턴스, 디스크, 네트워크 리소스와 같이 컨테이너 클러스터를 구성하는 리소스를 삭제합니다.

    gcloud container clusters delete migration-tutorial

다음 단계