Tutorial: implantar uma VM atual em um cluster bare metal do GKE usando o ambiente de execução de VMs no GDC


Neste documento, apresentamos um guia explicativo para implantar uma carga de trabalho baseada em máquina virtual (VM) no GKE em Bare Metal usando o ambiente de execução da VM na GDC. A carga de trabalho usada neste guia é a amostra do aplicativo de ponto de venda. Este aplicativo representa um terminal de ponto de venda típico que é executado em hardware local em uma loja de varejo.

Neste documento, você vai migrar esse aplicativo de uma VM para um cluster do GKE em Bare Metal e acessar o front-end da Web do aplicativo. Para migrar uma VM para o cluster, primeiro é necessário criar uma imagem de disco dessa VM. Em seguida, a imagem precisa ser hospedada em um repositório que o cluster possa acessar. Por fim, o URL dessa imagem pode ser usado para criar a VM. O ambiente de execução de VM no GDC espera que as imagens estejam no formato qcow2. Se você fornecer um tipo de imagem diferente, ele será automaticamente convertido para o formato qcow2. Para evitar conversões repetitivas e permitir a reutilização, é possível converter uma imagem de disco virtual e hospedar a imagem qcow2.

Neste documento, usamos uma imagem pré-preparada de uma instância de VM do Compute Engine em que a carga de trabalho é executada como um serviço systemd. Siga as mesmas etapas para implantar seu próprio aplicativo.

Objetivos

Antes de começar

Para preencher este documento, você precisa dos recursos a seguir:

  • Acesso a um cluster do GKE em Bare Metal versão 1.12.0 ou mais recente que foi criado seguindo o guia Como executar o GKE em Bare Metal em VMs do Compute Engine com balanceador de carga manual. Nesse documento, você vai ver a configuração de recursos de rede para que seja possível acessar a carga de trabalho executada na VM por um navegador. Se você não precisar desse comportamento, siga este documento usando qualquer Cluster do GKE em Bare Metal.
  • Uma estação de trabalho que atenda aos requisitos a seguir:
    • Acesso ao cluster usando a CLI bmctl.
    • Acesso ao cluster usando a CLI kubectl.

Ative o ambiente de execução da VM na GDC e instale o plug-in virtctl

A definição de recurso personalizada (CRD, na sigla em inglês) do VM Runtime no GDC faz parte de todos os clusters do GKE em Bare Metal desde a versão 1.10. Uma instância do recurso personalizado VMRuntime já foi criada na instalação. No entanto, ele fica desativado por padrão.

  1. Ative o ambiente de execução da VM no GDC:

    sudo bmctl enable vmruntime --kubeconfig KUBECONFIG_PATH
    
    • KUBECONFIG_PATH: caminho para o arquivo de configuração do Kubernetes do cluster de usuário do GKE Enterprise
  2. Verifique se VMRuntime está ativado:

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

    Pode demorar alguns minutos para que VMRuntime fique pronto. Se não ficar, verifique algumas vezes com pequenos intervalos de tempo. O exemplo de saída a seguir mostra que VMRuntime está pronto:

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

    sudo -E bmctl install virtctl
    

    A saída de exemplo a seguir mostra que o processo de instalação do plug-in virtctl foi 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. Verifique a instalação do plug-in virtctl:

    kubectl virt
    

    O exemplo de saída a seguir mostra que o plug-in virtctl está disponível para uso 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.
    ...
    

Implantar a carga de trabalho baseada em VM

Quando você implanta uma VM no GKE em Bare Metal, o ambiente de execução da VM na GDC espera uma imagem de VM. Essa imagem serve como o disco de inicialização da VM implantada.

