Configurar rotinas de inicialização da VM

Quando você usa o Google Distributed Cloud versão 1.13.0 e mais recentes, é possível especificar rotinas de inicialização para personalizar a inicialização da VM na inicialização. Você pode configurar sua VM para criar chaves SSH, adicionar usuários e senhas, instalar pacotes, gravar arquivos, definir configurações de rede e muito mais.

Essas tarefas de inicialização são configuradas com a API cloud-init ou com a API de scripts de inicialização (não ambas). Essas diretivas de inicialização são especificadas no arquivo de manifesto YAML VirtualMachine e são executadas automaticamente sempre que a VM é iniciada.

Pré-requisitos

Para configurar uma VM com diretivas de inicialização, atenda aos seguintes pré-requisitos:

As seções a seguir descrevem como especificar rotinas de inicialização no manifesto da VM com a API Cloud-init ou scripts de inicialização.

Usar a API cloud-init para inicializar VMs

O Cloud-init costuma ser usado para a inicialização de instâncias da nuvem e para personalizar VMs durante a inicialização. A inicialização da VM geralmente envolve tarefas como instalações de pacotes, configuração do repositório, criação de chaves SSH, gravação de dados em arquivos e configuração de outros aspectos da VM. Incorpore o YAML de configuração do cloud-init no recurso personalizado VirtualMachine com o campo spec.cloudInit. Quando a instância da VM é iniciada, o cloud-init lê os dados fornecidos e inicializa a VM corretamente.

Observe os seguintes detalhes da nossa implementação do cloud-init:

  • Especifique dados de cloud-init no manifesto do YAML VirtualMachine ao criar ou atualizar uma VM. Para instruções sobre como criar uma VM aplicando um manifesto, consulte Tutorial: criar e gerenciar uma VM Linux no ambiente de execução de VM no GDC.

  • Usamos a fonte de dados NoCloud, spec.cloudInit.noCloud, na especificação da VM.

  • Especifique dados do usuário e dados de rede em seções separadas no manifesto VirtualMachine. A nomenclatura e a estrutura da seção dependem do formato de dados que você decide usar.

  • É possível especificar informações de configuração do cloud-init nos seguintes formatos de dados:

    • Limpar texto
    • String codificada em base64
    • Secret do Kubernetes

Para ajudar você a começar, fornecemos alguns exemplos de configuração para tarefas comuns de inicialização de VM.

Dados do usuário de Cloud-init

O ambiente de execução de VM no GDC é compatível com os dados do usuário do cloud-init na sintaxe do config-cloud. Portanto, inicie os dados do usuário com #cloud-config. É possível formatar os dados do usuário como texto não criptografado, uma string codificada em base64 ou uma chave secreta do Kubernetes.

Para saber mais sobre a sintaxe de dados do usuário e a referência do módulo, consulte a documentação do Cloud-init.

Dados do usuário do Cloud-init como texto não criptografado

O manifesto de exemplo a seguir mostra como especificar os dados do usuário como texto não criptografado. Nesse caso, o cloud-init executa um comando quando a VM é iniciada:

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - echo hello

Dados do usuário do Cloud-init como uma string codificada em base64

O exemplo a seguir mostra como especificar dados do usuário no formato codificado em Base64. Neste exemplo, os dados do usuário consistem no mesmo comando echo hello do exemplo de texto não criptografado:

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userDataBase64: I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBlY2hvIGhlbGxvCg==

Dados do usuário do Cloud-init como um secret do Kubernetes

O exemplo a seguir mostra um manifesto YAML para VirtualMachine e Secret. A seção spec.cloudInit.noCloud.secretRef na configuração de VirtualMachine indica que os dados do usuário de cloud-init estão em um secret do Kubernetes chamado my-sec. A configuração Secret correspondente especifica os dados do usuário como um par de chave-valor. O valor codificado em base64 nesse caso são os dados do usuário de cloud-init na sintaxe de cloud-config.

Na chave secreta referenciada, use a chave de dados userData (mostrada) ou userdata para especificar os dados do usuário de cloud-init.

Neste exemplo, os dados do usuário consistem no mesmo comando echo hello do exemplo de texto não criptografado:

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      secretRef:
        name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  userData: I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBlY2hvIGhlbGxvCg==

