Configura las rutinas de inicio de la VM

Cuando usas GKE en Bare Metal versión 1.13.0 y posteriores, puedes especificar rutinas de inicio para personalizar la inicialización de tu VM en el inicio. Puedes configurar tu VM para crear claves SSH, agregar usuarios y contraseñas, instalar paquetes, escribir archivos, establecer la configuración de red y más.

Estas tareas de inicio se configuran con la API de cloud-init o con la API de las secuencias de comandos de inicio (no ambas). Estas directivas de inicio se especifican en el archivo de manifiesto YAML VirtualMachine y se ejecutan de forma automática cada vez que se inicia la VM.

Requisitos previos

Para configurar una VM con directivas de inicio, debes cumplir con los siguientes requisitos:

En las siguientes secciones, se describe cómo especificar rutinas de inicio en el manifiesto de VM con la API de cloud-init o las secuencias de comandos de inicio.

Usa la API de cloud-init para inicializar las VMs

Cloud-init se usa, por lo general, para la inicialización de instancias en la nube y la personalización de VMs durante el inicio. La inicialización de VMs suele implicar tareas como la instalación de paquetes, la configuración de repositorios, la creación de claves SSH, la escritura de datos en archivos y la configuración de otros aspectos de tu VM. Incorpora YAML de configuración cloud-init en el recurso personalizado VirtualMachine con el campo spec.cloudInit. Cuando se inicia la instancia de VM, cloud-init lee los datos proporcionados e inicializa la VM según corresponda.

Ten en cuenta los siguientes detalles de nuestra implementación de cloud-init:

  • Debes especificar los datos de cloud-init en el manifiesto YAML de VirtualMachine cuando creas o actualizas una VM. Si deseas obtener instrucciones para crear una VM mediante la aplicación de un manifiesto, consulta Instructivo: Crea y administra una VM de Linux en el entorno de ejecución de VM en GDC.

  • Usamos la fuente de datos NoCloud, spec.cloudInit.noCloud, en nuestra especificación de VM.

  • Debes especificar los datos del usuario y los datos de red en secciones separadas del manifiesto de VirtualMachine. El nombre y la estructura de la sección dependen del formato de datos que decidas usar.

  • Puedes especificar la información de configuración de cloud-init en los siguientes formatos de datos:

    • Borrar el texto
    • String codificada en base64
    • Secret de Kubernetes

A fin de ayudarte a comenzar, proporcionamos algunos ejemplos de configuración para realizar tareas comunes de inicialización de VMs.

Datos del usuario de cloud-init

El entorno de ejecución de VM en GDC admite los datos del usuario cloud-init en la sintaxis cloud-config, por lo que debes comenzar los datos del usuario con #cloud-config. Puedes formatear los datos del usuario como texto sin encriptar, una string codificada en base64 o un Secret de Kubernetes.

Para obtener más información sobre la sintaxis de los datos del usuario y la referencia del módulo, consulta la documentación de cloud-init.

Datos del usuario de cloud-init como texto sin encriptar

En el siguiente manifiesto de ejemplo, se muestra cómo especificar los datos del usuario como texto sin encriptar. En este caso, cloud-init ejecuta un comando cuando se inicia la VM:

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

Cloud-init para datos del usuario como una string codificada en base64

En el siguiente ejemplo, se muestra cómo especificar datos de usuarios en formato codificado en base64. En este ejemplo, los datos del usuario constan del mismo comando echo hello que en el ejemplo de texto sin encriptar:

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

Datos del usuario de cloud-init como un Secret de Kubernetes

En el siguiente ejemplo, se muestra un manifiesto YAML para VirtualMachine y Secret. En la sección spec.cloudInit.noCloud.secretRef de la configuración de VirtualMachine, se indica que los datos del usuario de cloud-init se encuentran en un Secret de Kubernetes llamado my-sec. La configuración Secret correspondiente especifica los datos del usuario como un par clave-valor. En este caso, el valor codificado en base64 son los datos de usuario de cloud-init en sintaxis cloud-config.

