如何创建Linux环境的映像并在DigitalOcean上启动它
介绍
DigitalOcean 的 Custom Images 功能允许您将自定义 Linux 和类 Unix 虚拟磁盘映像从本地环境或其他云平台带到 DigitalOcean,并使用它们来启动 DigitalOcean Droplets。
如 自定义图像文档 中所述,自定义图像上传工具原生支持以下图像类型:
虽然官方不支持 ISO 格式的镜像,但是你可以通过 How to Create a DigitalOcean Droplet from an Ubuntu ISO Format Image 学习如何使用 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 上创建新用户并授予其管理权限,请按照我们的 Initial Server Setup with Ubuntu 18.04。 要了解如何在 Debian 9 上执行此操作,请参阅 使用 Debian 9 进行初始服务器设置。
- 用于存储本指南中创建的磁盘映像的附加存储设备,最好与要复制的磁盘一样大。 这可以是附加的块存储卷、外部 USB 驱动器、附加物理磁盘等。
- 配置为与您的 Space 一起使用的 DigitalOcean Space 和
s3cmd
文件传输实用程序。 要了解如何创建空间,请参阅空间 快速入门 。 要了解如何设置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
数据源,因此我们将检查它是否在 Droplet 启动时 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 Console 结合使用来访问您的系统并诊断可能出现的任何问题已经浮出水面。
设置非 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 复制和压缩磁盘,请在 local 机器上执行以下命令:
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
将其上传到您的空间:
注意: 您应该将 your_space_name
替换为您的空间名称,而不是其 URL。 例如,如果您的 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 控制面板 导航到您的空间,然后在文件列表中找到图像。 我们将暂时使图像可公开访问,以便自定义图像可以访问它并保存副本。
在图片列表的右侧,点击More下拉菜单,然后点击进入Manage Permissions:
然后,单击 Public 旁边的单选按钮并点击 Update 以使图像可公开访问。
警告: 在此过程中,任何拥有其空间路径的人都可以暂时公开访问您的图像。 如果您想避免暂时公开您的图像,您可以使用 DigitalOcean API 创建您的自定义图像。 在您的图像成功传输到自定义图像后,请务必使用上述步骤将您的图像设置为 Private。
通过将鼠标悬停在控制面板中的图像名称上来获取图像的空间 URL,然后在弹出的窗口中点击 复制 URL 。
现在,导航到左侧导航栏中的 Images,然后导航到 Custom Images。
从这里,使用自定义图像 产品文档 中详细说明的 URL 上传您的图像。
然后,您可以 从此图像 创建一个 Droplet。 请注意,您需要在创建 Droplet 时添加 SSH 密钥。 要了解如何执行此操作,请参阅 如何将 SSH 密钥添加到 Droplets。
一旦你的 Droplet 启动,如果你可以通过 SSH 连接到它,你就成功地将你的自定义图像作为 DigitalOcean Droplet 启动了。
调试
如果您尝试通过 SSH 连接到您的 Droplet 并且无法连接,请确保您的映像满足列出的要求并且已安装并正确配置了 cloud-init
和 SSH。 如果您仍然无法访问 Droplet,您可以尝试使用 DigitalOcean Droplet Console 和您之前创建的非 root 用户来探索系统并调试您的网络,cloud-init
和SSH 配置。 调试映像的另一种方法是使用 Virtualbox 之类的虚拟化工具在虚拟机内启动磁盘映像,并从 VM 内调试系统配置。
结论
在本指南中,您学习了如何使用 dd
命令行实用程序创建 Ubuntu 18.04 系统的磁盘映像,并将其作为自定义映像上传到 DigitalOcean,您可以从中启动 Droplets。
本指南中的步骤可能会因您的操作系统、现有硬件和内核配置而异,但一般来说,从流行的 Linux 发行版创建的映像应该使用这种方法工作。 请务必仔细按照安装和配置 cloud-init
的步骤操作,并确保您的系统满足上面 先决条件 部分中列出的所有要求。
要了解有关自定义图像的更多信息,请参阅 自定义图像产品文档。