默认情况下创建的 ECS 实例只有一个40G 的高效云盘系统盘,通过任何形式(控制台、ECS SDK 等) 方式创建的实例,如果需要使用数据盘,必须先进行额外的格式化数据盘工作。
如果需要批量创建大量的有特定格式化需求数据盘的 ECS 实例,那么单独为每一台实例格式化数据盘肯定是一件浪费运维资源的工作。所以,这里介绍一种比较简单的 ECS 实例数据盘自动挂载和格式化的方式,也许有更好的方法,请各位大神拍砖。
背景
阿里云 ECS 实例对数据盘的使用,由于涉及到用户自己的业务逻辑,对盘的数目、分区方式、文件系统要求等都不尽相同,所以 ECS 服务提供了自主的方式,将数据盘的格式化工作全部交托给用户自行处理,这样就导致了用户需要进行一步的运维工作,才能对数据盘进行正常的使用。如果用户需要创建批量的实例,那么对这些实例分别进行数据盘的初始化操作必然会成为运维中的一项额外的工作。
以 Linux 系统为例,主要的步骤如下:
如果是新购买的数据盘,那么需要先挂载数据盘。如果是和实例一同购买的数据盘,那么可以直接进行数据盘的格式化即可。
我们知道,ECS 提供了自定义镜像的功能,用户可以从现有的实例构建镜像,此后就可以使用该镜像作为新的实例创建的模板,"克隆"业务所需的实例了。那么数据盘的格式化信息是否也能被"录制"到镜像中呢?当然可以。
如何制作数据盘格式化了的镜像
这里以 Linux 系统(实例基础镜像为 linux_17_01_64_20G_cloudinit_20171222.vhd),挂载 SSD 云盘,创建一个单分区,并挂载文件系统为例。使用 ECS 的 SDK 进行相关的操作。
首先,通过 CreateInstance 创建一个 ECS 实例,注意,创建参数中 DataDisk 参数的内容:
type DataDiskType struct {
Size int
Category DiskCategory //Enum cloud, ephemeral, ephemeral_ssd
SnapshotId string
DiskName string
Description string
Device string
DeleteWithInstance bool
}
- Size: 数据盘大小,单位 GB
- Category: 数据盘的类型,如 ephemeral_ssd, cloud_efficiency 和 cloud_ssd 等,分别对应本地 SSD , 高效云盘,高效 SSD 等。
- Device: 数据盘挂载点的设备名称,如果不填,默认由系统分配,I/O 优化实例的数据盘设备名从
/dev/vdb 递增排列,包括 /dev/vdb− /dev/vdz。如果数据盘设备名为 dev/xvd( 是 a−z 的任意一个字母),表示您使用的是非 I/O 优化实例。
在创建时,DataDisk 参数中只有一块 DataDiskType 类型,我们选择使用默认的 Device 。此时创建出来的实例,带有一块数据盘,但是未格式化。如果登录机器,通过 fdisk -l 可以看到对应的数据盘的信息以及挂载点。但是文件系统中是没有任何该数据盘的信息的。
接下来就是自定义机器的业务逻辑,比如,需要如何配置系统、安装什么软件等等,可以通过 SSH Client 相关工具对机器进行自动化操作。比如数据盘格式化的操作,可以生成这样的 shell 文件,通过 SSH Client 拷贝到实例机器上,然后执行就可以了。
set -e
setup_disk() {
tee ./command <<-EOF
n
p
1
w
p
EOF
fdisk -u /dev/vdb < ./command
mkfs.ext4 /dev/vdb1
echo /dev/vdb1 /your_dir ext4 defaults 0 0 >> /etc/fstab
mkdir -p /your_dir
mount /dev/vdb1 /your_dir
}
setup_disk
执行完成之后,你可以看到系统信息已经发生变化:
当然,为了验证磁盘格式化信息正确持久化,你可以对这个实例重启,然后再进行相关的 check,check 逻辑可以简单如下:
set -e
df -h|grep '/your_dir'|grep '/dev/vdb1'
fdisk -l|tail -1|grep '/dev/vdb1'
最后,通过 CreateImage 构建镜像即可。
如何通过镜像复制实例
通过上面的步骤,你应该已经制作了一个带有数据盘格式化信息的镜像了,那么这时你需要通过这个镜像来创建你需要的实例。创建实例的过程和一开始通过 CreateInstance 相同,但是有一些坑需要注意:
- CreateInstance 的参数中 DataDisk 必须填写,并且 DataDisk 中的一块数据盘的 Device 信息必须和镜像中的数据盘设备名完全相同。如果不填或者填错,那么系统会当做一块新的数据盘进行处理,此时创建出来的实例会有两块数据盘。分别挂载 /dev/xvdb 和 /dev/xvdc。而 /dev/xvdb 是镜像自带的已经格式化的数据盘,/dev/xvdc 才是你在这次 CreateInstance 指定的数据盘,而且只挂载没有格式化化。下图展示了我的一次失败的操作结果:
- 镜像中仅仅保存了数据盘格式化的信息,但是并未保存磁盘类型信息,比如在创建进行的时候使用的实例挂载的数据盘是 cloud_ssd,但是如果不指定 DataDisk 中数据盘的 Category ,默认使用的是高效云盘。因为数据盘类型属于业务属性,镜像本身并没有这个属性。
- Device 的值并不是你在机器上通过 fdisk -l 看到的,可以需要通过 DescribeImages 查看。我们通过 fdisk -l 可以看到上面的数据盘都是在 /dev/vdb 这个设备名上,但是 DescribeImages 的返回结果却是:
这个值和虚拟化的类型相关,所以,请以 DescribeImages 的结果为准。
总结
一个简单的数据盘格式化模板构建方式,小总结一下~~谢谢拍砖。