文章 How to Build a Netboot Server, Part 1 向您展示了如何使用主目录位于易失性内存中的“liveuser”帐户创建 netboot 映像。 不过,大多数用户可能希望在重新启动后保留文件和设置。 因此,netboot 系列的第二部分展示了如何从第一部分重新配置 netboot 映像,以便 活动目录 用户帐户可以登录,并且可以从 NFS 服务器自动挂载他们的主目录。
本系列的第 3 部分将展示如何为 netboot 客户端制作交互式且可集中配置的 iPXE 引导菜单。
使用 KRB5 身份验证设置 NFS4 主目录
按照上一篇文章“使用 Kerberos 安全地共享 NFS 主目录”中的说明进行操作,然后返回此处。
删除 Liveuser 帐户
删除本系列第一部分中创建的“liveuser”帐户:
$ sudo -i # sed -i '/automaticlogin/Id' /fc28/etc/gdm/custom.conf # rm -f /fc28/etc/sudoers.d/liveuser # for i in passwd shadow group gshadow; do sed -i '/^liveuser:/d' /fc28/etc/$i; done
配置 NTP、KRB5 和 SSSD
接下来,我们需要在客户端镜像中复制我们在服务器上设置的 NTP、KRB5 和 SSSD 配置,以便可以使用相同的帐户:
# MY_HOSTNAME=$(</etc/hostname) # MY_DOMAIN=${MY_HOSTNAME#*.} # dnf -y --installroot=/fc28 install ntp krb5-workstation sssd # cp /etc/ntp.conf /fc28/etc # chroot /fc28 systemctl enable ntpd.service # cp /etc/krb5.conf.d/${MY_DOMAIN%%.*} /fc28/etc/krb5.conf.d # cp /etc/sssd/sssd.conf /fc28/etc/sssd
重新配置 sssd 以提供身份验证服务,除了已经配置的识别服务:
# sed -i '/services =/s/$/, pam/' /fc28/etc/sssd/sssd.conf
此外,确保没有任何客户端尝试更新计算机帐户密码:
# sed -i '/id_provider/a ad_maximum_machine_account_password_age = 0' /fc28/etc/sssd/sssd.conf
另外,复制 nfsnobody 定义:
# for i in passwd shadow group gshadow; do grep "^nfsnobody:" /etc/$i >> /fc28/etc/$i; done
加入活动目录
接下来,您将执行 chroot 以将客户端映像加入 Active Directory。 首先删除与您的网络启动映像将使用的名称相同的任何预先存在的计算机帐户:
# MY_USERNAME=jsmith # MY_CLIENT_HOSTNAME=$(</fc28/etc/hostname) # adcli delete-computer "${MY_CLIENT_HOSTNAME%%.*}" -U "$MY_USERNAME"
如果存在,还要从 netboot 映像中删除 krb5.keytab 文件:
# rm -f /fc28/etc/krb5.keytab
对 netboot 映像执行 chroot:
# for i in dev dev/pts dev/shm proc sys run; do mount -o bind /$i /fc28/$i; done # chroot /fc28 /usr/bin/bash --login
执行连接:
# MY_USERNAME=jsmith # MY_HOSTNAME=$(</etc/hostname) # MY_DOMAIN=${MY_HOSTNAME#*.} # MY_REALM=${MY_DOMAIN^^} # MY_OU="cn=computers,dc=${MY_DOMAIN//./,dc=}" # adcli join $MY_DOMAIN --login-user="$MY_USERNAME" --computer-name="${MY_HOSTNAME%%.*}" --host-fqdn="$MY_HOSTNAME" --user-principal="host/$MY_HOSTNAME@$MY_REALM" --domain-ou="$MY_OU"
现在退出 chroot 并清除 root 用户的命令历史记录:
# logout # for i in run sys proc dev/shm dev/pts dev; do umount /fc28/$i; done # > /fc28/root/.bash_history
安装和配置 PAM 挂载
我们希望我们的客户在登录时自动挂载用户的主目录。为此,我们将使用“pam_mount”模块。 安装和配置 pam_mount:
# dnf install -y --installroot=/fc28 pam_mount # cat << END > /fc28/etc/security/pam_mount.conf.xml <?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE pam_mount SYSTEM "pam_mount.conf.xml.dtd"> <pam_mount> <debug enable="0" /> <volume uid="1400000000-1499999999" fstype="nfs4" server="$MY_HOSTNAME" path="/home/%(USER)" mountpoint="/home/%(USER)" options="sec=krb5" /> <mkmountpoint enable="1" remove="0" /> <msg-authpw>Password:</msg-authpw> </pam_mount> END
重新配置 PAM 以使用 pam_mount:
# dnf install -y patch # cp -r /fc28/usr/share/authselect/default/sssd /fc28/etc/authselect/custom # echo 'initgroups: files' >> /fc28/etc/authselect/custom/sssd/nsswitch.conf # patch /fc28/etc/authselect/custom/sssd/system-auth << END @@ -12 +12,2 @@ -auth sufficient pam_sss.so forward_pass +auth requisite pam_mount.so {include if "with-pammount"} +auth sufficient pam_sss.so {if "with-pammount":use_first_pass|forward_pass} @@ -35,2 +36,3 @@ session required pam_unix.so +session optional pam_mount.so {include if "with-pammount"} session optional pam_sss.so END # patch /fc28/etc/authselect/custom/sssd/password-auth << END @@ -9 +9,2 @@ -auth sufficient pam_sss.so forward_pass +auth requisite pam_mount.so {include if "with-pammount"} +auth sufficient pam_sss.so {if "with-pammount":use_first_pass|forward_pass} @@ -32,2 +33,3 @@ session required pam_unix.so +session optional pam_mount.so {include if "with-pammount"} session optional pam_sss.so END # chroot /fc28 authselect select custom/sssd with-pammount --force
还要确保 NFS 服务器的主机名始终可以从客户端解析:
# MY_IP=$(host -t A $MY_HOSTNAME | awk '{print $4}') # echo "$MY_IP $MY_HOSTNAME ${MY_HOSTNAME%%.*}" >> /fc28/etc/hosts
(可选)允许所有用户运行 sudo:
# echo '%users ALL=(ALL) NOPASSWD: ALL' > /fc28/etc/sudoers.d/users
将 NFS 根转换为 iSCSI 后备存储
当前版本的 nfs-utils 可能难以在已建立 nfsroot 连接时建立从客户端到 NFS 服务器的第二个连接以获取主目录。 客户端在尝试访问主目录时挂起。 因此,我们将通过使用不同的协议 (iSCSI) 来共享我们的网络引导映像来解决这个问题。
首先 chroot 进入映像以重新配置其 initramfs 以便从 iSCSI 根引导:
# for i in dev dev/pts dev/shm proc sys run; do mount -o bind /$i /fc28/$i; done # chroot /fc28 /usr/bin/bash --login # dnf install -y iscsi-initiator-utils # sed -i 's/nfs/iscsi/' /etc/dracut.conf.d/netboot.conf # sed -i '/^node.conn[0].timeo.noop_out_interval /s/=.*$/= 0/' /etc/iscsi/iscsid.conf # sed -i '/^node.conn[0].timeo.noop_out_timeout /s/=.*$/= 0/' /etc/iscsi/iscsid.conf # sed -i '/^node.session.timeo.replacement_timeout /s/=.*$/= 86400/' /etc/iscsi/iscsid.conf # echo 'omit_drivers+=" qedi "' > /etc/dracut.conf.d/omit-qedi.conf # echo 'blacklist qedi' > /etc/modprobe.d/blacklist-qedi.conf # KERNEL=$(ls -c /lib/modules | head -n 1) # INITRD=$(find /boot -name 'init*' | grep -m 1 $KERNEL) # dracut -f $INITRD $KERNEL # logout # for i in run sys proc dev/shm dev/pts dev; do umount /fc28/$i; done # > /fc28/root/.bash_history
qedi 驱动程序在测试期间破坏了 iSCSI,因此这里已将其禁用。
接下来,创建一个 fc28.img 稀疏文件. 此文件用作 iSCSI 目标的后备存储:
# FC28_SIZE=$(du -ms /fc28 | cut -f 1) # dd if=/dev/zero of=/fc28.img bs=1MiB count=0 seek=$(($FC28_SIZE*2))
(如果有可用的,可以使用单独的分区或磁盘驱动器而不是创建文件。)
接下来,使用文件系统格式化映像,挂载它,然后将 netboot 映像复制到其中:
# mkfs -t xfs -L NETROOT /fc28.img # TEMP_MNT=$(mktemp -d) # mount /fc28.img $TEMP_MNT # cp -a /fc28/* $TEMP_MNT # umount $TEMP_MNT
在使用 SquashFS 进行测试期间,客户端偶尔会卡顿。 从多处理器客户端执行随机 I/O 时,SquashFS 似乎表现不佳。 (也可以看看 squashfs 停滞的奇怪案例.) 如果您想通过文件系统压缩来提高吞吐量性能, ZFS 可能是一个更好的选择。
如果您需要 iSCSI 服务器的极高吞吐量(例如,对于数百个客户端),则可以 负载均衡 一种 头孢 簇。 有关详细信息,请参阅 使用 HAProxy 和 Keepalived 对 Ceph 对象网关服务器进行负载平衡.
安装和配置 iSCSI
安装 scsi-target-utils 包,该包将提供 iSCSI 守护程序,用于将我们的映像提供给我们的客户:
# dnf install -y scsi-target-utils
配置 iSCSI 守护程序以提供 fc28.img 文件:
# MY_REVERSE_HOSTNAME=$(echo $MY_HOSTNAME | tr '.' "n" | tac | tr "n" '.' | cut -b -${#MY_HOSTNAME}) # cat << END > /etc/tgt/conf.d/fc28.conf <target iqn.$MY_REVERSE_HOSTNAME:fc28> backing-store /fc28.img readonly 1 </target> END
领先的智商。 由 /usr/lib/dracut/modules.d/40network/net-lib.sh 预期。
向防火墙添加例外并启用并启动服务:
# firewall-cmd --add-service=iscsi-target # firewall-cmd --runtime-to-permanent # systemctl enable tgtd.service # systemctl start tgtd.service
您现在应该能够看到正在使用 tgtadm 命令共享的图像:
# tgtadm --mode target --op show
上述命令应输出类似于以下内容:
Target 1: iqn.edu.example.server-01:fc28 System information: Driver: iscsi State: ready I_T nexus information: LUN information: LUN: 0 Type: controller SCSI ID: IET 00010000 SCSI SN: beaf10 Size: 0 MB, Block size: 1 Online: Yes Removable media: No Prevent removal: No Readonly: No SWP: No Thin-provisioning: No Backing store type: null Backing store path: None Backing store flags: LUN: 1 Type: disk SCSI ID: IET 00010001 SCSI SN: beaf11 Size: 10488 MB, Block size: 512 Online: Yes Removable media: No Prevent removal: No Readonly: Yes SWP: No Thin-provisioning: No Backing store type: rdwr Backing store path: /fc28.img Backing store flags: Account information: ACL information: ALL
我们现在可以删除我们在本系列的第一部分中创建的 NFS 共享:
# rm -f /etc/exports.d/fc28.exports # exportfs -rv # umount /export/fc28 # rmdir /export/fc28 # sed -i '/^/fc28 /d' /etc/fstab
您也可以删除 /fc28 文件系统,但您可能希望保留它以供将来执行更新。
更新 ESP 以使用 iSCSI 内核
更新 ESP 以包含启用 iSCSI 的 initramfs:
$ rm -vf $HOME/esp/linux/*.fc28.* $ MY_KRNL=$(ls -c /fc28/lib/modules | head -n 1) $ cp $(find /fc28/lib/modules -maxdepth 2 -name 'vmlinuz' | grep -m 1 $MY_KRNL) $HOME/esp/linux/vmlinuz-$MY_KRNL $ cp $(find /fc28/boot -name 'init*' | grep -m 1 $MY_KRNL) $HOME/esp/linux/initramfs-$MY_KRNL.img
更新 boot.cfg 文件以传递新的 root 和 netroot 参数:
$ MY_NAME=server-01.example.edu $ MY_EMAN=$(echo $MY_NAME | tr '.' "n" | tac | tr "n" '.' | cut -b -${#MY_NAME}) $ MY_ADDR=$(host -t A $MY_NAME | awk '{print $4}') $ sed -i "s! root=[^ ]*! root=/dev/disk/by-path/ip-$MY_ADDR:3260-iscsi-iqn.$MY_EMAN:fc28-lun-1 netroot=iscsi:$MY_ADDR::::iqn.$MY_EMAN:fc28!" $HOME/esp/linux/boot.cfg
现在您只需将更新后的文件从 $HOME/esp/linux 目录复制到所有客户端系统的 ESP 中。 您应该会看到类似于以下屏幕截图中显示的结果:
升级镜像
首先,复制当前图像:
# cp -a /fc28 /fc29
chroot 进入镜像的新副本:
# for i in dev dev/pts dev/shm proc sys run; do mount -o bind /$i /fc29/$i; done # chroot /fc29 /usr/bin/bash --login
允许更新内核:
# sed -i 's/^exclude=kernel-*$/#exclude=kernel-*/' /etc/dnf/dnf.conf
执行升级:
# dnf distro-sync -y --releasever=29
防止内核被更新:
# sed -i 's/^#exclude=kernel-*$/exclude=kernel-*/' /etc/dnf/dnf.conf
上述命令是可选的,但如果您在将来某个时间在映像中添加或更新一些软件包,则不必将新内核复制到客户端。
清理 dnf 的包缓存:
# dnf clean all
Exit chroot 并清除 root 的命令历史记录:
# logout # for i in run sys proc dev/shm dev/pts dev; do umount /fc29/$i; done # > /fc29/root/.bash_history
创建 iSCSI 映像:
# FC29_SIZE=$(du -ms /fc29 | cut -f 1) # dd if=/dev/zero of=/fc29.img bs=1MiB count=0 seek=$(($FC29_SIZE*2)) # mkfs -t xfs -L NETROOT /fc29.img # TEMP_MNT=$(mktemp -d) # mount /fc29.img $TEMP_MNT # cp -a /fc29/* $TEMP_MNT # umount $TEMP_MNT
定义一个指向我们的新映像的新 iSCSI 目标并将其导出:
# MY_HOSTNAME=$(</etc/hostname) # MY_REVERSE_HOSTNAME=$(echo $MY_HOSTNAME | tr '.' "n" | tac | tr "n" '.' | cut -b -${#MY_HOSTNAME}) # cat << END > /etc/tgt/conf.d/fc29.conf <target iqn.$MY_REVERSE_HOSTNAME:fc29> backing-store /fc29.img readonly 1 </target> END # tgt-admin --update ALL
将新内核和 initramfs 添加到 ESP:
$ MY_KRNL=$(ls -c /fc29/lib/modules | head -n 1) $ cp $(find /fc29/lib/modules -maxdepth 2 -name 'vmlinuz' | grep -m 1 $MY_KRNL) $HOME/esp/linux/vmlinuz-$MY_KRNL $ cp $(find /fc29/boot -name 'init*' | grep -m 1 $MY_KRNL) $HOME/esp/linux/initramfs-$MY_KRNL.img
更新 ESP 中的 boot.cfg:
$ MY_DNS1=192.0.2.91 $ MY_DNS2=192.0.2.92 $ MY_NAME=server-01.example.edu $ MY_EMAN=$(echo $MY_NAME | tr '.' "n" | tac | tr "n" '.' | cut -b -${#MY_NAME}) $ MY_ADDR=$(host -t A $MY_NAME | awk '{print $4}') $ cat << END > $HOME/esp/linux/boot.cfg #!ipxe kernel --name kernel.efi ${prefix}/vmlinuz-$MY_KRNL initrd=initrd.img ro ip=dhcp rd.peerdns=0 nameserver=$MY_DNS1 nameserver=$MY_DNS2 root=/dev/disk/by-path/ip-$MY_ADDR:3260-iscsi-iqn.$MY_EMAN:fc29-lun-1 netroot=iscsi:$MY_ADDR::::iqn.$MY_EMAN:fc29 console=tty0 console=ttyS0,115200n8 audit=0 selinux=0 quiet initrd --name initrd.img ${prefix}/initramfs-$MY_KRNL.img boot || exit END
最后,将 $HOME/esp/linux 目录中的文件复制到所有客户端系统的 ESP 中,尽情享受吧!