튜토리얼: GDC용 VM 런타임을 사용하여 베어메탈용 GKE 클러스터에 기존 VM 배포


이 문서에서는 GDC용 VM 런타임을 사용하여 가상 머신(VM) 기반 워크로드를 베어메탈용 GKE에 배포하는 방법을 단계별로 설명합니다. 이 가이드에서 사용되는 워크로드는 샘플 POS 애플리케이션입니다. 이 애플리케이션은 소매점의 온프레미스 하드웨어에서 실행되는 일반적인 POS 터미널을 나타냅니다.

이 문서에서는 이 애플리케이션을 VM에서 베어메탈용 GKE 클러스터로 마이그레이션하고 애플리케이션의 웹 프런트엔드에 액세스합니다. 기존 VM을 클러스터로 마이그레이션하려면 먼저 해당 VM의 디스크 이미지를 만들어야 합니다. 그런 다음 이미지를 클러스터가 액세스할 수 있는 저장소에 호스팅해야 합니다. 마지막으로, 이 이미지의 URL을 사용하여 VM을 만들면 됩니다. GDC용 VM 런타임에는 qcow2 형식의 이미지가 필요합니다. 다른 이미지 유형이 제공될 경우 qcow2 형식으로 자동 변환됩니다. 반복적인 변환을 방지하고 재사용을 사용 설정하려면 가상 디스크 이미지를 변환하고 qcow2 이미지를 호스팅하면 됩니다.

이 문서에서는 워크로드가 systemd 서비스로 실행되는 Compute Engine VM 인스턴스의 사전 준비된 이미지를 사용합니다. 동일한 단계를 수행하여 자체 애플리케이션을 배포할 수 있습니다.

목표

시작하기 전에

이 문서를 완료하려면 다음 리소스가 필요합니다.

  • 수동 부하 분산기로 Compute Engine VM에서 베어메탈용 GKE 실행 가이드에 따라 생성된 베어메탈용 GKE 버전 1.12.0 이상의 클러스터에 대한 액세스 권한. 이 문서에서는 브라우저를 통해 VM 내에서 실행되는 워크로드에 액세스할 수 있도록 네트워킹 리소스를 설정합니다. 이러한 동작이 필요하지 않으면 베어메탈용 GKE를 사용하여 이 문서를 따를 수 있습니다.
  • 다음 요구사항을 충족하는 워크스테이션:
    • bmctl CLI를 사용하여 클러스터에 액세스할 수 있음
    • kubectl CLI를 사용하여 클러스터에 액세스할 수 있습니다.

GDC용 VM 런타임 사용 설정 및 virtctl 플러그인 설치

GDC용 VM 런타임 커스텀 리소스 정의(CRD)는 버전 1.10부터 모든 베어메탈용 GKE 클러스터에 포함됩니다. VMRuntime 커스텀 리소스의 인스턴스가 이미 설치 시에 생성되어 있습니다. 하지만 기본적으로 중지되어 있습니다.

  1. GDC용 VM 런타임을 사용 설정합니다.

    sudo bmctl enable vmruntime --kubeconfig KUBECONFIG_PATH
    
    • KUBECONFIG_PATH: 베어메탈용 GKE 사용자 클러스터의 Kubernetes 구성 파일 경로
  2. VMRuntime이 사용 설정되어 있는지 확인합니다.

    kubectl wait --for=jsonpath='{.status.ready}'=true vmruntime vmruntime
    

    VMRuntime이 준비되는 데 몇 분 정도 걸릴 수 있습니다. 준비가 되지 않은 경우 짧은 간격으로 몇 번 확인하세요. 다음 예시 출력은 VMRuntime이 준비되었음을 보여줍니다.

    vmruntime.vm.cluster.gke.io/vmruntime condition met
    
  3. kubectlvirtctl 플러그인을 설치합니다.

    sudo -E bmctl install virtctl
    

    다음 출력 예시는 virtctl 플러그인 설치 프로세스가 완료되었는지 보여줍니다.

    Please check the logs at bmctl-workspace/log/install-virtctl-20220831-182135/install-virtctl.log
    [2022-08-31 18:21:35+0000] Install virtctl succeeded
    
  4. virtctl 플러그인 설치를 확인합니다.

    kubectl virt
    

    다음 출력 예시는 virtctl 플러그인을 kubectl과 함께 사용할 수 있음을 보여줍니다.

    Available Commands:
      addvolume         add a volume to a running VM
      completion        generate the autocompletion script for the specified shell
      config            Config subcommands.
      console           Connect to a console of a virtual machine instance.
      create            Create subcommands.
      delete            Delete  subcommands.
    ...
    

VM 기반 워크로드 배포

VM을 베어메탈용 GKE에 배포할 때 GDC용 VM 런타임에는 VM 이미지가 필요합니다. 이 이미지는 배포된 VM의 부팅 디스크 역할을 합니다.

