Notas Mentales de Un SysAdmin

blog sobre tecnologías para sysadmin y devops

Programar encendido/apagado de VM en GCE

Google Cloud tiene una solución para cada necesidad. Entre las muchas cosas que se pueden hacer, os hoy dejo un mini tutorial de como hacer que las instancias de VM se enciendan y se paren según la programación que nosotros le definamos.

1. Requisitos previos

  • Instancia/s de VM. Puedes ver aquí como crear una nueva instancia de VM.
  • Etiquetas en esa instancia/s.

Para esta documentación, utilizaremos la etiqueta schedule:l-v.

2. Crear Cloud Functions con Cloud Pub/Sub

2.1. Crear la función de inicio.

  1. Ve a la página de Cloud Functions en GCP Console.
    Ir a la página de Cloud Functions
  2. Haz clic en Crear función.
  3. Configura el Nombre como startInstancePubSub.
  4. Deja el valor predeterminado en Memoria asignada.
  5. En Activador, selecciona Cloud Pub/Sub.
  6. En Tema, selecciona Create new topic…
  7. Aparecerá un cuadro de diálogo Nuevo tema pub/sub.
    1. En Nombre, ingresa start-instance-event.
    2. Haz clic en Crear para finalizar el cuadro de diálogo.
  8. En Entorno de ejecución, selecciona Node.js 10.
  9. Sobre el bloque de texto del código, selecciona la pestaña index.js.
  10. Reemplaza el código de inicio con lo siguiente:functions/scheduleinstance/index.js
const Compute = require('@google-cloud/compute');
const compute = new Compute();

exports.startInstancePubSub = async (event, context, callback) => {
  try {
    const payload = _validatePayload(
      JSON.parse(Buffer.from(event.data, 'base64').toString())
    );
    const options = {filter: `labels.${payload.label}`};
    const [vms] = await compute.getVMs(options);
    await Promise.all(
      vms.map(async instance => {
        if (payload.zone === instance.zone.id) {
          const [operation] = await compute
            .zone(payload.zone)
            .vm(instance.name)
            .start();

          // Operation pending
          return operation.promise();
        }
      })
    );
    const message = `Successfully started instance(s)`;
    console.log(message);
    callback(null, message);
  } catch (err) {
    console.log(err);
    callback(err);
  }
};
const _validatePayload = payload => {
  if (!payload.zone) {
    throw new Error(`Attribute 'zone' missing from payload`);
  } else if (!payload.label) {
    throw new Error(`Attribute 'label' missing from payload`);
  }
  return payload;
};

11. Sobre el bloque de texto del código, selecciona la pestaña package.json.
12. Reemplaza el código de inicio con lo siguiente:functions/scheduleinstance/package.json

{
  "name": "cloud-functions-schedule-instance",
  "version": "0.1.0",
  "private": true,
  "license": "Apache-2.0",
  "author": "Google Inc.",
  "repository": {
    "type": "git",
    "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
  },
  "engines": {
    "node": ">=8.0.0"
  },
  "scripts": {
    "test": "mocha test/*.test.js --timeout=20000"
  },
  "devDependencies": {
    "@google-cloud/nodejs-repo-tools": "^3.3.0",
    "mocha": "^6.0.0",
    "proxyquire": "^2.0.0",
    "sinon": "^7.0.0"
  },
  "dependencies": {
    "@google-cloud/compute": "^1.0.0"
  }
}

En Función a ejecutar, ingresa startInstancePubSub.

Haz clic en Crear.

2.2. Crear la función de detención

  1. Debes estar en la página de Cloud Functions en GCP Console.
  2. Haz clic en Crear función.
  3. Configura el Nombre como stopInstancePubSub.
  4. Deja el valor predeterminado en Memoria asignada.
  5. En Activador, selecciona Cloud Pub/Sub.
  6. En Tema, selecciona Create new topic…
  7. Aparecerá un cuadro de diálogo Nuevo tema pub/sub.
    1. En Nombre, ingresa stop-instance-event.
    2. Haz clic en Crear para finalizar el cuadro de diálogo.
  8. En Entorno de ejecución, selecciona Node.js 10.
  9. Sobre el bloque de texto del código, selecciona la pestaña index.js.
  10. Reemplaza el código de inicio con lo siguiente: functions/scheduleinstance/index.js
