如何使用 PXE 和直播服务器图像?
原因
随着 20.04 版本的发布,Ubuntu 似乎正在进一步推动直播服务器安装程序(下位性) 选项。debian-installer (di) 映像已重命名为 legacy。我通常喜欢的网络启动安装程序也是如此。20.04 版本还为直播服务器安裝程式。
答案1
使用 PXE 全自动安装 Ubuntu 20.04 服务器
这些是使用 PXE 进行全自动 Ubuntu 20.04 服务器安装的步骤,直播服务器图片。我发现这个过程记录得很少,而且问题很多。在这些步骤中,我将在UEFI基于服务器。
编辑:这些步骤适用于BIOS基于服务器通过 pxelinux 在裸机或 VirtualBox VM 上部署 Ubuntu 20.04,cloud-init 不会获取用户数据文件
编辑20.04
:这些步骤是专门针对Ubuntu 版本 ( )创建的subiquity 20.04.3
。 版本subiquity
随每次发布而变化。例如,20.04.3
Ubuntu 版本有subiquity 21.08.2
。由于 的积极开发,subiquity
本文中的一些信息对于较新的版本并不完全准确。
这些步骤可能有很多变化。它们可以根据个人需求进行定制和调整。目标是提供一个如何实现这一点的示例,并帮助其他用户克服遇到的问题。
关于安装程序的链接
- https://wiki.ubuntu.com/FocalFossa/ReleaseNotes#Installer
- https://ubuntu.com/server/docs/install/autoinstall
- https://discourse.ubuntu.com/t/server-installer-plans-for-20-04-lts/13631
- https://discourse.ubuntu.com/t/netbooting-the-live-server-installer/14510
配置参考
- https://ubuntu.com/server/docs/install/autoinstall-reference
- https://curtin.readthedocs.io/en/latest/topics/config.html
源代码
搭建一个tftp服务器
以下步骤均以 root 身份运行。这些步骤已在 Ubuntu 18.04 服务器上进行了测试。
安装 tftp 服务器和 web 服务器
apt-get -y install tftpd-hpa apache2
配置 apache 以从 tftp 目录提供文件
cat > /etc/apache2/conf-available/tftp.conf <<EOF
<Directory /var/lib/tftpboot>
Options +FollowSymLinks +Indexes
Require all granted
</Directory>
Alias /tftp /var/lib/tftpboot
EOF
a2enconf tftp
systemctl restart apache2
下载实时服务器 iso
wget http://old-releases.ubuntu.com/releases/20.04/ubuntu-20.04-live-server-amd64.iso -O /var/lib/tftpboot/ubuntu-20.04-live-server-amd64.iso
从实时服务器 iso 中提取内核和 initramfs
mount /var/lib/tftpboot/ubuntu-20.04-live-server-amd64.iso /mnt/
cp /mnt/casper/vmlinuz /var/lib/tftpboot/
cp /mnt/casper/initrd /var/lib/tftpboot/
umount /mnt
下载 grub 映像以通过 PXE 加载
wget http://archive.ubuntu.com/ubuntu/dists/focal/main/uefi/grub2-amd64/current/grubnetx64.efi.signed -O /var/lib/tftpboot/pxelinux.0
配置 grub。此配置将提供全自动启动选项以及手动启动选项
mkdir -p /var/lib/tftpboot/grub
cat > /var/lib/tftpboot/grub/grub.cfg <<'EOF'
default=autoinstall
timeout=30
timeout_style=menu
menuentry "Focal Live Installer - automated" --id=autoinstall {
echo "Loading Kernel..."
# make sure to escape the ';' or surround argument in quotes
linux /vmlinuz ip=dhcp url=http://${pxe_default_server}/tftp/ubuntu-20.04-live-server-amd64.iso autoinstall ds="nocloud-net;s=http://${pxe_default_server}/tftp/" root=/dev/ram0 cloud-config-url=/dev/null
echo "Loading Ram Disk..."
initrd /initrd
}
menuentry "Focal Live Installer" --id=install {
echo "Loading Kernel..."
linux /vmlinuz ip=dhcp url=http://${pxe_default_server}/tftp/ubuntu-20.04-live-server-amd64.iso root=/dev/ram0 cloud-config-url=/dev/null
echo "Loading Ram Disk..."
initrd /initrd
}
EOF
配置云初始化使用自动安装配置。我首先手动运行安装以获取生成的/var/log/installer/autoinstall-user-data
文件作为基础。然后我根据我的需求和遇到的错误进行了修改。
cat > /var/lib/tftpboot/meta-data <<EOF
instance-id: focal-autoinstall
EOF
cat > /var/lib/tftpboot/user-data <<'EOF'
#cloud-config
autoinstall:
version: 1
# use interactive-sections to avoid an automatic reboot
#interactive-sections:
# - locale
apt:
# even set to no/false, geoip lookup still happens
#geoip: no
preserve_sources_list: false
primary:
- arches: [amd64, i386]
uri: http://us.archive.ubuntu.com/ubuntu
- arches: [default]
uri: http://ports.ubuntu.com/ubuntu-ports
# r00tme
identity: {hostname: focal-autoinstall, password: $6$.c38i4RIqZeF4RtR$hRu2RFep/.6DziHLnRqGOEImb15JT2i.K/F9ojBkK/79zqY30Ll2/xx6QClQfdelLe.ZjpeVYfE8xBBcyLspa/,
username: ubuntu}
keyboard: {layout: us, variant: ''}
locale: en_US.UTF-8
# interface name will probably be different
network:
network:
version: 2
ethernets:
ens192:
critical: true
dhcp-identifier: mac
dhcp4: true
ssh:
allow-pw: true
authorized-keys: []
install-server: true
# this creates an efi partition, /boot partition, and root(/) lvm volume
storage:
grub:
reorder_uefi: False
swap:
size: 0
config:
- {ptable: gpt, path: /dev/sda, preserve: false, name: '', grub_device: false,
type: disk, id: disk-sda}
- {device: disk-sda, size: 536870912, wipe: superblock, flag: boot, number: 1,
preserve: false, grub_device: true, type: partition, id: partition-sda1}
- {fstype: fat32, volume: partition-sda1, preserve: false, type: format, id: format-2}
- {device: disk-sda, size: 1073741824, wipe: superblock, flag: linux, number: 2,
preserve: false, grub_device: false, type: partition, id: partition-sda2}
- {fstype: ext4, volume: partition-sda2, preserve: false, type: format, id: format-0}
- {device: disk-sda, size: -1, flag: linux, number: 3, preserve: false,
grub_device: false, type: partition, id: partition-sda3}
- name: vg-0
devices: [partition-sda3]
preserve: false
type: lvm_volgroup
id: lvm-volgroup-vg-0
- {name: lv-root, volgroup: lvm-volgroup-vg-0, size: 100%, preserve: false,
type: lvm_partition, id: lvm-partition-lv-root}
- {fstype: ext4, volume: lvm-partition-lv-root, preserve: false, type: format,
id: format-1}
- {device: format-1, path: /, type: mount, id: mount-2}
- {device: format-0, path: /boot, type: mount, id: mount-1}
- {device: format-2, path: /boot/efi, type: mount, id: mount-3}
write_files:
# override the kernel package
- path: /run/kernel-meta-package
content: |
linux-virtual
owner: root:root
permissions: "0644"
# attempt to also use an answers file by providing a file at the default path. It did not seem to have any effect
#- path: /subiquity_config/answers.yaml
# content: |
# InstallProgress:
# reboot: no
# owner: root:root
# permissions: "0644"
EOF
配置 DHCP
根据 DHCP 服务器的文档设置 DHCP 选项 66,67。
启动服务器
此时,您应该能够启动基于 UEFI 的服务器并执行完全自动安装。
遇到错误
- 正在安装的服务器需要超过 2 GB 的 RAM。我最终创建了一个具有 3 GB 的 VM 进行测试。 编辑使用
cloud-config-url=/dev/null
内核参数将防止cloud-init
不必要地下载 iso,这减少所需内存,减少网络流量,加快启动时间。 - 生成的
/var/log/installer/autoinstall-user-data
文件被破坏的方式如下- 没有
version
属性,导致验证失败。我添加了属性 - 该
network
部分需要另一层嵌套。配置参考中提到了这个错误 preserve
需要将每个项目的属性设置storage
config
为错误的。 否则科廷无法安装在空白磁盘上- 该
keyboard
属性toggle
被设置为 null,导致验证失败。我简单地删除了该属性
- 没有
- 什么时候科廷在 UEFI 设备上安装时,它会重新排列引导顺序,以便当前引导选项位于列表中的第一个。结果是网络引导成为下次重新启动时的第一个选项。因此,当安装完成并重新启动时……您最终会再次进入 PXE 环境,而不是从磁盘启动。我发现了一个未记录的 科廷选项
reorder_uefi
。幸运的是,下位性恰好将此配置传递给科廷 - 配置
apt
选项geoip
似乎不起作用。始终有 geoip 请求日志 - 使用人类可读的分区大小值(例如
size: 512M
)会导致大小存储为浮点数,从而导致在以百分比形式调整 LVM 卷大小时出错。避免使用人类可读的值似乎可以解决这个问题
其他缺失的功能
我没有深入研究这些。它们基于我的预置文件的功能。大多数问题可能可以通过巧妙使用early-commands
、late-commands
和来解决云初始化我可能还漏掉了一些东西
- 设置时区的方法
- 设置 root 密码的方法
- 配置仅 apt 代理的方法。我喜欢将其用于
apt-cacher-ng
apt,但它不能用作通用代理。安装程序假定您配置的任何代理都适用于所有内容 - 一种在安装结束时暂停而不是自动重新启动的方法。解决方法是向 添加一个值
interactive-sections
,但这会导致 3 次暂停 - 允许直接科廷配置。您必须创建 yaml云初始化提供 yaml 给下位性,然后生成 yaml科廷. 能够直接提供 curtin yaml,这将提供更多的配置灵活性
- 允许直接云初始化配置。您必须创建 yaml云初始化提供 yaml 给下位性,然后生成 yaml云初始化在已安装的机器上。这些文件应该很容易修改
late-commands
,但我没有尝试过 - 能够选择内核包。我发现安装的内核映像基于写入的内容
/run/kernel-meta-package
。这linux-generic
在 initramfs 中是硬编码的。我更喜欢linux-virtual
为虚拟机使用包。我能够使用云初始化配置覆盖文件
编辑1
cloud-init 在首次启动时使用的结果/target/var/lib/cloud/seed/nocloud-net/user-data
文件。回复表明该lock-passwd
属性有拼写错误,可能会影响某些用户
#cloud-config
growpart: {mode: 'off'}
locale: en_US.UTF-8
preserve_hostname: true
resize_rootfs: false
ssh_pwauth: true
users:
- gecos: ubuntu
groups: [adm, cdrom, dip, plugdev, lxd, sudo]
lock-passwd: false
name: ubuntu
passwd: $6$.c38i4RIqZeF4RtR$hRu2RFep/.6DziHLnRqGOEImb15JT2i.K/F9ojBkK/79zqY30Ll2/xx6QClQfdelLe.ZjpeVYfE8xBBcyLspa/
shell: /bin/bash
答案2
我在用户数据文件的“用户数据”部分设置了时区,并且在那里设置了 root 密码;如下所示:
#cloud-config
autoinstall:
version: 1
...
user-data:
timezone: Europe/London
disable_root: false
chpasswd:
list: |
root:HASHEDPASSWORD
...