在 Linux 虚拟机上使用启动脚本

本文档介绍了如何在 Google Distributed Cloud (GDC) 网闸隔离配置中使用启动脚本来启动虚拟机 (VM) 实例及其关联的程序。

启动脚本是一种自动化工具,用于在虚拟机启动过程中执行任务。使用启动脚本可以自动执行新实例或现有实例上的虚拟机配置和部署任务,从而节省时间并减少手动配置工作量。

本文档适用于平台管理员或应用运维人员组中的开发者,他们希望在 Distributed Cloud 环境中使用虚拟机的启动脚本。如需了解详情,请参阅 GDC 网闸隔离配置文档的受众群体

准备工作

如需使用 gdcloud 命令行界面 (CLI) 命令,请确保您已下载、安装、 并配置 gdcloud CLI。 Distributed Cloud 的所有命令都使用 gdcloudkubectl CLI,并且需要操作系统 (OS) 环境。

获取 kubeconfig 文件路径

如需针对 Management API 服务器运行命令,请确保您拥有以下资源:

  1. 登录并生成 Management API 服务器的 kubeconfig 文件(如果您还没有)。

  2. 使用 Management API 服务器的 kubeconfig 文件的路径替换这些说明中的 MANAGEMENT_API_SERVER

请求 IAM 角色

如需使用虚拟机的启动脚本,请与您的项目 IAM 管理员联系,以请求对您的项目使用以下角色:

  • 虚拟机项目管理员 (project-vm-admin):在项目命名空间中创建、修改、列出和删除虚拟机。

  • Secret 管理员 (secret-admin):在项目命名空间中获取、列出、创建、更新、删除、修补和监控 Kubernetes Secret。使用此角色指定启动脚本 Secret。您无需此角色即可指定纯文本启动脚本。

所有虚拟机角色都必须绑定到虚拟机所在项目的命名空间。 按照这些步骤验证 您的访问权限。

传递启动脚本

您可以使用 bash 或非 bash 脚本作为启动脚本。为此,请在脚本开头添加 #!/bin/…,以指示脚本解释器。 例如,如需使用 Python 3 启动脚本,请在脚本开头添加 #! /usr/bin/python3

Google Distributed Cloud (GDC) 网闸隔离配置会按照启动脚本在 startupScripts 数组中的显示顺序运行这些脚本。

下表显示了根据脚本大小使用的脚本格式:

脚本大小 脚本格式
不超过 2048 字节的脚本 明文
超过 2048 字节的脚本 Kubernetes Secret

定义启动脚本

如需使用启动脚本,您必须将 startupScripts 字段添加到虚拟机的 spec 字段。在此字段中,您可以将多个启动脚本指定为纯文本或 Kubernetes Secret。

以下示例将启动脚本指定为明文和 Kubernetes Secret:

apiVersion: virtualmachine.gdc.goog/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  # …
  startupScripts:
  - name: hello-world
    script: |
      #!/bin/bash
      echo hello
  - name: add-user
    scriptSecretRef:
      name: add-user
---

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: add-user
data:
  script:
    IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==

请注意以下几点:

  • 启动脚本会在每次启动时运行。
  • 启动脚本具有默认根权限。
  • 在 Kubernetes Secret 中,虚拟机 spec 中的 scriptSecretRef 的名称必须与 metadata.name 字段匹配。
  • 在 Kubernetes Secret 中,通过向 data 字段添加键 script 来指定启动脚本内容。

使用启动脚本创建新虚拟机

