Tutorial: implemente uma VM existente num cluster com o tempo de execução de VMs no GDC


Este documento fornece um guia passo a passo para implementar uma carga de trabalho baseada em máquinas virtuais (VMs) numa instalação do Google Distributed Cloud (apenas software) em bare metal através do VM Runtime no GDC. A carga de trabalho usada neste guia é a aplicação de ponto de venda de exemplo. Esta aplicação representa um terminal de ponto de venda típico que é executado em hardware no local numa loja de retalho.

Neste documento, migra esta aplicação de uma VM para um cluster e acede à interface Web da aplicação. Para migrar uma VM existente para o cluster, primeiro tem de criar uma imagem de disco dessa VM. Em seguida, a imagem tem de ser alojada num repositório ao qual o cluster possa aceder. Por último, o URL dessa imagem pode ser usado para criar a VM. O tempo de execução da VM no GDC espera que as imagens estejam no formato qcow2. Se fornecer um tipo de imagem diferente, esta é convertida automaticamente para o formato qcow2. Para evitar conversões repetitivas e permitir a reutilização, pode converter uma imagem de disco virtual e alojar a imagem qcow2.

Este documento usa uma imagem preparada previamente de uma instância de VM do Compute Engine onde a carga de trabalho é executada como um serviço systemd. Pode seguir estes mesmos passos para implementar a sua própria aplicação.

Objetivos

Antes de começar

Para preencher este documento, precisa dos seguintes recursos:

  • Acesso a um cluster bare metal da versão 1.12.0 ou superior que foi criado seguindo o guia Instalar com balanceador de carga manual. Este documento configura recursos de rede para que possa aceder à carga de trabalho em execução na VM através de um navegador. Se não precisar desse comportamento, pode seguir este documento usando qualquer instalação do Google Distributed Cloud em bare metal.
  • Uma estação de trabalho que cumpra os seguintes requisitos:
    • Tem acesso ao seu cluster através da CLI bmctl.
    • Tem acesso ao seu cluster através da CLI kubectl.

Ative o tempo de execução de VMs no GDC e instale o plug-in virtctl

O tempo de execução da VM na definição de recursos personalizados do GDC faz parte de todos os clusters bare metal desde a versão 1.10. Uma instância do recurso personalizado VMRuntime já é criada após a instalação. No entanto, está desativada por predefinição.

  1. Ative o tempo de execução de VMs no GDC:

    sudo bmctl enable vmruntime --kubeconfig KUBECONFIG_PATH
    
    • KUBECONFIG_PATH: caminho do ficheiro kubeconfig do cluster de utilizadores.
  2. Valide se o VMRuntime está ativado:

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

    O VMRuntime pode demorar alguns minutos a ficar pronto. Se não estiver pronto, verifique algumas vezes com pequenos atrasos. O exemplo de saída seguinte mostra que o VMRuntime está pronto:

    vmruntime.vm.cluster.gke.io/vmruntime condition met
    
  3. Instale o plugin virtctl para kubectl:

    sudo -E bmctl install virtctl
    

    O seguinte exemplo de resultado mostra que o virtctlprocesso de instalação do plug-in está concluído:

    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. Valide a instalação do plugin virtctl:

    kubectl virt
    

    O exemplo de resultado seguinte mostra que o plugin virtctl está disponível para utilização com 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.
    ...
    

Implemente a carga de trabalho baseada em VMs

Quando implementa uma VM numa instalação do Google Distributed Cloud (apenas software) em hardware não processado, o VM Runtime no GDC espera uma imagem de VM. Esta imagem serve como disco de arranque para a VM implementada.

Neste tutorial, migra uma carga de trabalho baseada em VMs do Compute Engine para um cluster. Esta VM do Compute Engine foi criada e a aplicação de ponto de venda (PDV) de exemplo foi configurada para ser executada como um serviço systemd. Foi criada uma imagem de disco desta VM, juntamente com a carga de trabalho da aplicação de PDV, em Google Cloud. Esta imagem foi, em seguida, exportada para um contentor do Cloud Storage como uma imagem qcow2. Use esta imagem qcow2 preparada previamente nos passos seguintes.

