Ubuntu 将停止支持 Debian 安装程序(预置)。Ubuntu Server 20.04 附带了一种新的自动化操作系统安装方法,称为带有 subiquity 服务器安装程序的自动安装。这篇文章展示了使用新安装程序构建的打包程序。
此设置仅适用于 Ubuntu-20.04 live-server 而不是旧版。
Subiquity 是 Ubuntu 服务器的新自动安装程序,它是在 18.04 中引入的。自动安装的设置由 cloud-init 配置提供。如果设置,将从配置文件中获取值,否则将使用默认值。有多种交付 cloud-init 配置的方式。用户配置通常包含在元数据文件中的用户数据和云配置中。有关更多详细信息,您可以查看Canonical 提供的 AutoInstall 文档。
我们的安装程序基于 curtin、netplan 和 cloud-init。
#cloud-config
autoinstall:
version: 1
early-commands:
# Stop ssh for packer
- sudo systemctl stop ssh
locale: en_US
keyboard:
layout: en
variant: us
identity:
hostname: ubuntu-server
username: ubuntu
password: '$6$rounds=4096$NYG7e8HxIMgz1$BqP28Ppt0FqXiBQuiE6PxiVBJJJAbm8tJrNz4HC7MEC.7Gv/eOyQIfaLqZ6W6fnMMtxP.BYfHmTBxUFQQs0u91'
ssh:
install-server: yes
allow-pw: yes
storage:
layout:
name: direct
apt:
primary:
- arches: [i386, amd64]
uri: "http://ro.archive.ubuntu.com/ubuntu/"
user-data:
disable_root: false
late-commands:
- sed -i -e 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /target/etc/ssh/sshd_config
- sed -i -e 's/^#\?PermitRootLogin.*/PermitRootLogin yes/g' /target/etc/ssh/sshd_config
- echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/ubuntu
- curtin in-target --target=/target -- chmod 440 /etc/sudoers.d/ubuntu
- curtin in-target --target=/target -- apt-get update
- curtin in-target --target=/target -- apt-get upgrade --yes
如您所见,它是.yaml
格式化的配置。我们已经在此配置中指定了所有详细信息(否则我们需要的将使用默认值)。但是我们需要了解一些棘手的部分。首先,identity
正如您所见,我们使用了散列密码。出于安全目的,这是自动安装程序的默认要求。实际上,我们需要更多的深度安全系统,但目前还可以。但是我们如何生成这个散列密码呢?实际上,我用作ubuntu
ssh 连接的密码并对其进行哈希处理,我使用了以下命令:
mkpasswd -m SHA-512 --rounds=4096
现在让我们向上移动一点并找出答案early-commands
。这是什么意思?实际上,当我们开始packer build时,packer会尝试从一开始就设置ssh连接到我们的机器。所以在初始化期间它可能会给我们错误可能会破坏构建。所以在第一阶段我们需要确保我们的 ssh 连接已经停止。要了解所有部分,您可以查看Ubuntu Autoinstall Reference。幸运的是,Canonical 提供的文档非常简单和有用。
现在我们需要创建元数据文件。但我们会将其保留为空。最后我们需要创建http
目录并将这些文件放入其中。
现在我们需要定义我们的打包文件:
{
"builders": [
{
"CPUs": 2,
"RAM": 2048,
"RAM_reserve_all": true,
"firmware": "bios",
"boot_command": [
"",
"",
"/casper/vmlinuz ",
"root=/dev/sr0 ",
"initrd=/casper/initrd ",
"autoinstall ",
"ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/",
""
],
"boot_wait": "2s",
"convert_to_template": "true",
"create_snapshot": "false",
"datacenter": "{{user `vcenter_datacenter`}}",
"datastore": "{{user `vcenter_datastore`}}",
"disk_controller_type": "pvscsi",
"folder": "{{user `vcenter_folder`}}",
"guest_os_type": "ubuntu64Guest",
"host": "{{user `vcenter_host`}}",
"http_directory": "{{user `http_directory`}}",
"insecure_connection": "true",
"iso_checksum": "{{user `iso_checksum_type`}}:{{user `iso_checksum`}}",
"iso_paths": "{{user `iso_paths`}}",
"name": "Ubuntu-20.04",
"network_adapters": [
{
"network": "{{user `vcenter_network`}}",
"network_card": "vmxnet3"
}
],
"notes": "Default SSH User: {{user `ssh_username`}}\nDefault SSH Pass: {{user `ssh_password`}}\nBuilt by Packer @ {{isotime \"2006-01-02 03:04\"}}.",
"password": "{{user `vcenter_password`}}",
"shutdown_command": "echo 'ubuntu'|sudo -S shutdown -P now",
"ssh_password": "{{user `ssh_password`}}",
"ssh_timeout": "20m",
"ssh_handshake_attempts": "100000",
"ssh_username": "{{user `ssh_username`}}",
"storage": [
{
"disk_size": 20480,
"disk_thin_provisioned": true
}
],
"type": "vsphere-iso",
"username": "{{user `vcenter_username`}}",
"vcenter_server": "{{user `vcenter_server`}}",
"vm_name": "{{user `vm_name`}}"
}
],
"provisioners": [
{
"type": "shell",
"execute_command": "echo 'ubuntu' | {{.Vars}} sudo -S -E bash '{{.Path}}'",
"script": "scripts/setup_ubuntu2004.sh"
}
]
}
我现在需要提一些棘手的问题。所以如你所见,我user
在打包文件上使用了关键字。它用于定义变量。另一个最重要的部分是ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/
. 那是什么意思呢?正如您所记得的,我创建了 http 目录并将配置文件放入其中。所以我们需要一个 web 服务器来提供这些文件,以便打包程序在构建过程中使用它们。执行构建时,Packer 将启动一个小型 HTTP 服务器并用相应的 IP 和端口替换{{.HTTPIP}}
和{.HTTPPort}}
变量。您还必须设置http_directory
(我已经在打包文件中定义了)配置选项来定义哪个目录托管您希望由文件系统上的 HTTP 服务器提供的文件。如您所愿,您还可以通过不同方式提供文件。例如,我已将配置文件上传到我的自定义静态服务器并通过此服务器提供服务。我的意思是,http://{{ .HTTPIP }}:{{ .HTTPPort }}/
我没有使用自己的服务器https://ubuntu-cloud-init.vercel.app/
进行企业配置。
至少我们需要定义变量文件。这是我的:
{
"vm_name": "Ubuntu-2004-Template",
"vcenter_server":"",
"vcenter_username":"",
"vcenter_password":"",
"vcenter_datacenter": "",
"vcenter_datastore": "",
"vcenter_host": "",
"vcenter_folder": "",
"vcenter_network": "",
"guest_os_type": "ubuntu64Guest",
"http_directory": "http",
"iso_urls": "https://releases.ubuntu.com/focal/ubuntu-20.04.1-live-server-amd64.iso",
"iso_checksum_type": "sha256",
"iso_checksum": "443511f6bf12402c12503733059269a2e10dec602916c0a75263e5d990f6bb93",
"iso_paths": "[Datastore VMS] /packer_cache/ubuntu-20.04.1-live-server-amd64.iso",
"ssh_username": "ubuntu",
"ssh_password": "ubuntu"
}
您可以将自己的自定义详细信息用于空vcenter
变量。我iso_path
在打包文件上使用了变量。但我也已将iso_url
变量添加到变量文件中。所以如果你没有准备好 Ubuntu-20.04 live-server 那么你基本上可以在打包文件中更改iso_path
变量iso_url
。
这在基于 Ubuntu 20.04 的 vSphere 中构建了一个 VM 模板,具有预定义的 ubuntu/ubuntu 用户。虽然这张图片仍然很有帮助,但我想为我的图片添加另一个阶段。我计划将此映像与 Rancher 的 vSphere Provisioner 一起使用,这意味着我需要 vSphere cloud-init 的数据源。它可在此处作为插件使用。所以我provisioners
在打包文件中添加了一个脚本:
"provisioners": [
{
"type": "shell",
"execute_command": "echo 'ubuntu' | {{.Vars}} sudo -S -E bash '{{.Path}}'",
"script": "scripts/setup_ubuntu2004.sh"
}
]
这将设置数据源并重置机器 ID 以重置机器的状态。您可以从我的 github repo 中找到打包程序文件和配置以及脚本。