无论您使用什么作为映像来创建虚拟机,这些说明都适用。请完成以下操作:

  1. 如需将启动脚本创建为 Kubernetes Secret,请运行:

    cat <<EOF >>FILE_NAME
    STARTUP_SCRIPT_CONTENT
    EOF
    
    kubectl --kubeconfig MANAGEMENT_API_SERVER \
      -n PROJECT \
      create secret generic SECRET_NAME \
      --from-file=script=FILE_NAME
    
    rm FILE_NAME
    
  2. 请参阅 创建虚拟机页面上介绍的创建虚拟机的步骤。 在 第一步 中,在运行命令以 创建虚拟机之前,将启动脚本添加到 spec 字段。

    此示例定义了一个同时包含明文和 Kubernetes Secret 的启动脚本:

    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
      namespace: PROJECT
    spec:
      # …
      startupScripts:
      - name: CLEAR_TEXT_SCRIPT_NAME
        script: |
          #!/bin/bash
          CLEAR_TEXT_SCRIPT
      - name: SECRET_SCRIPT_NAME
        scriptSecretRef:
          name: SECRET_NAME
    

    这些变量的定义如下:

    变量定义
    MANAGEMENT_API_SERVER Management API 服务器 kubeconfig 文件。
    PROJECT 您要在其中创建虚拟机的 Distributed Cloud 项目。
    VM_NAME 虚拟机的名称。
    FILE_NAME 用于存储启动脚本的文件的名称。
    STARTUP_SCRIPT_CONTENT 作为启动脚本的一部分运行的命令
    CLEAR_TEXT_SCRIPT_NAME 明文启动脚本的名称。
    CLEAR_TEXT_SCRIPT 您定义的明文脚本。
    SECRET_NAME Kubernetes Secret 的名称。
    SECRET_SCRIPT_NAME 作为 Kubernetes Secret 的启动脚本的名称。
  3. 继续执行以下步骤以创建虚拟机。

    以下示例展示了如何使用启动脚本创建虚拟机,该脚本使用 Kubernetes Secret 和明文添加新用户。

    kubectl --kubeconfig MANAGEMENT_API_SERVER \
      -n PROJECT \
      apply -f - <<EOF
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachineDisk
    metadata:
      name: VM_BOOT_DISK_NAME
    spec:
      source:
        image:
          name: BOOT_DISK_IMAGE_NAME
          namespace: vm-system
      size: BOOT_DISK_SIZE
    ---
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
      name: add-user
    data:
      script:
        IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==
    ---
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      compute:
        virtualMachineType: MACHINE_TYPE
      disks:
      - virtualMachineDiskRef:
          name: VM_BOOT_DISK_NAME
        boot: true
        autoDelete: BOOT_DISK_AUTO_DELETE
      startupScripts:
      - name: add-user
        scriptSecretRef:
          name: add-user
      - name: add-to-sudoers
        script: |
          #!/bin/bash
          usermod -aG sudo user
    EOF
    

    在此示例中,变量的定义如下。

    变量定义
    MANAGEMENT_API_SERVER Management API 服务器 kubeconfig 文件。
    PROJECT 您要在其中创建虚拟机的 Distributed Cloud 项目。
    VM_NAME 新虚拟机的名称。
    VM_BOOT_DISK_NAME 新虚拟机启动磁盘的名称。
    BOOT_DISK_IMAGE_NAME 要用于新虚拟机启动磁盘的映像的名称。
    BOOT_DISK_SIZE 启动磁盘的大小,例如 20G
    此值必须始终大于或等于 启动磁盘映像的 minimumDiskSize
    BOOT_DISK_AUTO_DELETE `true` 或 `false`,表示在删除虚拟机实例时是否自动删除启动磁盘。
    MACHINE_TYPE 新虚拟机的预定义机器类型。如需选择可用的机器类型,请运行以下命令:
    kubectl --kubeconfig MANAGEMENT_API_SERVER get virtualmachinetype.virtualmachine.gdc.goog --namespace vm-system

使用启动脚本更新现有虚拟机

您还可以使用启动脚本更新现有虚拟机。在执行更新之前,必须关闭虚拟机。

按照这些步骤更新虚拟机属性 并使用您要运行的启动脚本更新 spec 字段。

查看启动脚本的输出

  1. 按照这些步骤连接到虚拟机
  2. 在 guest 虚拟机内运行以下命令,以获取您运行的启动脚本的日志:

    sudo journalctl -u cloud-final
    

    启动脚本日志以以下内容开头:

    Started to run the command: /var/lib/google/startup-scripts/<script-name> ...