Neste tutorial, você migra uma carga de trabalho baseada em VM do Compute Engine para um cluster do GKE em Bare Metal. Esta VM do Compute Engine foi criada, e o aplicativo de ponto de venda (PoS, na sigla em inglês de exemplo) foi configurado para ser executado como um serviço systemd. Uma imagem de disco dessa VM com a carga de trabalho do aplicativo de PoS foi criada no Google Cloud. Essa imagem foi exportada para um bucket do Cloud Storage como uma imagem qcow2. Use essa imagem qcow2 pré-preparada nas etapas a seguir.

O código-fonte deste documento está disponível no repositório anthos-samples do GitHub. Você usa os recursos desse repositório para concluir as etapas a seguir.

  1. Implante um StatefulSet do MySQL. O aplicativo de ponto de venda espera se conectar a um banco de dados MySQL para armazenar informações de inventário e pagamento. O repositório de ponto de venda tem um manifesto de amostra que implanta um StatefulSet do MySQL, configura um ConfigMap associado e um Service do Kubernetes. O ConfigMap define as credenciais da instância do MySQL, que são as mesmas credenciais transmitidas ao aplicativo de ponto de venda.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/point-of-sale/main/k8-manifests/common/mysql-db.yaml
    
  2. Implante a carga de trabalho da VM usando a imagem qcow2 pré-preparada:

    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
    

    Esse comando cria um arquivo YAML com o nome da VM (google-virtctl/pos-vm.yaml). É possível inspecionar o arquivo para ver a definição de VirtualMachine e VirtualMachineDisk. Em vez de usar o plug-in virtctl, é possível implantar a carga de trabalho da VM usando definições do Kubernetes Resource Model (KRM), como visto no arquivo YAML criado.

    Quando o comando é executado com êxito, ele produz um resultado como o exemplo a seguir, que explica os diferentes recursos 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 status de criação da VM.

    O recurso VirtualMachine é identificado pelo recurso vm.cluster.gke.io/v1.VirtualMachine no ambiente de execução da VM na GDC. A forma curta é gvm.

    Durante a criação de uma VM, são criados os dois recursos a seguir:

    • O VirtualMachineDisk é o disco permanente para onde o conteúdo da imagem da VM é importado.
    • Uma VirtualMachine é a própria instância de VM. O DataVolume é ativado na VirtualMachine antes de uma VM ser inicializada.

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

    kubectl get datavolume
    

    Este exemplo de saída mostra o início da importação da imagem:

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

    kubectl get gvm
    

    O exemplo de saída a seguir mostra a VirtualMachine sendo provisionada:

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

    kubectl get datavolume -w
    

    A saída de exemplo a seguir mostra a imagem do disco que está sendo 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 for concluída e DataVolume for criado, o exemplo de saída a seguir vai mostrar o PHASE de Succeeded :

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

    kubectl get gvm
    

    Se a criação for bem-sucedida, STATUS vai mostrar RUNNING, como mostrado no exemplo a seguir, junto com o endereço IP da VM:

    NAME      STATUS    AGE     IP
    pos-vm    Running   40m     192.168.3.250
    

Conectar-se à VM e verificar o status do aplicativo

A imagem usada para a VM inclui o aplicativo de amostra de ponto de venda. O aplicativo está configurado para iniciar automaticamente na inicialização como um serviço systemd. Veja os arquivos de configuração dos serviços systemd no diretório pos-systemd-services.

  1. Conecte-se ao console da VM. Execute o comando a seguir e pressione Enter⏎ depois de ver a mensagem Successfully connected to pos-vm…:

    kubectl virt console pos-vm
    

    Este comando produz o exemplo de saída a seguir, que solicita que você insira os detalhes de login:

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

    Use a conta de usuário e a senha a seguir. Essa conta foi configurada dentro da VM original a partir da qual a imagem do VM Runtime no GDC VirtualMachine foi criada.

    • Nome de usuário do login: abmuser
    • Senha: abmworks
  2. Verifique o status dos serviços de aplicativos do ponto de venda. O aplicativo de ponto de venda inclui três serviços: API, Inventory e Payments. Todos esses serviços são executados como serviços do sistema.

    Os três serviços se conectam pelo localhost. No entanto, o aplicativo se conecta ao banco de dados MySQL usando um serviço mysql-db do Kubernetes criado na etapa anterior. Esse comportamento significa que a VM é conectada automaticamente à mesma rede que Pods e Services, permitindo a comunicação perfeita entre as cargas de trabalho da VM e outros aplicativos em contêiner. Não é necessário fazer nada extra para tornar o Services do Kubernetes acessível a partir das VMs implantadas usando o ambiente de execução da VM na GDC.

    sudo systemctl status pos*
    

    A saída de exemplo a seguir mostra o status 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 conexão de console, use a sequência de escape ^] pressionando Ctrl + ].