O código fonte neste documento está disponível no repositório do GitHub anthos-samples. Use os recursos deste repositório para concluir os passos que se seguem.

  1. Implemente um MySQL StatefulSet. A aplicação de ponto de venda espera estabelecer ligação a uma base de dados MySQL para armazenar informações de inventário e pagamento. O repositório do ponto de venda tem um manifesto de exemplo que implementa um MySQL StatefulSet, configura um ConfigMap associado e um Kubernetes Service. O ConfigMap define as credenciais para a instância do MySQL, que são as mesmas credenciais transmitidas para a aplicação do ponto de venda.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/point-of-sale/main/k8-manifests/common/mysql-db.yaml
    
  2. Implemente a carga de trabalho da VM com a imagem 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 cria um ficheiro YAML com o nome da VM (google-virtctl/pos-vm.yaml). Pode inspecionar o ficheiro para ver a definição de VirtualMachine e VirtualMachineDisk. Em vez de usar o plug-in virtctl, podia ter implementado a carga de trabalho da VM usando definições do modelo de recursos do Kubernetes (KRM), conforme indicado no ficheiro YAML criado.

    Quando o comando é executado com êxito, produz um resultado como o exemplo seguinte, que explica os diferentes recursos que foram criados:

    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. Verifique o estado de criação da VM.

    O recurso VirtualMachine é identificado pelo recurso vm.cluster.gke.io/v1.VirtualMachine no VM Runtime no GDC. A forma abreviada é gvm.

    Quando cria uma VM, são criados os dois recursos seguintes:

    • Um VirtualMachineDisk é o disco persistente para o qual o conteúdo da imagem de VM é importado.
    • Uma VirtualMachine é a própria instância de VM. O DataVolume é montado no VirtualMachine antes de a VM ser iniciada.

    Verifique o estado do VirtualMachineDisk. VirtualMachineDisk cria internamente um recurso DataVolume. A imagem da VM é importada para o DataVolume, que é montado na VM:

    kubectl get datavolume
    

    O exemplo de saída seguinte mostra o início da importação de imagens:

    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    ImportScheduled   N/A                   8s
    
  4. Verifique o estado do VirtualMachine. O VirtualMachine está no estado Provisioning até que o DataVolume seja importado completamente:

    kubectl get gvm
    

    O exemplo de saída seguinte mostra o VirtualMachine a ser aprovisionado:

    NAME      STATUS         AGE     IP
    pos-vm    Provisioning   1m
    
  5. Aguarde que a imagem da VM seja totalmente importada para o DataVolume. Continue a ver o progresso enquanto a imagem é importada:

    kubectl get datavolume -w
    

    O exemplo de saída seguinte mostra a imagem de disco a ser importada:

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

    Quando a importação estiver concluída e o DataVolume for criado, o seguinte exemplo de saída mostra o PHASE de Succeeded :

    kubectl get datavolume
    
    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    Succeeded         100.0%                14m18s
    
  6. Confirme que o VirtualMachine foi criado com êxito:

    kubectl get gvm
    

    Se a criação for bem-sucedida, o STATUS apresenta RUNNING, como mostrado no exemplo seguinte, juntamente com o endereço IP da VM:

    NAME      STATUS    AGE     IP
    pos-vm    Running   40m     192.168.3.250
    

Estabeleça ligação à VM e verifique o estado da aplicação