이 튜토리얼에서는 Compute Engine VM 기반 워크로드를 베어메탈용 GKE 클러스터로 마이그레이션합니다. 이 Compute Engine VM이 생성되었으며 샘플 판매 시점(POS) 애플리케이션은 systemd 서비스로 실행되도록 구성되었습니다. Google Cloud에 POS 애플리케이션 워크로드와 함께 이 VM의 디스크 이미지가 생성되었습니다. 그런 다음 이 이미지를 Cloud Storage 버킷에 qcow2 이미지로 내보냈습니다. 다음 단계에서 이 미리 준비된 qcow2 이미지를 사용합니다.

이 문서의 소스 코드는 anthos-samples GitHub 저장소에서 제공됩니다. 이 저장소의 리소스를 사용하여 다음 단계를 완료합니다.

  1. MySQL StatefulSet를 배포합니다. 판매 시점 애플리케이션은 MySQL 데이터베이스에 연결되어 인벤토리 및 결제 정보를 저장해야 합니다. 판매 시점 저장소에는 MySQL StatefulSet를 배포하고 연결된 ConfigMap 및 Kubernetes Service를 구성하는 샘플 매니페스트가 있습니다. ConfigMapPOS 애플리케이션에 전달되는 사용자 인증 정보와 동일한 MySQL 인스턴스의 사용자 인증 정보를 정의합니다.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/point-of-sale/main/k8-manifests/common/mysql-db.yaml
    
  2. 미리 준비된 qcow2 이미지를 사용하여 VM 워크로드를 배포합니다.

    kubectl virt create vm pos-vm \
        --boot-disk-size=80Gi \
        --memory=4Gi \
        --vcpu=2 \
        --image=https://storage.googleapis.com/pos-vm-images/pos-vm.qcow2
    

    이 명령어는 VM(google-virtctl/pos-vm.yaml) 이름을 따서 명명된 YAML 파일을 만듭니다. 파일을 검사하여 VirtualMachineVirtualMachineDisk의 정의를 볼 수 있습니다. virtctl 플러그인을 사용하는 대신 생성된 YAML 파일에 표시된 것처럼 Kubernetes 리소스 모델(KRM) 정의를 사용하여 VM 워크로드를 배포할 수 있었습니다.

    명령어가 성공적으로 실행되면 생성된 여러 리소스를 설명하는 다음 예시와 같은 출력이 생성됩니다.

    Constructing manifest for vm "pos-vm":
    Manifest for vm "pos-vm" is saved to /home/tfadmin/google-virtctl/pos-vm.yaml
    Applying manifest for vm "pos-vm"
    Created gvm "pos-vm"
    
  3. VM 생성 상태를 확인합니다.

    VirtualMachine 리소스는 GDC용 VM 런타임에서 vm.cluster.gke.io/v1.VirtualMachine 리소스로 식별됩니다. 짧은 형식은 gvm입니다.

    VM을 만들면 다음 두 가지 리소스가 생성됩니다.

    • VirtualMachineDisk는 VM 이미지의 콘텐츠를 가져올 영구 디스크입니다.
    • VirtualMachine은 VM 인스턴스 자체입니다. VM이 부팅되기 전에 DataVolumeVirtualMachine에 마운트됩니다.

    VirtualMachineDisk 상태를 확인합니다. VirtualMachineDisk는 내부적으로 DataVolume 리소스를 만듭니다. VM 이미지를 VM에 마운트된 DataVolume으로 가져옵니다.

    kubectl get datavolume
    

    다음 예시 출력은 이미지 가져오기의 시작을 보여줍니다.

    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    ImportScheduled   N/A                   8s
    
  4. VirtualMachine의 상태를 확인합니다. DataVolume을 완전히 가져올 때까지 VirtualMachineProvisioning 상태가 됩니다.

    kubectl get gvm
    

    다음 예시 출력은 프로비저닝되는 VirtualMachine을 보여줍니다.

    NAME      STATUS         AGE     IP
    pos-vm    Provisioning   1m
    
  5. VM 이미지를 DataVolume으로 완전히 가져올 때까지 기다립니다. 이미지를 가져오는 동안 진행 상황을 계속 확인합니다.

    kubectl get datavolume -w
    

    다음 예시 출력은 가져오는 디스크 이미지를 보여줍니다.

    NAME              PHASE              PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv   ImportInProgress   0.00%                 14s
    ...
    ...
    pos-vm-boot-dv   ImportInProgress   0.00%                 31s
    pos-vm-boot-dv   ImportInProgress   1.02%                 33s
    pos-vm-boot-dv   ImportInProgress   1.02%                 35s
    ...
    

    가져오기가 완료되고 DataVolume이 생성되면 다음 예시 출력과 같이 SucceededPHASE가 표시됩니다.

    kubectl get datavolume
    
    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    Succeeded         100.0%                14m18s
    
  6. VirtualMachine이 성공적으로 생성되었는지 확인합니다.

    kubectl get gvm
    

    만들기에 성공하면 STATUS에 다음 예시와 같이 VM의 IP 주소와 함께 RUNNING이 표시됩니다.

    NAME      STATUS    AGE     IP
    pos-vm    Running   40m     192.168.3.250
    