En el Secret al que se hace referencia, usa la clave de datos userData (que se muestra) o userdata para especificar los datos del usuario de cloud-init.

En este ejemplo, los datos del usuario constan del mismo comando echo hello que en el ejemplo de texto sin encriptar:

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

Si no se encuentra el Secret al que se hace referencia o la clave de datos userData o userdata no existen en el Secret, ten en cuenta el siguiente comportamiento de inicio de la VM:

  • Para la creación de la VM, esta se pone en un estado ErrorConfiguration con un motivo y un mensaje detallados.

  • En otros casos, la VM continúa usando los datos del usuario de cloud-init anteriores hasta que la VM esté configurada de forma correcta. Como resultado, las actualizaciones de habilitación o inhabilitación del agente invitado no se aplican hasta que la VM esté configurada de forma correcta.

Para recuperar información de VM, incluidos los datos del usuario de cloud-init que se usaron, usa el siguiente comando:

kubectl get vm VM_NAME -o yaml --kubeconfig KUBECONFIG_PATH

Reemplaza lo siguiente:

  • VM_NAME: El nombre de tu VM.

  • KUBECONFIG_PATH: es la ruta de acceso al archivo kubeconfig del clúster que contiene tu VM.

Para recuperar el evento de advertencia de Kubernetes relacionado, usa kubectl get event o kubectl describe gvm.

Datos de red de cloud-init

Al igual que con los datos del usuario, puedes formatear los datos de la red como texto sin encriptar, una string codificada en base64 o un Secret de Kubernetes. A diferencia de los datos del usuario, los datos de red no usan la sintaxis cloud-config.

Cuando se usa texto sin encriptar o una string codificada en base64, el tamaño máximo permitido es de 2048 bytes. Si el tamaño de los datos del usuario es cercano o superior a 2048 bytes, especifícalo como un Secret de Kubernetes.

Para obtener más información sobre la sintaxis de datos de red y los detalles relacionados, consulta la versión 2 de configuración de la red en la documentación de cloud-init.

Datos de red de cloud-init como texto sin encriptar

En el siguiente manifiesto de ejemplo, se muestra cómo especificar datos de red como texto sin encriptar. En este caso, cloud-init habilita DHCP para todos los dispositivos Ethernet con nombres que comienzan con “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

Datos de red de cloud-init como una string codificada en base64

En el siguiente ejemplo, se muestra cómo especificar datos de red en formato codificado en base64. En este ejemplo, los datos de red constan de la misma configuración de DHCP especificada en el ejemplo de texto sin encriptar:

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

Datos de red de cloud-init como un Secret de Kubernetes

En el siguiente ejemplo, se muestra un manifiesto YAML para VirtualMachine y Secret. En la sección spec.cloudInit.noCloud.networkDataSecretRef de la configuración de VirtualMachine, se indica que los datos de red de cloud-init se encuentran en un Secret de Kubernetes llamado my-sec. La configuración Secret correspondiente especifica los datos de red como un par clave-valor. En este caso, el valor codificado en base64 son los datos de red de cloud-init.

En el Secret al que se hace referencia, usa la clave de datos networkData (mostrada) o networkdata para especificar los datos de red de cloud-init.

En este ejemplo, los datos de red constan de la misma configuración de DHCP especificada en el ejemplo de texto sin encriptar:

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

Ejemplos de cloud-init

Las siguientes secciones contienen ejemplos de texto sin encriptar de algunos casos de uso comunes para la inicialización de VMs con cloud-init:

Configura claves SSH autorizadas

En el siguiente ejemplo de datos del usuario, se asigna la clave SSH autorizada ssh-rsa AAAAB3NzaK8L93bWxnyp al usuario predeterminado.

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

Agregar un usuario nuevo

En el siguiente ejemplo de datos de usuario, se crea un usuario test y se le otorga a test acceso completo a sudo. En este ejemplo, se asigna al usuario una contraseña sin vencimiento 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

Ejecuta comandos en el primer inicio

En el siguiente ejemplo de datos del usuario, se ejecuta un comando echo y un comando ls. Puedes usar comandos para instalar paquetes y más cuando se inicia la VM.

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

