Instructivo: Implementa una VM existente en un clúster de Google Distributed Cloud con el entorno de ejecución de VM en GDC


En este documento, se proporciona una guía paso a paso para implementar una carga de trabajo basada en una máquina virtual (VM) en Google Distributed Cloud con el entorno de ejecución de VM en GDC. La carga de trabajo que se usa en esta guía es la aplicación de punto de venta de ejemplo. Esta aplicación representa una terminal de punto de venta típica que se ejecuta en hardware local en una tienda minorista.

En este documento, migrarás esta aplicación de una VM a un clúster de Google Distributed Cloud y accederás al frontend web de la aplicación. Para migrar una VM existente al clúster, primero se debe crear una imagen de disco de esa VM. Luego, la imagen debe alojarse en un repositorio al que el clúster pueda acceder. Por último, se puede usar la URL de esa imagen para crear la VM. El entorno de ejecución de VM en GDC espera que las imágenes estén en formato qcow2. Si proporcionas un tipo de imagen diferente, se convierte automáticamente al formato qcow2. Para evitar la conversión repetitiva y habilitar la reutilización, puedes convertir una imagen de disco virtual y alojar la imagen qcow2.

En este documento, se usa una imagen preparada previamente de una instancia de VM de Compute Engine en la que la carga de trabajo se ejecuta como un servicio systemd. Puedes seguir estos mismos pasos para implementar tu propia aplicación.

Objetivos

Antes de comenzar

Para completar este documento, necesitas los siguientes recursos:

  • Acceso a un clúster de la versión 1.12.0 o superior de Google Distributed Cloud que se creó siguiendo la guía Ejecuta Google Distributed Cloud en VMs de Compute Engine con el balanceador de cargas manual En este documento, se configuran recursos de red para que puedas acceder a la carga de trabajo que se ejecuta dentro de la VM a través de un navegador. Si no necesitas ese comportamiento, puedes seguir este documento con cualquier Google Distributed Cloud.
  • Una estación de trabajo que cumpla con los siguientes requisitos:
    • Tiene acceso a tu clúster con la CLI de bmctl.
    • Tiene acceso a tu clúster con la CLI de kubectl.

Habilita el entorno de ejecución de VM en GDC y, luego, instala el complemento virtctl

La definición de recursos personalizados (CRD) del entorno de ejecución de VM en GDC forma parte de todos los clústeres de Google Distributed Cloud desde la versión 1.10. Ya se creó una instancia del recurso personalizado VMRuntime durante la instalación. Sin embargo, está inhabilitado de forma predeterminada.

  1. Habilita el entorno de ejecución de VM en GDC.

    sudo bmctl enable vmruntime --kubeconfig KUBECONFIG_PATH
    
    • KUBECONFIG_PATH: Es la ruta de acceso al archivo de configuración de Kubernetes del clúster de usuarios de Google Distributed Cloud.
  2. Verifica que VMRuntime esté habilitado:

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

    Es posible que esto tarde algunos minutos para VMRuntime. Si no está listo, vuelve a verificarlo varias veces con demoras cortas. En el siguiente resultado de ejemplo, se muestra que el VMRuntime está listo:

    vmruntime.vm.cluster.gke.io/vmruntime condition met
    
  3. Instala el complemento virtctl para kubectl:

    sudo -E bmctl install virtctl
    

    En el siguiente resultado de ejemplo, se muestra que se completó el proceso de instalación del complemento 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. Verifica la instalación del complemento virtctl:

    kubectl virt
    

    En el siguiente resultado de ejemplo, se muestra que el complemento virtctl está disponible para usarse con 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.
    ...
    

Implementa la carga de trabajo basada en VM

Cuando implementas una VM en Google Distributed Cloud, el entorno de ejecución de VM en GDC espera una imagen de VM. Esta imagen sirve como disco de arranque para la VM implementada.

En este instructivo, migrarás una carga de trabajo basada en una VM de Compute Engine a un clúster de Google Distributed Cloud. Se creó esta VM de Compute Engine y se configuró la aplicación de punto de venta (PoS) de ejemplo para que se ejecute como un servicio systemd. Se creó una imagen de disco de esta VM junto con la carga de trabajo de la aplicación de PdV en Google Cloud. Luego, esta imagen se exportó a un bucket de Cloud Storage como una imagen qcow2. Usas esta imagen qcow2 preparada previamente en los siguientes pasos.