VM에 연결하고 애플리케이션 상태 확인

VM에 사용되는 이미지에는 POS 샘플 애플리케이션이 포함됩니다. 이 애플리케이션은 부팅 시 systemd 서비스로 자동 시작되도록 구성되어 있습니다. pos-systemd-services 디렉터리에서 systemd 서비스의 구성 파일을 볼 수 있습니다.

  1. VM 콘솔에 연결합니다. 다음 명령어를 실행하고 Successfully connected to pos-vm… 메시지가 표시되면 Enter⏎ 키를 누릅니다.

    kubectl virt console pos-vm
    

    이 명령어는 로그인 세부정보를 입력하라는 메시지를 표시하는 다음 예시 출력을 생성합니다.

    Successfully connected to pos-vm console. The escape sequence is ^]
    
    pos-from-public-image login:
    

    다음 사용자 계정과 비밀번호를 사용합니다. 이 계정은 GDC용 VM 런타임 VirtualMachine 이미지가 생성된 원래 VM 내에 설정되었습니다.

    • 로그인 사용자 이름: abmuser
    • 비밀번호: abmworks
  2. 판매 시점 애플리케이션 서비스의 상태를 확인합니다. 판매 시점 애플리케이션에는 API, 인벤토리, 결제라는 세 가지 서비스가 포함됩니다. 이러한 서비스 모두 시스템 서비스로 실행됩니다.

    세 가지 서비스는 모두 localhost를 통해 서로 연결됩니다. 하지만 애플리케이션은 이전 단계에서 만든 mysql-db Kubernetes 서비스를 사용하여 MySQL 데이터베이스에 연결합니다. 이 동작은 VM이 PodsServices와 동일한 네트워크에 자동으로 연결되어 VM 워크로드와 다른 컨테이너화된 애플리케이션 간에 원활한 통신이 가능하다는 것을 의미합니다. GDC용 VM 런타임을 통해 배포된 VM에서 Kubernetes Services에 연결할 수 있게 하기 위해 추가 작업을 수행할 필요는 없습니다.

    sudo systemctl status pos*
    

    다음 출력 예시에서는 세 서비스 및 루트 시스템 서비스 pos.service의 상태를 보여줍니다.

    ● pos_payments.service - Payments service of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_payments.service; enabled; vendor >
        Active: active (running) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 750 (payments.sh)
          Tasks: 27 (limit: 4664)
        Memory: 295.1M
        CGroup: /system.slice/pos_payments.service
                ├─750 /bin/sh /pos/scripts/payments.sh
                └─760 java -jar /pos/jars/payments.jar --server.port=8083
    
    ● pos_inventory.service - Inventory service of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_inventory.service; enabled; vendor>
        Active: active (running) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 749 (inventory.sh)
          Tasks: 27 (limit: 4664)
        Memory: 272.6M
        CGroup: /system.slice/pos_inventory.service
                ├─749 /bin/sh /pos/scripts/inventory.sh
                └─759 java -jar /pos/jars/inventory.jar --server.port=8082
    
    ● pos.service - Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos.service; enabled; vendor preset: e>
        Active: active (exited) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 743 (code=exited, status=0/SUCCESS)
          Tasks: 0 (limit: 4664)
        Memory: 0B
        CGroup: /system.slice/pos.service
    
    Jun 21 18:55:30 pos-vm systemd[1]: Starting Point of Sale Application...
    Jun 21 18:55:30 pos-vm systemd[1]: Finished Point of Sale Application.
    
    ● pos_apiserver.service - API Server of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_apiserver.service; enabled; vendor>
        Active: active (running) since Tue 2022-06-21 18:55:31 UTC; 1h 10min ago
      Main PID: 751 (api-server.sh)
          Tasks: 26 (limit: 4664)
        Memory: 203.1M
        CGroup: /system.slice/pos_apiserver.service
                ├─751 /bin/sh /pos/scripts/api-server.sh
                └─755 java -jar /pos/jars/api-server.jar --server.port=8081
    
  3. VM을 종료합니다. 콘솔 연결을 종료하려면 Ctrl + ]를 눌러 이스케이프 시퀀스 ^]를 사용합니다.

VM 기반 워크로드 액세스

