介绍
DigitalOcean的自定义图像功能允许您将自定义Linux和类Unix虚拟磁盘映像从内部部署环境或其他云平台引入DigitalOcean,并使用它们启动DigitalOcean Droplet。
如自定义图像文档中所述,自定义图像上载工具本身支持以下图像类型:
虽然ISO格式图像不受官方支持,但您可以按照如何从Ubuntu ISO格式图像创建DigitalOcean Droplet,了解如何使用VirtualBox创建和上载兼容图像。
如果您还没有要上载到DigitalOcean的兼容映像 ,则可以创建和压缩类Unix或Linux系统的磁盘映像,前提是它已安装必备软件和驱动程序 。
我们首先要确保我们的图像符合自定义图像要求。 为此,我们将配置系统并安装一些必备软件。 然后,我们将使用dd
命令行实用程序创建映像,并使用gzip
对其进行压缩。 接下来,我们将此压缩图像文件上传到DigitalOcean Spaces,我们可以将其作为自定义图像导入。 最后,我们将使用上传的图像启动Droplet。
先决条件
如果可能,您应该使用DigitalOcean提供的图像之一作为基础,或者使用官方发行版提供的云图像,如Ubuntu Cloud 。 然后,您可以使用Packer和VirtualBox等工具在此基本映像之上安装软件和应用程序以烘焙新映像。 许多云提供商和虚拟化环境还提供了将虚拟磁盘导出为上面列出的兼容格式之一的工具,因此,如果可能,您应该使用这些来简化导入过程。 如果您需要手动创建系统的磁盘映像,可以按照本指南中的说明进行操作。 请注意,这些说明仅使用Ubuntu 18.04系统进行了测试,步骤可能因服务器的操作系统和配置而异。
在开始本教程之前,您应该可以使用以下内容:
类似于Linux或类Unix的系统,可满足自定义映像产品文档中列出的所有要求。 例如,您的启动盘必须具有:
- 最大尺寸为100GB
- 带有
grub
引导加载程序的MBR或GPT分区表 - 安装了VirtIO驱动程序
您正在成像的系统上具有管理权限的非root用户。 要创建新用户并在Ubuntu 18.04上授予其管理权限,请按照Ubuntu 18.04的初始服务器设置进行操作 。 要了解如何在Debian 9上执行此操作,请参阅Debian 9的初始服务器设置 。
用于存储本指南中创建的磁盘映像的附加存储设备,最好与正在复制的磁盘一样大。 这可以是附加的块存储卷,外部USB驱动器,附加物理磁盘等。
DigitalOcean Space和配置为与您的Space一起使用的
s3cmd
文件传输实用程序。 要了解如何创建Space,请参阅Spaces Quickstart 。 要了解如何设置s3cmd
以用于Space,请参阅s3cmd 2.x设置指南 。
第1步 - 安装Cloud-Init并启用SSH
首先,我们将安装cloud-Init初始化包。 Cloud-init是一组在引导时运行的脚本,用于配置某些云实例属性,如默认语言环境,主机名,SSH密钥和网络设备。
安装cloud-init的步骤将根据您安装的操作系统而有所不同。 通常, cloud-init
软件包应该可以在您的操作系统的软件包管理器中使用,因此如果您不使用基于Debian的分发版,则应该在以下步骤中使用特定于分发的软件包管理器命令替换apt
。
安装cloud-init
在本指南中,我们将使用Ubuntu 18.04服务器,因此将使用apt
来下载和安装cloud-init
软件包。 请注意, cloud-init
可能已经安装在您的系统上(某些Linux发行版默认安装了cloud-init
)。 要检查,请登录到您的服务器并运行以下命令:
cloud-init
如果您看到以下输出,则已在服务器上安装了cloud-init
,您可以继续配置它以与DigitalOcean一起使用:
Outputusage: /usr/bin/cloud-init [-h] [--version] [--file FILES] [--debug] [--force]
{init,modules,single,query,dhclient-hook,features,analyze,devel,collect-logs,clean,status}
...
/usr/bin/cloud-init: error: the following arguments are required: subcommand
如果您看到以下内容,则需要安装cloud-init
:
Outputcloud-init: command not found
要安装cloud-init
,请更新软件包索引,然后使用apt
安装软件包:
sudo apt update
sudo apt install cloud-init
现在我们已经安装了cloud-init
,我们将其配置为与DigitalOcean一起使用,确保它使用ConfigDrive
数据源。 Cloud-init数据源决定了cloud-init
将如何搜索和更新实例配置和元数据。 DigitalOcean Droplets使用ConfigDrive
数据源,因此我们将检查它是否在ConfigDrive
cloud-init
boots引导时cloud-init
搜索的数据源列表中排在第一位。
重新配置cloud-init
默认情况下,在Ubuntu 18.04上, cloud-init
将自己配置为首先使用NoCloud
数据源。 这将在DigitalOcean上运行映像时出现问题,因此我们需要重新配置cloud-init
以使用ConfigDrive
数据源,并确保在DigitalOcean上启动映像时重新运行cloud-init
。
从命令行,导航到/etc/cloud/cloud.cfg.d
目录:
cd /etc/cloud/cloud.cfg.d
使用ls
命令列出目录中存在的cloud-init
配置文件:
ls
Output05_logging.cfg 50-curtin-networking.cfg 90_dpkg.cfg curtin-preserve-sources.cfg README
根据您的安装,可能不存在其中一些文件。 如果存在,请删除50-curtin-networking.cfg
文件,该文件为您的Ubuntu服务器配置网络接口。 在DigitalOcean上启动映像时, cloud-init
将自动运行并重新配置这些接口,因此不需要此文件。 如果未删除此文件,则从此Ubuntu映像创建的DigitalOcean Droplet将使其接口配置错误,并且无法从Internet访问:
sudo rm 50-curtin-networking.cfg
接下来,我们将运行dpkg-reconfigure cloud-init
来删除NoCloud
数据源,确保cloud-init
搜索并找到DigitalOcean上使用的ConfigDrive
数据源:
sudo dpkg-reconfigure cloud-init
您应该看到以下图形菜单:
最初突出显示NoCloud
数据源。 按SPACE
取消选择它,然后按ENTER
。
最后,导航到/etc/netplan
:
cd /etc/netplan
删除50-cloud-init.yaml
文件,该文件是我们之前删除的cloud-init
网络文件生成的:
sudo rm 50-cloud-init.yaml
最后一步是确保我们从初始的cloud-init
运行中清理配置,以便在DigitalOcean上启动映像时重新运行。
为此,请运行cloud-init clean
:
sudo cloud-init clean
此时,您已安装并配置了cloud-init
,以便与DigitalOcean一起使用。 您现在可以继续启用对Droplet的SSH访问。
启用SSH访问
一旦安装并配置了cloud-init
,下一步就是确保您的计算机上可以使用非root管理员用户和密码,如先决条件中所述。 此步骤对于诊断上载图像和启动Droplet后可能出现的任何错误至关重要。 如果预先存在的网络配置或错误的cloud-init
配置使您的Droplet无法通过网络访问,则可以将此用户与DigitalOcean Droplet控制台结合使用,以访问您的系统并诊断可能出现的任何问题。
设置非root管理用户后,最后一步是确保已安装并运行SSH服务器。 SSH通常预装在许多流行的Linux发行版上。 检查服务是否正在运行的过程将根据服务器的操作系统而有所不同。如果您不确定如何执行此操作,请参阅操作系统有关管理服务的文档。 在Ubuntu上,您可以使用以下命令验证SSH是否已启动并正在运行:
sudo service ssh status
您应该看到以下输出:
Output● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2018-10-22 19:59:38 UTC; 8 days 1h ago
Docs: man:sshd(8)
man:sshd_config(5)
Process: 1092 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 1115 (sshd)
Tasks: 1 (limit: 4915)
Memory: 9.7M
CGroup: /system.slice/ssh.service
└─1115 /usr/sbin/sshd -D
如果SSH未启动并运行,您可以使用apt
(在基于Debian的发行版上)安装它:
sudo apt install openssh-server
默认情况下,SSH服务器将在启动时启动,除非另有配置。 在云中运行系统时,这是可取的,因为DigitalOcean可以自动复制您的公钥,并在创建后立即授予您对Droplet的SSH访问权限。
一旦您创建了非root管理用户,启用了SSH并安装了cloud-init,您就可以继续创建启动盘的映像了。
第2步 - 创建磁盘映像
在此步骤中,我们将使用dd
命令行实用程序创建RAW格式磁盘映像,并使用gzip
对其进行压缩。 然后我们将使用s3cmd
将图像上传到DigitalOcean Spaces。
首先,登录到您的服务器,然后使用lsblk
检查系统的块设备排列:
lsblk
您应该看到如下内容:
OutputNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 12.7M 1 loop /snap/amazon-ssm-agent/495
loop1 7:1 0 87.9M 1 loop /snap/core/5328
vda 252:0 0 25G 0 disk
└─vda1 252:1 0 25G 0 part /
vdb 252:16 0 420K 1 disk
在这种情况下,我们注意到我们的主启动盘是/dev/vda
,一个25GB的磁盘,而安装在/
的主分区是/dev/vda1
。 在大多数情况下,包含安装在/
的分区的磁盘将是要映像的源磁盘。 我们将使用dd
创建/dev/vda
的映像。
此时,您应该决定要存储磁盘映像的位置。 一种选择是连接另一个块存储设备,最好与要进行映像的磁盘一样大。 然后,您可以将图像保存到此附加的临时磁盘,并将其上载到DigitalOcean Spaces。
如果您具有对服务器的物理访问权限,则可以向计算机添加其他驱动器或连接其他存储设备,如外部USB磁盘。
我们将在本指南中演示的另一个选项是将图像通过SSH复制到本地计算机,您可以从中将其上载到Spaces。
无论您选择遵循哪种方法,请确保保存压缩图像的存储设备有足够的可用空间。 如果您要成像的磁盘大部分为空,则可以预期压缩的映像文件会比原始磁盘小得多。
警告:在运行以下dd
命令之前,请确保已停止所有关键应用程序,并且系统尽可能安静。 复制主动使用的磁盘可能会导致某些损坏的文件,因此请务必暂停所有数据密集型操作并关闭尽可能多的正在运行的应用程序。
选项1:在本地创建图像
我们要执行的dd
命令的语法如下所示:
dd if=/dev/vda bs=4M conv=sparse | pv -s 25G | gzip > /mnt/tmp_disk/ubuntu.gz
在这种情况下,我们选择/dev/vda
作为要映像的输入磁盘,并将输入/输出块大小设置为4MB(默认为512字节)。 这通常可以加快速度。 此外,我们使用conv=sparse
标志通过跳过空白空间来最小化输出文件大小。 要了解有关dd
参数的更多信息,请参阅dd
联机帮助页 。
然后,我们将输出通过管道传输到pv
管道查看器实用程序,以便我们可以直观地跟踪传输进度(此管道是可选的,需要使用包管理器安装pv
)。 如果您知道初始磁盘的大小(在这种情况下它是25G),您可以将-s 25G
添加到pv
管道以获得传输完成时的ETA。
然后我们将它全部传输到gzip
,并将其保存在我们附加到服务器的临时块存储卷上的名为ubuntu.gz
的文件中。 将/mnt/tmp_disk
替换为您已连接到服务器的外部存储设备的路径。
选项2:通过SSH创建映像
如果您的本地计算机上有足够的可用磁盘空间,您也可以通过SSH执行复制,而不是为远程计算机配置额外的存储空间。 请注意,根据您可用的带宽,这可能会很慢,并且您可能会因网络上的数据传输而产生额外的成本。
要通过SSH复制和压缩磁盘,请在本地计算机上执行以下命令:
ssh remote_user@your_server_ip "sudo dd if=/dev/vda bs=4M conv=sparse | gzip -1 -" | dd of=ubuntu.gz
在这种情况下,我们正在SSH连接到我们的远程服务器,在那里执行dd
命令,并将输出传递给gzip
。 然后我们通过网络传输gzip
输出并将其保存为本地ubuntu.gz
。 在运行此命令之前,请确保在本地计算机上可以使用dd
实用程序:
which dd
Output/bin/dd
使用上述任一方法创建压缩的图像文件。 这可能需要几个小时,具体取决于您要成像的磁盘大小以及您用于创建映像的方法。
创建压缩图像文件后,您可以继续使用s3cmd
将其上传到DigitalOcean Spaces。
第3步 - 将图像上传到空格和自定义图像
如先决条件中所述,您应该安装并配置s3cmd
,以便与包含压缩映像的计算机上的DigitalOcean Space一起使用。
找到压缩的图像文件,然后使用s3cmd
将其上传到Space:
注意:您应该使用Space的名称而不是其URL替换your_space_name
。 例如,如果您的Space的URL是https:// example-space-name .nyc3.digitaloceanspaces.com
,那么您的Space的名称是example-space-name
。
s3cmd put /path_to_image/ubuntu.gz s3://your_space_name
上传完成后,使用DigitalOcean 控制面板导航到您的Space,并在文件列表中找到该图像。 我们将暂时使图像可公开访问,以便自定义图像可以访问它并保存副本。
在图片列表的右侧,单击“ 更多”下拉菜单,然后单击“ 管理权限” :
然后,单击“ 公共”旁边的单选按钮,然后单击“ 更新”以使图像可公开访问。
警告:在此过程中,任何拥有Spaces路径的人都可以暂时公开您的图片。 如果您想避免暂时公开您的图片,可以使用DigitalOcean API创建自定义图像。 图像成功传输到自定义图像后,请务必使用上述步骤将图像设置为“ 专用” 。
将鼠标悬停在“控制面板”中的图像名称上,然后在弹出的窗口中单击“ 复制URL” ,以获取图像的空格URL。
现在,导航到左侧导航栏中的图像 ,然后导航到自定义图像 。
在此处,使用此URL上传图像,如自定义图像产品文档中所述 。
然后,您可以从此图像创建Droplet 。 请注意,您需要在创建时向Droplet添加SSH密钥。 要了解如何执行此操作,请参阅如何将SSH密钥添加到Droplet 。
一旦你的Droplet启动,如果你可以通过SSH连接它,你就已经成功地将自定义图像作为DigitalOcean Droplet启动了。
调试
如果您尝试通过SSH连接Droplet并且无法连接,请确保您的映像符合列出的要求,并且已安装并正确配置了cloud-init
和SSH。 如果您仍然无法访问Droplet,则可以尝试使用您之前创建的DigitalOcean Droplet控制台和非root用户来浏览系统并调试网络, cloud-init
和SSH配置。 调试映像的另一种方法是使用Virtualbox等虚拟化工具在虚拟机内启动磁盘映像,并在VM中调试系统配置。
结论
在本指南中,您学习了如何使用dd
命令行实用程序创建Ubuntu 18.04系统的磁盘映像,并将其作为自定义映像上载到DigitalOcean,您可以从中启动Droplet。
本指南中的步骤可能因操作系统,现有硬件和内核配置而异,但通常,从流行的Linux发行版创建的映像应使用此方法。 请务必仔细按照安装和配置cloud-init
的步骤进行操作,并确保您的系统满足上述[先决条件](todo:link)部分中列出的所有要求。
要了解有关自定义图像的更多信息,请参阅官方自定义图像产品文档 。