Acessar a carga de trabalho baseada em VM

Se o cluster foi configurado seguindo o guia Como executar o GKE em Bare Metal em VMs do Compute Engine com balanceador de carga manual, ele já tem um recurso Ingress chamado pos-ingress. Ele roteia o tráfego do endereço IP externo do balanceador de carga do Ingress para o serviço do servidor da API do aplicativo de amostra do ponto de venda.

  1. Se o cluster não tiver esse 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 Service do Kubernetes que encaminhe o tráfego para a VM. O recurso Ingress 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 saída abaixo 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. Consiga o endereço IP externo do balanceador de carga Ingress. O Loadbalancer Ingress encaminha o tráfego com base nas regras de recurso Ingress. Você já tem uma regra pos-ingress para encaminhar solicitações ao servidor da API Service. Este Service encaminha as solicitações para a VM:

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

    A saída de exemplo a seguir mostra o endereço IP do balanceador de carga Ingress:

    172.29.249.159 # you might have a different IP address
    
  4. Acesse o aplicativo usando o endereço IP do recurso Loadbalancer do Ingress em um navegador. As capturas de tela de exemplo a seguir mostram o quiosque de ponto de venda simples com dois itens. Você pode clicar nos itens mais de uma vez se quiser pedir vários deles e fazer um pedido com o botão Pagar. Essa experiência mostra que você implantou com sucesso uma carga de trabalho baseada em VM em um cluster do GKE em Bare Metal usando o ambiente de execução de VM no GDC.

IU do ponto de venda do aplicativo
IU do aplicativo de ponto de venda (clique na imagem para ampliá-la)

Limpar

É possível excluir todos os recursos criados neste tutorial ou apenas a VM e manter os recursos reutilizáveis. O artigo Excluir uma VM no GKE em Bare Metal explica em detalhes as opções disponíveis.

Excluir tudo

  • Exclua o ambiente de execução da VM na GDC VirtualMachine com todos os recursos:

    kubectl virt delete vm pos-vm --all
    

    O exemplo de saída a seguir confirma a exclusã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".
    

Excluir apenas a VM

  • A exclusão apenas da VM preserva o VirtualMachineDisk criado. Isso permite a reutilização dessa imagem de VM e economiza o tempo gasto na importação da imagem ao criar uma nova VM.

    kubectl virt delete vm pos-vm
    

    O exemplo de saída a seguir confirma a exclusão:

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

A seguir

  • A VM original usada neste guia é uma instância do Compute Engine que executa o Ubuntu 20.04 LTS. A imagem dessa VM é acessível publicamente pelo bucket do Cloud Storage pos-vm-images. Para mais informações sobre como a VM foi configurada e a respectiva imagem criada, consulte as instruções no repositório do ponto de venda.
  • Ao criar uma VM em um cluster do GKE em Bare Metal usando o comando kubectl virt create vm pos-vm, um arquivo YAML nomeado com base na VM (google-virtctl/pos-vm.yaml) é criado. É possível inspecionar o arquivo para ver a definição de VirtualMachine e VirtualMachineDisk. Em vez de usar o plug-in virtctl, é possível implantar uma VM usando definições de KRM, como visto no arquivo YAML criado.