Compute Engine VM에서 수동 부하 분산기를 사용하여 베어메탈용 GKE 실행 가이드를 수행하여 클러스터를 설정한 경우 pos-ingress라는 Ingress 리소스가 이미 생성되어 있습니다. 이 리소스는 트래픽을 인그레스 부하 분산기의 외부 IP 주소에서 판매 시점 샘플 애플리케이션의 API 서버 서비스로 라우팅합니다.

  1. 클러스터에 이 Ingress 리소스가 없으면 다음 매니페스트를 적용하여 리소스를 만듭니다.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-samples/main/anthos-bm-gcp-terraform/resources/manifests/pos-ingress.yaml
    
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: pos-ingress
    spec:
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-server-svc
                port:
                  number: 8080
  2. 트래픽을 VM으로 라우팅하는 Kubernetes Service를 만듭니다. Ingress 리소스는 이 Service로 트래픽을 라우팅합니다.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-samples/main/anthos-vmruntime/pos-service.yaml
    

    다음은 서비스가 만들어졌는지 확인하는 예시 출력입니다.

    service/api-server-svc created
    
    apiVersion: v1
    kind: Service
    metadata:
      name: api-server-svc
    spec:
      selector:
        kubevirt/vm: pos-vm
      ports:
      - protocol: TCP
        port: 8080
        targetPort: 8081
  3. Ingress 부하 분산기의 외부 IP 주소를 가져옵니다. Ingress Loadbalancer는 Ingress 리소스 규칙에 따라 트래픽을 라우팅합니다. 요청을 API 서버 Service에 전달하는 pos-ingress 규칙이 이미 있습니다. 이 Service는 요청을 VM에 전달합니다.

    INGRESS_IP=$(kubectl get ingress/pos-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo $INGRESS_IP
    

    다음 예시 출력에서는 Ingress 부하 분산기의 IP 주소를 보여줍니다.

    172.29.249.159 # you might have a different IP address
    
  4. 브라우저에서 인그레스 Loadbalancer IP 주소를 사용하여 애플리케이션에 액세스합니다. 다음 스크린샷 예시는 두 항목이 포함된 간단한 POS 키오스크를 보여줍니다. 항목을 여러 개 주문하려는 경우 항목을 두 번 이상 클릭하고 결제 버튼을 사용하여 주문할 수 있습니다. 이 경험은 GDC용 VM 런타임을 사용하여 VM 기반 워크로드를 베어메탈용 GKE 클러스터에 성공적으로 배포했음을 보여줍니다.

판매 시점 애플리케이션 UI
POS 애플리케이션 UI(확대하려면 클릭)

삭제

이 튜토리얼에서 만든 모든 리소스를 삭제하거나 VM만 삭제하고 재사용 가능한 리소스를 유지할 수 있습니다. 베어메탈용 GKE에서 VM 삭제에서는 사용 가능한 옵션을 자세히 설명합니다.

모두 삭제

  • 모든 리소스와 함께 GDC용 VM 런타임 VirtualMachine을 삭제합니다.

    kubectl virt delete vm pos-vm --all
    

    다음 출력 예시는 삭제를 확인합니다.

    vm "pos-vm" used the following resources:
        gvm: pos-vm
        VirtualMachineDisk: pos-vm-boot-dv
    Start deleting the resources:
        Deleted gvm "pos-vm".
        Deleted VirtualMachineDisk "pos-vm-boot-dv".
    

VM만 삭제

  • VM만 삭제하면 만든 VirtualMachineDisk가 보존됩니다. 이렇게 하면 이 VM 이미지를 재사용할 수 있으며 새 VM을 만들 때 이미지를 가져오는 데 소요되는 시간이 절약됩니다.

    kubectl virt delete vm pos-vm
    

    다음 출력 예시는 삭제를 확인합니다.

    vm "pos-vm" used the following resources:
        gvm: pos-vm
        VirtualMachineDisk: pos-vm-boot-dv
    Start deleting the resources:
        Deleted gvm "pos-vm".
    

다음 단계

  • 이 가이드에서 사용된 원래 VM은 Ubuntu 20.04 LTS를 실행하는 Compute Engine 인스턴스입니다. 이 VM의 이미지는 pos-vm-images Cloud Storage 버킷을 통해 공개적으로 액세스할 수 있습니다. VM이 구성된 방식과 이미지가 생성된 방법에 대한 자세한 내용은 판매 시점 저장소의 안내를 참조하세요.
  • kubectl virt create vm pos-vm 명령어를 사용하여 베어메탈용 GKE 클러스터에 VM을 만들면 VM 이름을 따라 명명된 YAML 파일(google-virtctl/pos-vm.yaml)이 생성됩니다. 파일을 검사하여 VirtualMachineVirtualMachineDisk의 정의를 볼 수 있습니다. virtctl 플러그인을 사용하는 대신 만든 YAML 파일에 표시된 대로 KRM 정의를 사용하여 VM을 배포할 수 있습니다.