El código fuente de este documento está disponible en el repositorio de GitHub anthos-samples. Usarás los recursos de este repositorio para completar los pasos que se indican a continuación.

  1. Implementa un StatefulSet de MySQL. La aplicación de punto de venta espera conectarse a una base de datos de MySQL para almacenar información de inventario y pagos. El repositorio de punto de venta tiene un manifiesto de muestra que implementa un StatefulSet de MySQL, configura un ConfigMap asociado y un Service de Kubernetes. ConfigMap define las credenciales de la instancia de MySQL, que son las mismas credenciales que se pasan a la aplicación de punto de venta.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/point-of-sale/main/k8-manifests/common/mysql-db.yaml
    
  2. Implementa la carga de trabajo de la VM con la imagen qcow2 preparada previamente:

    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
    

    Este comando crea un archivo YAML con el nombre de la VM (google-virtctl/pos-vm.yaml). Puedes inspeccionar el archivo para ver la definición de VirtualMachine y VirtualMachineDisk. En lugar de usar el complemento virtctl, podrías haber implementado la carga de trabajo de la VM con definiciones del modelo de recursos de Kubernetes (KRM), como se ve en el archivo YAML creado.

    Cuando el comando se ejecuta correctamente, produce un resultado como el siguiente ejemplo, que explica los diferentes recursos que se crearon:

    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. Verifica el estado de creación de la VM.

    El recurso VirtualMachine se identifica con el recurso vm.cluster.gke.io/v1.VirtualMachine en el entorno de ejecución de VM en GDC. Su forma abreviada es gvm.

    Cuando creas una VM, se crean los siguientes dos recursos:

    • Un VirtualMachineDisk es el disco persistente en el que se importa el contenido de la imagen de la VM.
    • Un VirtualMachine es la instancia de VM en sí. El DataVolume se activa en la VirtualMachine antes de que se inicie la VM.

    Verifica el estado de VirtualMachineDisk. VirtualMachineDisk crea, de forma interna, un recurso DataVolume. La imagen de la VM se importa al DataVolume que se activa en la VM:

    kubectl get datavolume
    

    En el siguiente ejemplo de resultado, se muestra el inicio de la importación de imágenes:

    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    ImportScheduled   N/A                   8s
    
  4. Verifica el estado de VirtualMachine. VirtualMachine se encuentra en el estado Provisioning hasta que se importa DataVolume por completo:

    kubectl get gvm
    

    En el siguiente resultado de ejemplo, se muestra el VirtualMachine que se aprovisiona:

    NAME      STATUS         AGE     IP
    pos-vm    Provisioning   1m
    
  5. Espera a que la imagen de la VM se importe por completo en DataVolume. Continúa observando el progreso mientras se importa la imagen:

    kubectl get datavolume -w
    

    En el siguiente resultado de ejemplo, se muestra la imagen de disco que se importa:

    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
    ...
    

    Cuando se completa la importación y se crea el DataVolume, el siguiente resultado del ejemplo muestra el PHASE de Succeeded :

    kubectl get datavolume
    
    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    Succeeded         100.0%                14m18s
    
  6. Confirma que se haya creado correctamente VirtualMachine:

    kubectl get gvm
    

    Si la creación se realizó correctamente, STATUS muestra RUNNING, como se muestra en el siguiente ejemplo, junto con la dirección IP de la VM:

    NAME      STATUS    AGE     IP
    pos-vm    Running   40m     192.168.3.250
    

Conéctate a la VM y verifica el estado de la aplicación