const Compute = require('@google-cloud/compute');
const compute = new Compute();

exports.stopInstancePubSub = async (event, context, callback) => {
  try {
    const payload = _validatePayload(
      JSON.parse(Buffer.from(event.data, 'base64').toString())
    );
    const options = {filter: `labels.${payload.label}`};
    const [vms] = await compute.getVMs(options);
    await Promise.all(
      vms.map(async instance => {
        if (payload.zone === instance.zone.id) {
          const [operation] = await compute
            .zone(payload.zone)
            .vm(instance.name)
            .stop();

          // Operation pending
          return operation.promise();
        } else {
          return Promise.resolve();
        }
      })
    );
    const message = `Successfully stopped instance(s)`;
    console.log(message);
    callback(null, message);
  } catch (err) {
    console.log(err);
    callback(err);
  }
};

const _validatePayload = payload => {
  if (!payload.zone) {
    throw new Error(`Attribute 'zone' missing from payload`);
  } else if (!payload.label) {
    throw new Error(`Attribute 'label' missing from payload`);
  }
  return payload;
};

11. Sobre el bloque de texto del código, selecciona la pestaña package.json.
12. Reemplaza el código de inicio con lo siguiente: functions/scheduleinstance/package.json

{
  "name": "cloud-functions-schedule-instance",
  "version": "0.1.0",
  "private": true,
  "license": "Apache-2.0",
  "author": "Google Inc.",
  "repository": {
    "type": "git",
    "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
  },
  "engines": {
    "node": ">=8.0.0"
  },
  "scripts": {
    "test": "mocha test/*.test.js --timeout=20000"
  },
  "devDependencies": {
    "@google-cloud/nodejs-repo-tools": "^3.3.0",
    "mocha": "^6.0.0",
    "proxyquire": "^2.0.0",
    "sinon": "^7.0.0"
  },
  "dependencies": {
    "@google-cloud/compute": "^1.0.0"
  }
}

13. En Función a ejecutar, ingresa stopInstancePubSub.
14. Haz clic en Crear.

3. Verifica que tus funciones actúen correctamente

3.1. Detén la instancia

  1. Ve a la página de Cloud Functions en GCP Console.
    Ir a la página de Cloud Functions
  2. Haz clic en la función denominada stopInstancePubSub.
  3. Deberías ver algunas pestañas: GeneralActivadorFuente, y Prueba. Haz clic en la pestaña Prueba.
  4. Para Evento de activación, ingresa lo siguiente:1 {"data":"eyJ6b25lIjoiZXVyb3BlLXdlc3QxLWIiLCJsYWJlbCI6InNjaGVkdWxlOmwtdiJ9"} 
    • Esto es simplemente una string codificada en base64 que contiene la siguiente información: {«zone»:»europe-west1-b»,»label»:»schedule:l-v»}
    • Si deseas codificar tu propia string, puedes usar cualquier herramienta de codificación en base64 en línea.
  5. Haz clic en el botón Probar la función.
  6. Cuando haya terminado de ejecutarse, deberías ver el texto Successfully stopped instance dev-app-01-instance debajo de Resultado. La ejecución puede tardar hasta 60 segundos en completarse.
  7. Ve a la página Instancias de VM en GCP Console.
    Ir a la página Instancias de VM
  8. Verifica que la instancia denominada dev-app-01 tenga un recuadro gris junto a su nombre. Esto indica que se detuvo. Puede tardar hasta 30 segundos en terminar de desactivarse.
    • Si parece que no va a finalizar, prueba hacer clic en Actualizar en la parte superior de la página.

