自动执行 GCP 永久性磁盘初始化

Posted

技术标签:

【中文标题】自动执行 GCP 永久性磁盘初始化【英文标题】:Automate GCP persistent disk initialization 【发布时间】:2019-04-09 07:09:30 【问题描述】:

是否有任何脚本可以自动格式化永久性磁盘并将其附加到 Google Cloud VM 实例,而不是执行formatting & mounting steps?

永久性磁盘是使用 Terraform 创建的,它还会创建一个 VM 并使用 attached_disk 命令将磁盘附加到它。

我希望在 VM 实例启动时运行一个简单的脚本:

检查附加的磁盘是否已格式化,如果需要,请使用 ext4 进行格式化 检查磁盘是否挂载,如果没有挂载 否则什么也不做

【问题讨论】:

我不确定您所说的instead of doing formatting & mounting steps 是什么意思,因为这是您需要执行的过程才能使用磁盘。你是说你想要一些只为你做的东西,而不必编写脚本(或者基本上从链接的文档中复制它)? @ydaetskcoR 该过程可以是手动的(我复制/粘贴命令),也可以是自动的(terraform 格式化磁盘,启动脚本自动安装它)。我更喜欢后者,并希望有人已经这样做了,而不是每个人都重新发明***:)在文档中,编辑 /etc/fstab 说明不正确 - 它会在实例重启时重置。 您链接到的文档还提到了文件可能被重置的原因:“在 Container-Optimized OS 上,对 /etc/fstab 的修改不会在重新启动后持续存在。为确保在引导过程中检查并挂载设备,请从 cloud-config 的 bootcmd 部分在永久磁盘上运行 fsck 和挂载操作。请参阅 Container-Optimized OS 文档中的“安装和格式化磁盘”。” 不幸的是,阳光下的每个人都使用不同的操作系统配置工具。对于基本的 shell 脚本,您应该从文档中复制粘贴,但要将其与 Puppet / Chef / Ansible / Salt / 中的其他配置脚本集成,还需要做更多的工作。 【参考方案1】:

您是否考虑过在实例上使用startup script(我想您也可以使用 Terraform 添加启动脚本)?您可以使用if 循环来发现磁盘是否已格式化,如果没有,您可以尝试在您链接的文档中运行格式化/安装命令(我知道您曾建议您不想按照文档,但可以将这些集成到启动脚本中以实现所需的结果)。

如果磁盘未格式化,则运行以下输出和空字符串:

 sudo blkid /dev/sdb

因此,您可以在启动脚本中使用它来检测磁盘是否已格式化,然后在未格式化的情况下执行格式化/挂载。例如,您可以使用这样的东西(注意***如果磁盘已格式化但未安装,这可能很危险,如果您的用例可能涉及可能已经格式化的现有磁盘,则不应使用):

#!/bin/bash


if sudo blkid /dev/sdb;then 
        exit
else 
        sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb; \
        sudo mkdir -p /mnt/disks/newdisk
        sudo mount -o discard,defaults /dev/sdb /mnt/disks/newdisk
fi

【讨论】:

谢谢! GCP 是否保证/dev/sdb 始终是第二个附加磁盘,sda == 引导?此外,您建议的格式化很危险 - 磁盘可能已格式化但未安装。 就您关于 /dev/sdb 的问题而言,不,它不能保证这一点,尽管如果这是您附加的第一个磁盘,它很可能是 /dev/sdb。关于您关于磁盘被格式化但未安装的风险的观点,我在我的回复中添加了一条注释以警告风险。我建议将您在脚本方面所做的尝试添加到您的原始问题中(如果您现在尝试自己编写脚本),以便人们可以解决您的尝试失败的原因。 @yurik 您可以为磁盘分配一个 ID。 google 然后提供一个符号链接 /dev/disk/by-id/google- 我提供了一个脚本,它通过分配磁盘名称然后使用它来识别 /dev/sd* - ***.com/a/59646741/3074229 上的正确设备【参考方案2】:

标记的答案对我不起作用,因为sudo blkid /dev/sdb 部分总是返回一个值(因此为真)并且脚本将退出。

我更新了脚本以检查 fstab 中的条目,并为脚本添加了安全选项。

#!/bin/bash
set -uxo pipefail

MNT_DIR=/mnt/disks/persistent_storage
DISK_NAME=my-disk

# Check if entry exists in fstab
grep -q "$MNT_DIR" /etc/fstab
if [[ $? -eq 0 ]]; then # Entry exists
    exit
else
    set -e # The grep above returns non-zero for no matches & we don't want to exit then.

    # Find persistent disk's drive value, prefixed by `google-`
    DEVICE_NAME="/dev/$(basename $(readlink /dev/disk/by-id/google-$DISK_NAME))"

    sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard $DEVICE_NAME
    sudo mkdir -p $MOUNT_DIR
    sudo mount -o discard,defaults $DEVICE_NAME $MOUNT_DIR

    # Add fstab entry
    echo UUID=$(sudo blkid -s UUID -o value $DEVICE_NAME) $MNT_DIR ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab
fi

如果你想下载它,这里是要点 - https://gist.github.com/raj-saxena/3dcaa5c0ba0be88ed91ef3fb50d3ce85

【讨论】:

这听起来很危险,我们应该检查是否已经有分区以及是否有文件系统,否则你可能会重做文件系统。 @FreshMike 是的,你是对的。我已经更新了脚本,而不是文件夹,我正在检查 fstab 中的条目。你会怎么做?

以上是关于自动执行 GCP 永久性磁盘初始化的主要内容,如果未能解决你的问题,请参考以下文章

sh GCP实例持久性磁盘

在 GCP 上调整永久磁盘大小时,如何触发文件系统调整大小?

Google Cloud Platform抢占实例:磁盘发生了什么?

.db-journal如何执行

定期自动执行 Colab 笔记本

启动脚本未在启用自动缩放的 GCP Compute Engine Windows 服务器上运行