Escribe archivos

En el siguiente ejemplo de datos del usuario, se escribe una secuencia de comandos bash en el archivo test en el directorio /var/lib/google de la VM. Las directivas cloud-init establecen los permisos de archivo para leer, escribir y ejecutar (0744) del propietario del archivo.

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

Soluciona problemas de cloud-init

Si tienes problemas con la inicialización de tu VM y usas cloud-init, verifica los siguientes registros de cloud-init en tu VM:

  • /var/log/cloud-init.log: De forma predeterminada, cloud-init escribe todos los eventos con un nivel de DEBUG o superior en este registro.

  • /var/log/cloud-init-output.log: De forma predeterminada, cloud-init dirige a stdout y stderr de todas las etapas de cloud-init a este registro.

Usa secuencias de comandos de inicio para inicializar las VMs

Las secuencias de comandos de inicio realizan tareas durante el proceso de inicio de una instancia de máquina virtual (VM). Puedes especificar una o más secuencias de comandos en la sección spec.startupScripts de la especificación VirtualMachine. Las secuencias de comandos de inicio se pueden usar para inicializar tu VM. La inicialización de VMs suele implicar tareas como la instalación de paquetes, la configuración de repositorios, la creación de claves SSH, la escritura de datos en archivos y la configuración de otros aspectos de tu VM.

Ten en cuenta los detalles siguientes para las secuencias de comandos de inicio:

  • Debes especificar secuencias de comandos de inicio en el manifiesto YAML VirtualMachine cuando creas o actualizas una VM. Si deseas obtener instrucciones para crear una VM mediante la aplicación de un manifiesto, consulta Instructivo: Crea y administra una VM de Linux en el entorno de ejecución de VM en GDC.

  • Las secuencias de comandos especificadas se ejecutan cada vez que se inicia la VM.

  • Incluye #!/bin/... en la parte superior de la secuencia de comandos para indicar el intérprete de la secuencia de comandos. Por ejemplo, incluye #!/bin/bash para ejecutar la secuencia de comandos con la shell Bash.

  • No puedes especificar directivas de API de cloud-init (spec.cloudInit) y secuencias de comandos de inicio (spec.startupScripts) en el mismo manifiesto VirtualMachine.

Formatos de secuencia de comandos

Puedes especificar secuencias de comandos de inicio en los siguientes formatos de datos:

  • Borrar el texto
  • String codificada en base64
  • Secret de Kubernetes

Ten en cuenta las siguientes reglas para trabajar con diferentes formatos de secuencia de comandos:

  • Cuando se usa texto sin encriptar o una string codificada en base64, el tamaño máximo permitido para el contenido de la secuencia de comandos es de 2048 bytes. Si el tamaño del contenido de tu secuencia de comandos es cercano o superior a 2048 bytes, especifica las secuencias de comandos como un Secret de Kubernetes.

  • Cuando uses un Secret de Kubernetes, usa la clave de datos script en el Secret al que se hace referencia para especificar el contenido de la secuencia de comandos.

  • Si no se encuentra un Secret al que se hace referencia o la clave de datos script no existe en el Secret al que se hace referencia, la VM continúa ejecutando la secuencia de comandos. Sin embargo, la VM no escribe ni actualiza el contenido de la secuencia de comandos. En este caso, puedes encontrar el evento de advertencia de Kubernetes con kubectl get event o kubectl describe gvm.

El siguiente manifiesto YAML de VirtualMachine de muestra contiene tres secuencias de comandos, una en cada uno de los formatos compatibles. En este caso, cada secuencia de comandos ejecuta el comando echo hello que se muestra en myscript1, el ejemplo de texto sin encriptar.

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=

Solución de problemas de secuencias de comandos

Para verificar los resultados o los registros de la secuencia de comandos, ejecuta el siguiente comando:

journalctl -u cloud-final

Las entradas del registro de secuencias de comandos de inicio comienzan con el siguiente texto:

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

En la entrada de registro, se incluye SCRIPT_NAME, el nombre de la secuencia de comandos de inicio.