3.2. Inicia la instancia

  1. Ve a la página de Cloud Functions en GCP Console.
    Ir a la página de Cloud Functions
  2. Haz clic en la función denominada startInstancePubSub.
  3. Deberías ver algunas pestañas: GeneralActivadorFuente, y Prueba. Haz clic en la pestaña Prueba.
  4. Para Evento de activación, ingresa lo siguiente:1 {"data":"eyJ6b25lIjoiZXVyb3BlLXdlc3QxLWIiLCJsYWJlbCI6InNjaGVkdWxlOmwtdiJ9"} 
    • Nuevamente, esto es simplemente la string codificada en base64 para {«zone»:»europe-west1-b»,»label»:»schedule:l-v»}
  5. Haz clic en el botón Probar la función.
  6. Cuando haya terminado de ejecutarse, deberías ver el texto Successfully started instance workday-instance debajo de Resultado.
  7. Ve a la página Instancias de VM en GCP Console.
    Ir a la página Instancias de VM
  8. Verifica que la instancia denominada dev-app-01 tenga una marca de verificación verde junto a su nombre. Esto indica que se está ejecutando. Puede tardar hasta 30 segundos en terminar de iniciarse.

4. Configurar los trabajos de Cloud Scheduler para llamar a Cloud Pub/Sub

Nota: La programación se especifica con el formato cron para UNIX. Ejemplos: Cada minuto «* * * * *»; cada 3 horas «0 */3 * * *»; todos los lunes a las 9:00 «0 9 * * 1». Más información

4.1. Crea el trabajo de inicio

  1. Ve a la página de Cloud Scheduler en GCP Console.
    Ir a la página de Cloud Scheduler
  2. Haz clic en Crear trabajo.
  3. Configura el Nombre como startup-l-v-instance.
  4. En Frecuencia, ingresa 0 6 * * 1-5.
  5. En Zona horaria, selecciona el país y la zona horaria que desees. En este ejemplo, usaremos United States y Los Angeles.
  6. En Destino, selecciona Pub/Sub.
  7. En Tema, ingresa start-instance-event.
  8. En Carga útil, ingresa lo siguiente:1 {"zone":"europe-west1-b","label":"schedule:l-v"}
  9. Haz clic en Crear.

4.2. Crea el trabajo de detención.

  1. Debes estar en la página de Cloud Functions en GCP Console.
  2. Haz clic en Crear trabajo.
  3. Configura el Nombre como shutdown-l-v-instance.
  4. En Frecuencia, ingresa 0 21 * * 1-5.
  5. En Zona horaria, selecciona el país y la zona horaria que desees. En este ejemplo, usaremos United States y Los Angeles.
  6. En Destino, selecciona Pub/Sub.
  7. En Tema, ingresa stop-instance-event.
  8. En Carga útil, ingresa lo siguiente:1 {"zone":"europe-west1-b","label":"schedule:l-v"}
  9. Haz clic en Crear.

5. Verifica que los trabajos funcionen

5.1. Detén la instancia

  1. Ve a la página de Cloud Scheduler en GCP Console.
    Ir a la página de Cloud Scheduler
  2. En el trabajo denominado shutdown-l-v-instance, haz clic en el botón Ejecutar ahora en el extremo derecho de la página.
  3. Ve a la página Instancias de VM en GCP Console.
    Ir a la página Instancias de VM
  4. Verifica que la instancia denominada app-dev-01-instance tenga un recuadro gris junto a su nombre. Esto indica que se detuvo. Puede tomar hasta 30 segundos para que termine de desactivarse.

5.2. Inicia la instancia

  1. Ve a la página de Cloud Scheduler en GCP Console.
    Ir a la página de Cloud Scheduler
  2. En el trabajo denominado startup-l-v-instance, haz clic en el botón Ejecutar ahora en el extremo derecho de la página.
  3. Ve a la página Instancias de VM en GCP Console.
    Ir a la página Instancias de VM
  4. Verifica que la instancia denominada dev-app-01-instance tenga una marca de verificación verde junto a su nombre. Esto indica que se está ejecutando. Puede tardar hasta 30 segundos para que termine de iniciarse.

Problema resuelto!

Programar encendido/apagado de VM en GCE
Scroll hacia arriba