我们在内部使用 Ubuntu (14.04 Trusty) 来构建工作站,到目前为止,我们所有的构建工作都是手动完成的,包括创建 RAID/LVM/LUKS 加密卷。这种方式无法扩展,我现在正在努力实现部分流程的自动化,以减少构建新工作站所需的“动手”参与程度。
我们的硬盘配置如下:
- /dev/sda 和 /dev/sdb 都是 1Tb 硬盘,分区方式相同,并有 RAID
- 具有 RAID 1 的 1Gb 分区,包含作为 /boot 安装的 ext4 文件系统
- 包含 LVM PV/VG (vg_raid) 的驱动器 RAID 1 的其余部分
- 8Gb LV 用于交换空间
- 剩余空间 - LV 包含作为 / 安装的 ext4 文件系统
- /dev/sdc 128Gb 固态硬盘
- 包含 LVM PV/VG (vg_ssd) 的单个分区
- 单个 LV 使用所有可用空间,包含挂载在 /ssd 上的 ext4 文件系统
通过这种方式分区,我们有一个大型、冗余的根文件系统用于一般数据存储,还有一个较小的分区,可以放置对 I/O 速度敏感的文件(例如 MySQL 数据库)。
我正在尝试在 partman 中复制此内容,expert_recipe
并附带相关配置,以便 Ubuntu 安装程序可以创建它。我的主要问题是 partman 配方“语言”中似乎没有(有效的?)机制来指定需要在特定列组中创建特定 LV,以及将哪些 LVM 物理卷分配给每个卷组。我有一个早期版本的此配置,无需尝试分区/格式化/安装任何卷即可运行/dev/sdc
,但一旦涉及额外的“非 RAID”驱动器,我似乎无法在 partman 配方中表达我想要的内容。
我的 preseed.cfg 文件的相关部分如下:
d-i partman-auto/disk string /dev/sda /dev/sdb /dev/sdc
d-i partman-auto/method string raid
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-auto-lvm/new_vg_name string vg_raid vg_ssd
d-i partman-auto-lvm/guided_size string max
d-i partman-auto/expert_recipe string \
boot-root :: \
512 10 1024 raid \
$primary{ } $lvmignore{ } $bootable{ } \
method{ raid } \
device{ /dev/sda /dev/sdb } \
vg_name{ vg_raid } \
. \
4096 20 -1 raid \
$primary{ } $lvmignore{ } \
method{ raid } \
device{ /dev/sda /dev/sdb } \
. \
2048 20 -1 lvm \
$primary{ } \
$defaultignore{ } \
method{ lvm } \
device{ /dev/sdc } \
vg_name{ vg_ssd } \
. \
8192 100 -1 ext4 \
$defaultignore $lvmok{ } \
in_vg{ vg_raid } \
lv_name{ lv_root } \
method{ format } format{ } \
use_filesystem{ } filesystem{ ext4 } \
mountpoint{ / } \
device{ /dev/sda /dev/sdb } \
. \
4096 100 100% linux-swap \
$defaultignore $lvmok{ } \
in_vg{ vg_raid } \
lv_name{ lv_swap } \
method{ swap } format{ } \
device{ /dev/sda /dev/sdb } \
. \
2048 100 -1 ext4 \
$defaultignore $lvmok{ } \
method{ format } format{ } \
use_filesystem{ } filesystem{ ext4 } \
device{ /dev/sdc } \
in_vg{ vg_ssd } \
lv_name{ lv_ssd } \
mountpoint{ /ssd } \
. \
d-i partman-auto-raid/recipe string \
1 2 0 ext4 /boot /dev/sda1#/dev/sdb1 . \
1 2 0 lvm - /dev/sda2#/dev/sdb2 .
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman-lvm/confirm boolean true
d-i partman-md/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman-md/confirm_nooverwrite boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman/mount_style select label
您会注意到,我试图非常具体地说明哪些分区/卷应放在哪些磁盘上,但 partman 似乎不遵守至少部分配置。我在虚拟机上测试此配置时,还将最小卷大小保持在相当小的水平。当我在具有较小驱动器的 VirtualBox VM 上运行使用此配置的安装时,安装失败并显示错误消息:
Error while setting up RAID
An unexpected error occurred while setting up a preseeded RAID configuration.
Check /var/log/syslog or see virtual console 4 for the details.
syslog 中的相关部分如下:
Jan 13 02:41:54 md-devices: mdadm: No arrays found in config file or automatically
Jan 13 02:41:54 partman: No matching physical volumes found
Jan 13 02:41:54 partman: Reading all physical volumes. This may take a while...
Jan 13 02:41:54 partman:
Jan 13 02:41:54 partman: No volume groups found
Jan 13 02:41:54 partman:
Jan 13 02:41:54 partman-lvm:
Jan 13 02:41:54 partman-lvm: No volume groups found
Jan 13 02:41:54 partman-lvm:
Jan 13 02:41:56 partman-auto: Available disk space (4294) too small for expert recipe (4608); skipping
Jan 13 02:41:57 kernel: [ 91.295036] Adding 2095100k swap on /dev/sdc5. Priority:-1 extents:1 across:2095100k FS
Jan 13 02:41:57 partman: mke2fs 1.42.9 (4-Feb-2014)
Jan 13 02:41:57 apt-install: Queueing package mdadm for later installation
Jan 13 02:41:57 partman-auto-raid: Error: No recipe specified in partman-auto-raid/recipe
我怀疑倒数第四行是最相关的,因为您可以看到 partman 已经继续并在上创建了交换空间/dev/sdc
,这不是我想要的。
我尝试了多种分区指定方法。我在 Google 上搜索了很多与 partman 配方和 preseed 相关的版本术语,但找不到配方中不同配置选项的规范参考以及它们适用的原因。我找到了很多 RAID 示例和许多 LVM 示例,但没有找到以我尝试使用的方式将两者混合在一起的示例。这来自 debian-user 邮件列表的帖子这表明我想要做的事情是不可能的,而且这似乎与我的印象相符,即 partman 配方语言没有描述我想要实现的目标所需的工具。
如果有人能指出我的配置哪里出了问题,或者哪怕只是一些关于 partmanexpert_recipe
和相关配置语言的优秀参考资料,我都会非常感激。目前看来,除了分区部分之外,我可以自动化整个安装,而分区部分才是我想要自动化的主要内容!
答案1
使用 preseed 文件创建 raid+lvm 比较棘手。基本上,您无法使用 preseed 创建灵活的配置文件。它不像 RedHat/CentOS 中的 kickstart 那样简单流畅。
对我来说,我必须使用 preseed_early 语法创建自定义命令。您可以根据自己的配置随意更改。主要目标是在分区程序启动之前创建 RAID 阵列。安装守护程序将提示您未定义 /boot 分区,请忽略此信息。在 Debian 9 上测试
所以我们有四个磁盘
/dev/sda1 和 /dev/sdb1 是 RAID1 镜像 -> /dev/md0
/dev/sda2 和 /dev/sdb2 是 RAID0 条带。-> /dev/md1
/dev/sdc1 和 /dev/sdd1 是 RAID1 镜像。-> /dev/md2
在 md0 上他有一个 /boot 分区,
在 md1 上我们有一个交换文件,
在 md2 上是 /root。
因此预置文件如下:
d-i partman-auto/disk string /dev/md0 /dev/md1 /dev/md2
d-i partman-auto/method string lvm
d-i partman-auto/expert_recipe string \
1 1 -1 lvm \
$defaultignore{ } \
$primary{ } \
device{ /dev/md0 } \
method{ lvm } \
vg_name{ vg00 } \
. \
1 1 -1 lvm \
$defaultignore{ } \
$primary{ } \
device{ /dev/md1 } \
method{ lvm } \
vg_name{ vg01 } \
. \
1 1 -1 lvm \
$defaultignore{ } \
$primary{ } \
device{ /dev/md2 } \
method{ lvm } \
vg_name{ vg02 } \
. \
512 512 512 ext4 \
$lvmok{ } \
in_vg{ vg00 } \
lv_name{ lv_boot } \
method{ format } format{ } \
use_filesystem{ } filesystem{ ext4 } \
mountpoint{ /boot } \
. \
512 1024 1024 linux-swap \
$lvmok{ } \
in_vg{ vg02 } \
lv_name{ lv_swap } \
method{ swap } format{ } \
. \
1000 9000 9000 ext4 \
$lvmok{ } \
in_vg{ vg01 } \
lv_name{ lv_root } \
method{ format } format{ } \
use_filesystem{ } filesystem{ ext4 } \
mountpoint{ / } \
.
d-i grub-installer/bootdev string /dev/sda /dev/sdb
d-i preseed/early_command string /bin/killall.sh;\
/bin/netcfg;\
echo "o# clear the in memory partition table" >> /tmp/fdisk1;\
echo "n# create new partition" >> /tmp/fdisk1;\
echo "p# type primary" >> /tmp/fdisk1;\
echo "1# no. of partition" >> /tmp/fdisk1;\
echo " # default" >> /tmp/fdisk1;\
echo "+512M# partition size" >> /tmp/fdisk1;\
echo "t# partition type" >> /tmp/fdisk1;\
echo "fd# Linux RAID" >> /tmp/fdisk1;\
echo "w# write changes" >> /tmp/fdisk1;\
echo "n# create new partition" >> /tmp/fdisk2;\
echo "p# type primary" >> /tmp/fdisk2;\
echo "2# no. of partition" >> /tmp/fdisk2;\
echo " # default" >> /tmp/fdisk2;\
echo " # partition size" >> /tmp/fdisk2;\
echo "t# partition type" >> /tmp/fdisk2;\
echo "2# no. of partition" >> /tmp/fdisk2;\
echo "fd# Linux RAID" >> /tmp/fdisk2;\
echo "w# write changes" >> /tmp/fdisk2;\
echo "o# clear the in memory partition table" >> /tmp/fdisk3;\
echo "n# create new partition" >> /tmp/fdisk3;\
echo "p# type primary" >> /tmp/fdisk3;\
echo "1# no. of partition" >> /tmp/fdisk3;\
echo " # default" >> /tmp/fdisk3;\
echo " # partition size" >> /tmp/fdisk3;\
echo "t# partition type" >> /tmp/fdisk3;\
echo "fd# Linux RAID" >> /tmp/fdisk3;\
echo "w# write changes" >> /tmp/fdisk3;\
cat /tmp/fdisk1 | grep -o '^[^#]*' | fdisk /dev/sda;\
cat /tmp/fdisk1 | grep -o '^[^#]*' | fdisk /dev/sdb;\
cat /tmp/fdisk2 | grep -o '^[^#]*' | fdisk /dev/sda;\
cat /tmp/fdisk2 | grep -o '^[^#]*' | fdisk /dev/sdb;\
/sbin/mdadm --create /dev/md0 --metadata=1.2 --auto=mdp \
--raid-devices=2 --level=1 /dev/sda1 /dev/sdb1;\
cat /tmp/fdisk3 | grep -o '^[^#]*' | fdisk /dev/sdc;\
cat /tmp/fdisk3 | grep -o '^[^#]*' | fdisk /dev/sdd;\
/sbin/mdadm --create /dev/md1 --metadata=1.2 --auto=mdp \
--raid-devices=2 --level=1 /dev/sdc1 /dev/sdd1;\
/sbin/mdadm --create /dev/md2 --metadata=1.2 --auto=mdp \
--raid-devices=2 --level=0 /dev/sda2 /dev/sdb2;\