La imagen que se usa para la VM incluye la aplicación de ejemplo de punto de venta. La aplicación se configura para iniciarse automáticamente durante el inicio como un servicio systemd. Puedes ver los archivos de configuración de los servicios systemd en el directorio pos-systemd-services.

  1. Conéctate a la consola de VM. Ejecuta el siguiente comando y presiona Intro⏎ después de ver el mensaje Successfully connected to pos-vm…:

    kubectl virt console pos-vm
    

    Este comando produce el siguiente resultado de ejemplo que te solicita que ingreses los detalles de acceso:

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

    Usa la siguiente cuenta de usuario y contraseña. Esta cuenta se configuró dentro de la VM original a partir de la cual se creó la imagen para el entorno de ejecución de la VM en la máquina virtual de GDC.

    • Nombre de usuario de acceso: abmuser
    • Contraseña: abmworks
  2. Verifica el estado de los servicios de la aplicación de punto de venta. La aplicación de punto de venta incluye tres servicios: API, inventario y pagos. Todos estos servicios se ejecutan como servicios del sistema.

    Los tres servicios se conectan entre sí a través de localhost. Sin embargo, la aplicación se conecta a la base de datos de MySQL con un servicio de Kubernetes mysql-db que se creó en el paso anterior. Este comportamiento significa que la VM se conecta automáticamente a la misma red que Pods y Services, lo que permite una comunicación fluida entre las cargas de trabajo de la VM y otras aplicaciones en contenedores. No tienes que hacer nada adicional para que se pueda acceder a Services de Kubernetes desde las VMs implementadas con VM Runtime en GDC.

    sudo systemctl status pos*
    

    En el siguiente resultado de ejemplo, se muestra el estado de los tres servicios y el servicio del sistema raíz, 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. Sal de la VM. Para salir de la conexión de la consola, usa la secuencia de escape ^] presionando Ctrl + ].

Accede a la carga de trabajo basada en VM

Si configuraste tu clúster siguiendo la guía Cómo ejecutar Google Distributed Cloud en VMs de Compute Engine con un balanceador de cargas manual, ya se creó un recurso Ingress llamado pos-ingress. Este recurso enruta el tráfico de la dirección IP externa del balanceador de cargas de Ingress al servicio del servidor de API de la aplicación de ejemplo de punto de venta.

  1. Si tu clúster no tiene este recurso Ingress, créalo aplicando el siguiente manifiesto:

    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. Crea un Service de Kubernetes que enrute el tráfico a la VM. El recurso Ingress enruta el tráfico a este Service:

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

    En el siguiente ejemplo de resultado, se confirma la creación de un servicio:

    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. Obtén la dirección IP externa del balanceador de cargas Ingress. El balanceador de cargas Ingress enruta el tráfico según las reglas de recursos Ingress. Ya tienes una regla pos-ingress para reenviar solicitudes al servidor de la API Service. Este Service reenvía las solicitudes a la VM:

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

    En el siguiente resultado de ejemplo, se muestra la dirección IP del balanceador de cargas Ingress:

    172.29.249.159 # you might have a different IP address
    
  4. Accede a la aplicación con la dirección IP del balanceador de cargas de Ingress en un navegador. En las siguientes capturas de pantalla de ejemplo, se muestra el kiosco de punto de venta simple con dos artículos. Puedes hacer clic en los artículos, más de una vez si quieres pedir varios, y realizar un pedido con el botón Pagar. Esta experiencia muestra que implementaste correctamente una carga de trabajo basada en VM en un clúster de Google Distributed Cloud con el entorno de ejecución de VM en GDC.

IU de la aplicación de punto de venta
IU de la aplicación de punto de venta (haz clic en la imagen para ampliarla)

Libera espacio

Puedes borrar todos los recursos creados en este instructivo o solo borrar la VM y conservar los recursos reutilizables. En Borra una VM en Google Distributed Cloud, se explican las opciones disponibles en detalle.

Borrar todo

  • Borra el entorno de ejecución de VM en GDC VirtualMachine junto con todos los recursos:

    kubectl virt delete vm pos-vm --all
    

    En el siguiente ejemplo, se confirma la eliminación:

    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".
    

Borra solo la VM

  • Si solo borras la VM, se conserva el VirtualMachineDisk que se crea. Esto permite reutilizar esta imagen de VM y ahorra tiempo en la importación de la imagen cuando se crea una VM nueva.

    kubectl virt delete vm pos-vm
    

    En el siguiente ejemplo, se confirma la eliminación:

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

¿Qué sigue?

  • La VM original que se usa en esta guía es una instancia de Compute Engine que ejecuta Ubuntu 20.04 LTS. Se puede acceder públicamente a la imagen de esta VM a través del bucket de Cloud Storage pos-vm-images. Para obtener más información sobre cómo se configuró la VM y se creó su imagen, consulta las instrucciones en el repositorio de punto de venta.
  • Cuando creas una VM en un clúster de Google Distributed Cloud con el comando kubectl virt create vm pos-vm, se crea un archivo YAML con el nombre de la VM (google-virtctl/pos-vm.yaml). Puedes inspeccionar el archivo para ver la definición de VirtualMachine y VirtualMachineDisk. En lugar de usar el complemento virtctl, puedes implementar una VM con definiciones de KRM, como se ve en el archivo YAML creado.