Se o Secret referenciado não for encontrado ou a chave de dados userData ou userdata não existir no Secret, observe o seguinte comportamento de inicialização da VM:

  • Para a criação da VM, a VM é colocada no estado ErrorConfiguration com um motivo e uma mensagem detalhados.

  • Em outros casos, a VM continua usando os dados do usuário cloud-init antigos até que a VM seja configurada corretamente. Por isso, o agente convidado para ativar ou desativar as atualizações não entrará em vigor até que a VM seja configurada corretamente.

Para recuperar informações da VM, incluindo quais dados do usuário de cloud-init foram usados, use o seguinte comando:

kubectl get vm VM_NAME -o yaml --kubeconfig KUBECONFIG_PATH

Substitua:

  • VM_NAME: o nome da VM.

  • KUBECONFIG_PATH: o caminho para o arquivo kubeconfig do cluster que contém sua VM.

Para recuperar o evento de aviso relacionado do Kubernetes, use kubectl get event ou kubectl describe gvm.

Dados de rede do Cloud-init

Assim como os dados do usuário, é possível formatar os dados da rede como texto não criptografado, uma string codificada em base64 ou um secret do Kubernetes. Ao contrário dos dados do usuário, os dados de rede não usam a sintaxe de configuração da nuvem.

Ao usar texto não criptografado ou uma string codificada em base64, o tamanho máximo permitido é 2048 bytes. Se o tamanho dos dados do usuário for próximo ou maior que 2.048 bytes, especifique-o como um Secret do Kubernetes.

Para mais informações sobre a sintaxe de dados de rede e detalhes relacionados, consulte a Configuração de rede da versão 2 na documentação do cloud-init.

Dados de rede do Cloud-init como texto não criptografado

O exemplo de manifesto a seguir mostra como especificar dados de rede como texto não criptografado. Nesse caso, o cloud-init ativa o DHCP para todos os dispositivos Ethernet com nomes que começam com um "e" (e*):

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - echo hello
      networkData: |
        version: 2
        ethernets:
          alleths:
            match:
              name: e*
            dhcp4: true

Dados de rede do Cloud-init como uma string codificada em base64

O exemplo a seguir mostra como especificar dados de rede no formato codificado em Base64. Neste exemplo, os dados de rede consistem na mesma configuração de DHCP especificada no exemplo de texto não criptografado:

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      networkDataBase64: dmVyc2lvbjogMgpldGhlcm5ldHM6CiAgYWxsZXRoczoKICAgIG1hdGNoOgogICAgICBuYW1lOiBlKgogICAgZGhjcDQ6IHRydWUK

Dados de rede do Cloud-init como um secret do Kubernetes

O exemplo a seguir mostra um manifesto YAML para VirtualMachine e Secret. A seção spec.cloudInit.noCloud.networkDataSecretRef na configuração de VirtualMachine indica que os dados da rede cloud-init estão em um secret do Kubernetes chamado my-sec. A configuração Secret correspondente especifica os dados de rede como um par de chave-valor. O valor codificado em base64 nesse caso são os dados da rede cloud-init.

No Secret referenciado, use a chave de dados networkData (mostrada) ou networkdata para especificar os dados da rede cloud-init.

Neste exemplo, os dados de rede consistem na mesma configuração de DHCP especificada no exemplo de texto não criptografado:

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      networkDataSecretRef:
        name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  networkData: dmVyc2lvbjogMgpldGhlcm5ldHM6CiAgYWxsZXRoczoKICAgIG1hdGNoOgogICAgICBuYW1lOiBlKgogICAgZGhjcDQ6IHRydWUK

Exemplos do Cloud-init

As seções a seguir contêm exemplos de texto não criptografados de alguns casos de uso comuns para inicialização da VM com cloud-init:

Configurar chaves SSH autorizadas

O exemplo de dados do usuário a seguir atribui a chave SSH autorizada ssh-rsa AAAAB3NzaK8L93bWxnyp ao usuário padrão.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        ssh_authorized_keys:
          - ssh-rsa AAAAB3NzaK8L93bWxnyp

Adicionar um novo usuário

O exemplo de dados do usuário a seguir cria um test de usuário e concede a test acesso sudo total. Este exemplo atribui ao usuário uma senha não expirante de pwd.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        users:
        - default
        - name: test
          sudo: ALL=(ALL) NOPASSWD:ALL
        chpasswd:
          list: |
            test:pwd
          expire: False

