Linux中國

如何構建一台網路引導伺服器(二)

如何構建一台網路引導伺服器(一) 的文章中,我們展示了如何創建一個網路引導鏡像,在那個鏡像中使用了一個名為 liveuser 帳戶,它的家目錄位於內存中,重啟後家目錄中的內容將全部消失。然而很多用戶都希望機器重啟後保存他們的文件和設置。因此,在本系列的第二部分,我們將向你展示如何在第一部分的基礎上,重新配置網路引導鏡像,以便 活動目錄 中的用戶帳戶可以進行登錄,然後從一個 NFS 伺服器上自動掛載他們的家目錄。

本系列的第三部分,我們將向你展示網路引導客戶端如何與中心化配置的 iPXE 引導菜單進行交互。

設置使用 KRB5 認證的 NFS4 Home 目錄

按以前的文章 「使用 Kerberos 強化共享的 NFS Home 目錄安全性」 的指導來做這個設置。

刪除 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 &apos;/services =/s/$/, pam/&apos; /fc28/etc/sssd/sssd.conf

另外,配置成確保客戶端不能更改這個帳戶密碼:

# sed -i &apos;/id_provider/a   ad_maximum_machine_account_password_age = 0&apos; /fc28/etc/sssd/sssd.conf

另外,複製 nfsnobody 的定義:

# for i in passwd shadow group gshadow; do grep "^nfsnobody:" /etc/$i >> /fc28/etc/$i; done

加入活動目錄

接下來,你將執行一個 chroot 將客戶端鏡像加入到活動目錄。從刪除預置在網路引導鏡像中同名的計算機帳戶開始:

# MY_USERNAME=jsmith
# MY_CLIENT_HOSTNAME=$(</fc28/etc/hostname)
# adcli delete-computer "${MY_CLIENT_HOSTNAME%%.*}" -U "$MY_USERNAME"

在網路引導鏡像中如果有 krb5.keytab 文件,也刪除它:

# rm -f /fc28/etc/krb5.keytab

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 &apos;initgroups: files&apos; >> /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 &apos;{print $4}&apos;)
# echo "$MY_IP $MY_HOSTNAME ${MY_HOSTNAME%%.*}" >> /fc28/etc/hosts

可選,允許所有用戶可以使用 sudo

# echo &apos;%users ALL=(ALL) NOPASSWD: ALL&apos; > /fc28/etc/sudoers.d/users

轉換 NFS 根目錄到一個 iSCSI 後備存儲器

在一個 nfsroot 連接建立之後,目前版本的 nfs-utils 可能很難為家目錄建立一個從客戶端到 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 &apos;s/nfs/iscsi/&apos; /etc/dracut.conf.d/netboot.conf
# echo &apos;omit_drivers+=" qedi "&apos; > /etc/dracut.conf.d/omit-qedi.conf
# echo &apos;blacklist qedi&apos; > /etc/modprobe.d/blacklist-qedi.conf
# KERNEL=$(ls -c /lib/modules | head -n 1)
# INITRD=$(find /boot -name &apos;init*&apos; | 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))

(如果你有一個可使用的獨立分區或磁碟驅動器,也可以用它,而不用再去創建這個稀疏文件了。)

接著,使用一個文件系統去格式化鏡像、掛載它、然後將網路引導鏡像複製進去:

# 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 測試時,客戶端偶爾會出現小狀況。似乎是因為 SquashFS 在多處理器客戶端上沒法執行隨機 I/O。(更多內容見 squashfs 讀取卡頓的奇怪案例)。如果你希望使用文件系統壓縮來提升吞吐性能,ZFS 或許是個很好的選擇。

如果你對 iSCSI 伺服器的吞吐性能要求非常高(比如,成百上千的客戶端要連接它),可能需要使用帶 負載均衡Ceph 集群了。更多相關內容,請查看 使用 HAProxy 和 Keepalived 負載均衡的 Ceph 對象網關

安裝和配置 iSCSI

為了給我們的客戶端提供網路引導鏡像,安裝 scsi-target-utils 包:

# dnf install -y scsi-target-utils

配置 iSCSI 守護程序去提供 fc28.img 文件:

# MY_REVERSE_HOSTNAME=$(echo $MY_HOSTNAME | tr &apos;.&apos; "n" | tac | tr "n" &apos;.&apos; | 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

開頭的 iqn./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

你現在應該能夠使用 tatadm 命令看到這個鏡像共享了:

# 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 &apos;/^/fc28 /d&apos; /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 &apos;vmlinuz&apos; | grep -m 1 $MY_KRNL) $HOME/esp/linux/vmlinuz-$MY_KRNL
$ cp $(find /fc28/boot -name &apos;init*&apos; | grep -m 1 $MY_KRNL) $HOME/esp/linux/initramfs-$MY_KRNL.img

更新 boot.cfg 文件去傳遞新的 rootnetroot 參數:

$ MY_NAME=server-01.example.edu
$ MY_EMAN=$(echo $MY_NAME | tr &apos;.&apos; "n" | tac | tr "n" &apos;.&apos; | cut -b -${#MY_NAME})
$ MY_ADDR=$(host -t A $MY_NAME | awk &apos;{print $4}&apos;)
$ 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 &apos;s/^exclude=kernel-*$/#exclude=kernel-*/&apos; /etc/dnf/dnf.conf

執行升級:

# dnf distro-sync -y --releasever=29

阻止更新過的內核被再次更新:

# sed -i &apos;s/^#exclude=kernel-*$/exclude=kernel-*/&apos; /etc/dnf/dnf.conf

上述命令是可選的,但是在以後,如果在鏡像中添加和更新了幾個包,在你的客戶端之外保存有一個最新內核的副本,會在關鍵時刻對你非常有幫助。

清理 dnf 的包緩存:

# dnf clean all

退出 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 &apos;.&apos; "n" | tac | tr "n" &apos;.&apos; | 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 &apos;vmlinuz&apos; | grep -m 1 $MY_KRNL) $HOME/esp/linux/vmlinuz-$MY_KRNL
$ cp $(find /fc29/boot -name &apos;init*&apos; | 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 &apos;.&apos; "n" | tac | tr "n" &apos;.&apos; | cut -b -${#MY_NAME})
$ MY_ADDR=$(host -t A $MY_NAME | awk &apos;{print $4}&apos;)
$ 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 中去使用它吧!

via: https://fedoramagazine.org/how-to-build-a-netboot-server-part-2/

作者:Gregory Bartholomew 選題:lujun9972 譯者:qhwdw 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國