A imagem usada para a VM inclui a aplicação de exemplo de ponto de venda. A aplicação está configurada para iniciar automaticamente no arranque como um serviço systemd. Pode ver os ficheiros de configuração dos serviços systemd no diretório pos-systemd-services.

  1. Estabeleça ligação à consola da VM. Execute o seguinte comando e prima Enter⏎ depois de ver a mensagem Successfully connected to pos-vm…:

    kubectl virt console pos-vm
    

    Este comando produz o seguinte exemplo de resultado que lhe pede para introduzir os detalhes de início de sessão:

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

    Use a seguinte conta de utilizador e palavra-passe. Esta conta foi configurada na VM original a partir da qual a imagem para o VM Runtime no GDC VirtualMachine foi criada.

    • Nome de utilizador de início de sessão: abmuser
    • Palavra-passe: abmworks
  2. Verifique o estado dos serviços da aplicação de ponto de venda. A aplicação de ponto de venda inclui três serviços: API, inventário e pagamentos. Todos estes serviços são executados como serviços do sistema.

    Os três serviços ligam-se entre si através do localhost. No entanto, a aplicação liga-se à base de dados do MySQL através de um serviço do Kubernetes mysql-db que foi criado no passo anterior. Este comportamento significa que a VM está automaticamente ligada à mesma rede que o Pods e o Services, o que permite uma comunicação perfeita entre as cargas de trabalho da VM e outras aplicações em contentores. Não tem de fazer nada mais para tornar o Kubernetes Services acessível a partir das VMs implementadas através do tempo de execução de VMs no GDC.

    sudo systemctl status pos*
    

    O exemplo de saída seguinte mostra o estado dos três serviços e do serviço do sistema raiz, 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. Saia da VM. Para sair da ligação à consola, use a sequência de escape ^] premindo Ctrl + ].

Aceda à carga de trabalho baseada em VMs

Se o cluster foi configurado seguindo o guia Instalar com o balanceador de carga manual, já tem um recurso Ingress denominado pos-ingress criado. Este recurso encaminha o tráfego do endereço IP externo do balanceador de carga do Ingress para o serviço do servidor da API da aplicação de exemplo do ponto de venda.

  1. Se o seu cluster não tiver este recurso Ingress, crie-o aplicando o seguinte manifesto:

    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. Crie um Kubernetes Service que encaminhe o tráfego para a VM. O Ingress recurso encaminha o tráfego para este Service:

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

    O exemplo de resultado seguinte confirma a criação de um serviço:

    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. Obtenha o endereço IP externo do balanceador de carga Ingress. O Ingress balanceador de carga encaminha o tráfego com base nas regras de recursos Ingress. Já tem uma regra pos-ingress para encaminhar pedidos para o servidor da APIService. Este Service encaminha os pedidos para a VM:

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

    O exemplo de saída seguinte mostra o endereço IP do balanceador de carga Ingress:

    172.29.249.159 # you might have a different IP address
    
  4. Aceda à aplicação através do endereço IP do balanceador de carga do Ingress num navegador. As seguintes capturas de ecrã de exemplo mostram o quiosque do ponto de venda com dois artigos. Pode clicar nos artigos mais do que uma vez se quiser encomendar vários e fazer uma encomenda com o botão Pagar. Esta experiência mostra que implementou com êxito uma carga de trabalho baseada em VMs num cluster através do tempo de execução de VMs no GDC.

IU da aplicação de ponto de venda
IU da aplicação de ponto de venda (clique na imagem para aumentar)

Limpar

Pode eliminar todos os recursos criados neste tutorial ou eliminar apenas a VM e manter os recursos reutilizáveis. O artigo Elimine uma VM explica as opções disponíveis em detalhe.

Eliminar tudo

  • Elimine o VM Runtime no GDC VirtualMachine juntamente com todos os recursos:

    kubectl virt delete vm pos-vm --all
    

    O exemplo de resultado seguinte confirma a eliminação:

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

Elimine apenas a VM

  • Se eliminar apenas a VM, preserva o VirtualMachineDisk criado. Isto permite a reutilização desta imagem de VM e poupa tempo gasto na importação da imagem quando cria uma nova VM.

    kubectl virt delete vm pos-vm
    

    O exemplo de resultado seguinte confirma a eliminação:

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

O que se segue?

  • A VM original usada neste guia é uma instância do Compute Engine que executa o Ubuntu 20.04 LTS. A imagem desta VM é acessível publicamente através do contentor do Cloud Storage pos-vm-images. Para mais informações sobre como a VM foi configurada e a respetiva imagem foi criada, consulte as instruções no repositório do ponto de venda.
  • Quando cria uma VM num cluster através do comando kubectl virt create vm pos-vm, é criado um ficheiro YAML com o nome da VM (google-virtctl/pos-vm.yaml). Pode inspecionar o ficheiro para ver a definição de VirtualMachine e VirtualMachineDisk. Em vez de usar o plug-in virtctl, pode implementar uma VM usando definições KRM , conforme visto no ficheiro YAML criado.