Executar comandos na primeira inicialização

O exemplo de dados do usuário a seguir executa um comando echo e ls. É possível usar comandos para instalar pacotes e muito mais quando a VM for iniciada.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - [ echo, hello ]
          - [ ls, -l, / ]

Gravar arquivos

O exemplo de dados do usuário a seguir grava um script bash no arquivo test no diretório /var/lib/google da VM. As diretivas cloud-init definem as permissões de arquivo para ler, gravar e executar (0744) para o proprietário do arquivo.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        write_files:
        - path: /var/lib/google/test
          permissions: 0744
          content: |
            #!/bin/bash
            echo hello

Solução de problemas da cloud-init

Se você encontrar problemas na inicialização da VM e estiver usando cloud-init, verifique os seguintes registros de cloud-init na VM:

  • /var/log/cloud-init.log: por padrão, o cloud-init grava todos os eventos com um nível de DEBUG ou mais recente nesse registro.

  • /var/log/cloud-init-output.log: por padrão, o cloud-init direciona stdout e stderr de todos os estágios do cloud-init para esse registro.

Usar scripts de inicialização para inicializar VMs

Os scripts de inicialização realizam tarefas durante o processo de inicialização de uma instância de máquina virtual (VM). É possível especificar um ou mais scripts na seção spec.startupScripts da especificação VirtualMachine. Os scripts de inicialização podem ser usados para inicializar sua VM. A inicialização da VM geralmente envolve tarefas como instalações de pacotes, configuração do repositório, criação de chaves SSH, gravação de dados em arquivos e configuração de outros aspectos da VM.

Observe os seguintes detalhes sobre os scripts de inicialização:

  • Especifique scripts de inicialização no manifesto YAML VirtualMachine ao criar ou atualizar uma VM. Para instruções sobre como criar uma VM aplicando um manifesto, consulte Tutorial: criar e gerenciar uma VM Linux no ambiente de execução de VM no GDC.

  • Os scripts especificados são executados sempre que a VM é iniciada.

  • Inclua #!/bin/... na parte superior do script para indicar o interpretador de scripts. Por exemplo, inclua #!/bin/bash para executar o script com o Shell do Bash.

  • Não é possível especificar as diretivas da API Cloud-init (spec.cloudInit) e os scripts de inicialização (spec.startupScripts) no mesmo manifesto VirtualMachine.

Formatos de script

É possível especificar scripts de inicialização nos seguintes formatos de dados:

  • Limpar texto
  • String codificada em base64
  • Secret do Kubernetes

Observe as seguintes regras para trabalhar com diferentes formatos de script:

  • Ao usar texto não criptografado ou uma string codificada em base64, o tamanho máximo permitido para o conteúdo do script é 2.048 bytes. Se o tamanho do conteúdo do script for próximo ou maior que 2.048 bytes, especifique scripts como um Secret do Kubernetes.

  • Ao usar um secret do Kubernetes, utilize a chave de dados script no secret referenciado para especificar o conteúdo do script.

  • Se uma chave secreta referenciada não for encontrada ou se a chave de dados script não existir na chave secreta referenciada, a VM continuará executando o script. No entanto, a VM não grava nem atualiza o conteúdo do script. Nesse caso, é possível encontrar o evento de aviso do Kubernetes com kubectl get event ou kubectl describe gvm.

O manifesto YAML de amostra VirtualMachine a seguir contém três scripts, um em cada um dos formatos compatíveis. Nesse caso, cada script executa o comando echo hello mostrado em myscript1, o exemplo de texto não criptografado.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  startupScripts:
  - name: myscript1
    script: |
      #!/bin/bash
      echo hello
  - name: myscript2
    scriptBase64: IyEvYmluL2Jhc2gKICAgICAgZWNobyBoZWxsbwo=
  - name: myscript3
    scriptSecretRef:
      name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  script: IyEvYmluL2Jhc2gKICAgICAgZWNobyBoZWxsbwo=

Solução de problemas de script

Para verificar os resultados ou registros do script, execute o seguinte comando:

journalctl -u cloud-final

As entradas do registro do script de inicialização começam com o seguinte texto:

started to run the command /var/lib/google/startup-scripts/SCRIPT_NAME ...

A entrada de registro inclui SCRIPT_NAME, o nome do script de inicialização.