Merge pull request #11534 from qhwdw/tr1205

Translated by qhwdw
This commit is contained in:
Xingyu.Wang 2018-12-07 23:21:59 +08:00 committed by GitHub
commit 8af5d1571b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 462 additions and 461 deletions

View File

@ -1,461 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (qhwdw)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: subject: (How to Build a Netboot Server, Part 1)
[#]: via: (https://fedoramagazine.org/how-to-build-a-netboot-server-part-1/)
[#]: author: (Gregory Bartholomew https://fedoramagazine.org/author/glb/)
[#]: url: ( )
How to Build a Netboot Server, Part 1
======
![](https://fedoramagazine.org/wp-content/uploads/2018/11/build-netboot-816x345.jpg)
Some computer networks need to maintain identical software installations and configurations on several physical machines. One such environment would be a school computer lab. A [netboot][1] server can be set up to serve an entire operating system over a network so that the client computers can be configured from one central location. This tutorial will show one method of building a netboot server.
Part 1 of this tutorial will cover creating a netboot server and image. Part 2 will show how to add Kerberos-authenticated home directories to the netboot configuration.
### Initial Configuration
Start by downloading one of Fedora Servers [netinst][2] images, burning it to a CD, and booting the server that will be reformatted from it. We just need a typical “Minimal Install” of Fedora Server for our starting point and we will use the command line to add any additional packages that are needed after the installation is finished.
![][3]
> NOTE: For this tutorial we will be using Fedora 28. Other versions may include a slightly different set of packages in their “Minimal Install”. If you start with a different version of Fedora, then you may need to do some troubleshooting if an expected file or command is not available.
Once you have your minimal installation of Fedora Server up and running, log in as root and set the hostname:
```
$ MY_HOSTNAME=server-01.example.edu
$ hostnamectl set-hostname $MY_HOSTNAME
```
> NOTE: Red Hat recommends that both static and transient names match the fully-qualified domain name (FQDN) used for the machine in DNS, such as host.example.com ([Understanding Host Names][4]).
>
> NOTE: This guide is meant to be copy-and-paste friendly. Any value that you might need to customize will be stated as a MY_* variable that you can tweak before running the remaining commands. Beware that if you log out, the variable assignments will be cleared.
>
> NOTE: Fedora 28 Server tends to dump a lot of logging output to the console by default. You may want to disable the console logging temporarily by running: sysctl -w kernel.printk=0
Next, we need a static network address on our server. The following sequence of commands should find and reconfigure your default network connection appropriately:
```
$ MY_DNS1=192.0.2.91
$ MY_DNS2=192.0.2.92
$ MY_IP=192.0.2.158
$ MY_PREFIX=24
$ MY_GATEWAY=192.0.2.254
$ DEFAULT_DEV=$(ip route show default | awk '{print $5}')
$ DEFAULT_CON=$(nmcli d show $DEFAULT_DEV | sed -n '/^GENERAL.CONNECTION:/s!.*:\s*!! p')
$ nohup bash << END
nmcli con mod "$DEFAULT_CON" connection.id "$DEFAULT_DEV"
nmcli con mod "$DEFAULT_DEV" connection.interface-name "$DEFAULT_DEV"
nmcli con mod "$DEFAULT_DEV" ipv4.method disabled
nmcli con up "$DEFAULT_DEV"
nmcli con add con-name br0 ifname br0 type bridge
nmcli con mod br0 bridge.stp no
nmcli con mod br0 ipv4.dns $MY_DNS1,$MY_DNS2
nmcli con mod br0 ipv4.addresses $MY_IP/$MY_PREFIX
nmcli con mod br0 ipv4.gateway $MY_GATEWAY
nmcli con mod br0 ipv4.method manual
nmcli con up br0
nmcli con add con-name br0-slave0 ifname "$DEFAULT_DEV" type bridge-slave master br0
nmcli con up br0-slave0
END
```
> NOTE: The last set of commands above is wrapped in a “nohup” script because it will disable networking temporarily. The nohup command should allow the nmcli commands to finish running even while your ssh connection is down. Beware that it may take 10 or so seconds for the connection to come back up and that you will have to start a new ssh connection if you changed the servers IP address.
>
> NOTE: The above network configuration creates a [network bridge][5] on top of the default connection so that we can run a virtual machine instance directly on the server for testing later. If you do not want to test the netboot image directly on the server, you can skip creating the bridge and set the static IP address directly on your default network connection.
### Install and Configure NFS4
Start by installing the nfs-utils package:
```
$ dnf install -y nfs-utils
```
Create a top-level [pseudo filesystem][6] for the NFS exports and share it out to your network:
```
$ MY_SUBNET=192.0.2.0
$ mkdir /export
$ echo "/export -fsid=0,ro,sec=sys,root_squash $MY_SUBNET/$MY_PREFIX" > /etc/exports
```
SELinux will interfere with the netboot servers operation. Configuring exceptions for it is beyond the scope of this tutorial, so we will disable it:
```
$ sed -i '/GRUB_CMDLINE_LINUX/s/"$/ audit=0 selinux=0"/' /etc/default/grub
$ grub2-mkconfig -o /boot/grub2/grub.cfg
$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
$ setenforce 0
```
> NOTE: Editing the grub command line should not be necessary, but simply editing /etc/sysconfig/selinux proved ineffective across reboots of Fedora Server 28 during testing, so the “selinux=0” flag has been set here to be doubly sure.
Now, add an exception for the NFS service to the local firewall and start the NFS service:
```
$ firewall-cmd --add-service nfs
$ firewall-cmd --runtime-to-permanent
$ systemctl enable nfs-server.service
$ systemctl start nfs-server.service
```
### Create the Netboot Image
Now that our NFS server is up and running, we need to supply it with an operating system image to serve to the client computers. We will start with a very minimal image and add to it after everything is working.
First, create a new directory where our image will be stored:
```
$ mkdir /fc28
```
Use the “dnf” command to build the image under the new directory with only a few base packages:
```
$ dnf -y --releasever=28 --installroot=/fc28 install fedora-release systemd passwd rootfiles sudo dracut dracut-network nfs-utils vim-minimal dnf
```
It is important that the “kernel” packages were omitted from the above command. Before they are installed, we need to tweak the set of drivers that will be included in the “initramfs” image that is built automatically when the kernel is first installed. In particular, we need to disable “hostonly” mode so that the initramfs image will work on a wider set of hardware platforms and we need to add support for networking and NFS:
```
$ echo 'hostonly=no' > /fc28/etc/dracut.conf.d/hostonly.conf
$ echo 'add_dracutmodules+=" network nfs "' > /fc28/etc/dracut.conf.d/netboot.conf
```
Now, install the kernel:
```
$ dnf -y --installroot=/fc28 install kernel
```
Set a rule to prevent the kernel from being updated:
```
$ echo 'exclude=kernel-*' >> /fc28/etc/dnf/dnf.conf
```
Set the locale:
```
$ echo 'LANG="en_US.UTF-8"' > /fc28/etc/locale.conf
```
> NOTE: Some programs (e.g. GNOME Terminal) will not function if the locale is not properly configured.
Blank roots passwd:
```
$ sed -i 's/^root:\*/root:/' /fc28/etc/shadow
```
Set the clients hostname:
```
$ MY_CLIENT_HOSTNAME=client-01.example.edu
$ echo $MY_CLIENT_HOSTNAME > /fc28/etc/hostname
```
Disable logging to the console:
```
$ echo 'kernel.printk = 0 4 1 7' > /fc28/etc/sysctl.d/00-printk.conf
```
Define a local “liveuser” in the netboot image:
```
$ echo 'liveuser:x:1000:1000::/home/liveuser:/bin/bash' >> /fc28/etc/passwd
$ echo 'liveuser::::::::' >> /fc28/etc/shadow
$ echo 'liveuser:x:1000:' >> /fc28/etc/group
$ echo 'liveuser:!::' >> /fc28/etc/gshadow
```
Allow “liveuser” to sudo:
```
$ echo 'liveuser ALL=(ALL) NOPASSWD: ALL' > /fc28/etc/sudoers.d/liveuser
```
Enable automatic home directory creation:
```
$ dnf install -y --installroot=/fc28 authselect oddjob-mkhomedir
$ echo 'dirs /home' > /fc28/etc/rwtab.d/home
$ chroot /fc28 authselect select sssd with-mkhomedir --force
$ chroot /fc28 systemctl enable oddjobd.service
```
Since multiple clients will be mounting our image concurrently, we need to configure the image so that it will operate in read-only mode:
```
$ sed -i 's/^READONLY=no$/READONLY=yes/' /fc28/etc/sysconfig/readonly-root
```
Configure logging to go to RAM rather than permanent storage:
```
$ sed -i 's/^#Storage=auto$/Storage=volatile/' /fc28/etc/systemd/journald.conf
```
Configure DNS:
```
$ MY_DNS1=192.0.2.91
$ MY_DNS2=192.0.2.92
$ cat << END > /fc28/etc/resolv.conf
nameserver $MY_DNS1
nameserver $MY_DNS2
END
```
Work-around a few bugs that exist for read-only root mounts at the time this tutorial is being written ([BZ1542567][7]):
```
$ echo 'dirs /var/lib/gssproxy' > /fc28/etc/rwtab.d/gssproxy
$ cat << END > /fc28/etc/rwtab.d/systemd
dirs /var/lib/systemd/catalog
dirs /var/lib/systemd/coredump
END
```
Finally, we can create the NFS filesystem for our image and share it out to our subnet:
```
$ mkdir /export/fc28
$ echo '/fc28 /export/fc28 none bind 0 0' >> /etc/fstab
$ mount /export/fc28
$ echo "/export/fc28 -ro,sec=sys,no_root_squash $MY_SUBNET/$MY_PREFIX" > /etc/exports.d/fc28.exports
$ exportfs -vr
```
### Create the Boot Loader
Now that we have an operating system available to netboot, we need a boot loader to kickstart it on the client systems. For this setup, we will be using [iPXE][8].
> NOTE: This section and the following section — Testing with QEMU — can be done on a separate computer; they do not have to be run on the netboot server.
Install git and use it to download iPXE:
```
$ dnf install -y git
$ git clone http://git.ipxe.org/ipxe.git $HOME/ipxe
```
Now we need to create a special startup script for our bootloader:
```
$ cat << 'END' > $HOME/ipxe/init.ipxe
#!ipxe
prompt --key 0x02 --timeout 2000 Press Ctrl-B for the iPXE command line... && shell ||
dhcp || exit
set prefix file:///linux
chain ${prefix}/boot.cfg || exit
END
```
Enable the “file” download protocol:
```
$ echo '#define DOWNLOAD_PROTO_FILE' > $HOME/ipxe/src/config/local/general.h
```
Install the C compiler and related tools and libraries:
```
$ dnf groupinstall -y "C Development Tools and Libraries"
```
Build the boot loader:
```
$ cd $HOME/ipxe/src
$ make clean
$ make bin-x86_64-efi/ipxe.efi EMBED=../init.ipxe
```
Make note of where the where the newly-compiled boot loader is. We will need it for the next section:
```
$ IPXE_FILE="$HOME/ipxe/src/bin-x86_64-efi/ipxe.efi"
```
### Testing with QEMU
This section is optional, but you will need to duplicate the file layout of the [EFI system partition][9] that is shown below on your physical machines to configure them for netbooting.
> NOTE: You could also copy the files to a TFTP server and reference that server from DHCP if you wanted a fully diskless system.
In order to test our boot loader with QEMU, we are going to create a small disk image containing only an EFI system partition and our startup files.
Start by creating the required directory layout for the EFI system partition and copying the boot loader that we created in the previous section to it:
```
$ mkdir -p $HOME/esp/efi/boot
$ mkdir $HOME/esp/linux
$ cp $IPXE_FILE $HOME/esp/efi/boot/bootx64.efi
```
The below command should identify the kernel version that our netboot image is using and store it in a variable for use in the remaining configuration directives:
```
$ DEFAULT_VER=$(ls -c /fc28/lib/modules | head -n 1)
```
Define the boot configuration that our client computers will be using:
```
$ MY_DNS1=192.0.2.91
$ MY_DNS2=192.0.2.92
$ MY_NFS4=server-01.example.edu
$ cat << END > $HOME/esp/linux/boot.cfg
#!ipxe
kernel --name kernel.efi \${prefix}/vmlinuz-$DEFAULT_VER initrd=initrd.img ro ip=dhcp rd.peerdns=0 nameserver=$MY_DNS1 nameserver=$MY_DNS2 root=nfs4:$MY_NFS4:/fc28 console=tty0 console=ttyS0,115200n8 audit=0 selinux=0 quiet
initrd --name initrd.img \${prefix}/initramfs-$DEFAULT_VER.img
boot || exit
END
```
> NOTE: The above boot script shows a minimal example of how to get iPXE to netboot Linux. Much more complex configurations are possible. Most notably, iPXE has support for interactive boot menus which can be configured with a default selection and a timeout. A more advanced iPXE script could, for example, default to booting an operation system from the local disk and only go to the netboot operation if a user pressed a key before a countdown timer reached zero.
Copy the Linux kernel and its associated initramfs to the EFI system partition:
```
$ cp $(find /fc28/lib/modules -maxdepth 2 -name 'vmlinuz' | grep -m 1 $DEFAULT_VER) $HOME/esp/linux/vmlinuz-$DEFAULT_VER
$ cp $(find /fc28/boot -name 'init*' | grep -m 1 $DEFAULT_VER) $HOME/esp/linux/initramfs-$DEFAULT_VER.img
```
Our resulting directory layout should look like this:
```
esp
├── efi
│   └── boot
│   └── bootx64.efi
└── linux
├── boot.cfg
├── initramfs-4.18.18-200.fc28.x86_64.img
└── vmlinuz-4.18.18-200.fc28.x86_64
```
To use our EFI system partition with QEMU, we need to create a small “uefi.img” disk image containing it and then connect that to QEMU as the primary boot drive.
Begin by installing the necessary tools:
```
$ dnf install -y parted dosfstools
```
Now create the “uefi.img” file and copy the files from the “esp” directory into it:
```
$ ESP_SIZE=$(du -ks $HOME/esp | cut -f 1)
$ dd if=/dev/zero of=$HOME/uefi.img count=$((${ESP_SIZE}+5000)) bs=1KiB
$ UEFI_DEV=$(losetup --show -f $HOME/uefi.img)
$ parted ${UEFI_DEV} -s mklabel gpt mkpart EFI FAT16 1MiB 100% toggle 1 boot
$ mkfs -t msdos ${UEFI_DEV}p1
$ mkdir -p $HOME/mnt
$ mount ${UEFI_DEV}p1 $HOME/mnt
$ cp -r $HOME/esp/* $HOME/mnt
$ umount $HOME/mnt
$ losetup -d ${UEFI_DEV}
```
> NOTE: On a physical computer, you need only copy the files from the “esp” directory to the computers existing EFI system partition. You do not need the “uefi.img” file to boot a physical computer.
>
> NOTE: On a physical computer you can rename the “bootx64.efi” file if a file by that name already exists, but if you do so, you will probably have to edit the computers BIOS settings and add the renamed efi file to the boot list.
Next we need to install the qemu package:
```
$ dnf install -y qemu-system-x86
```
Allow QEMU to access the bridge that we created in the “Initial Configuration” section of this tutorial:
```
$ echo 'allow br0' > /etc/qemu/bridge.conf
```
Create a copy of the “OVMF_VARS.fd” image to store our virtual machines persistent BIOS settings:
```
$ cp /usr/share/edk2/ovmf/OVMF_VARS.fd $HOME
```
Now, start the virtual machine:
```
$ qemu-system-x86_64 -machine accel=kvm -nographic -m 1024 -drive if=pflash,format=raw,unit=0,file=/usr/share/edk2/ovmf/OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,unit=1,file=$HOME/OVMF_VARS.fd -drive if=ide,format=raw,file=$HOME/uefi.img -net bridge,br=br0 -net nic,model=virtio
```
If all goes well, you should see results similar to what is shown in the below image:
![][10]
You can use the “shutdown” command to get out of the virtual machine and back to the server:
```
$ sudo shutdown -h now
```
> NOTE: If something goes wrong and the virtual machine hangs, you may need to start a new ssh session to the server and use the “kill” command to terminate the “qemu-system-x86_64” process.
### Adding to the Image
Adding to the image should be a simple matter of chrooting into the image on the server and running “dnf install <package_name>”.
There is no limit to what can be installed on the netboot image. A full graphical installation should function perfectly.
Here is an example of how to bring our minimal netboot image up to a complete graphical installation:
```
$ 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 -y groupinstall "Fedora Workstation"
$ dnf -y remove gnome-initial-setup
$ systemctl disable sshd.service
$ systemctl enable gdm.service
$ systemctl set-default graphical.target
$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
$ logout
$ for i in run sys proc dev/shm dev/pts dev; do umount /fc28/$i; done
```
Optionally, you may want to enable automatic login for the “liveuser” account:
```
$ sed -i '/daemon/a AutomaticLoginEnable=true' /fc28/etc/gdm/custom.conf
$ sed -i '/daemon/a AutomaticLogin=liveuser' /fc28/etc/gdm/custom.conf
```
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/how-to-build-a-netboot-server-part-1/
作者:[Gregory Bartholomew][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/glb/
[b]: https://github.com/lujun9972
[1]: https://en.wikipedia.org/wiki/Network_booting
[2]: https://dl.fedoraproject.org/pub/fedora/linux/releases/28/Server/x86_64/iso/
[3]: https://fedoramagazine.org/wp-content/uploads/2018/11/installation-summary-1024x768.png
[4]: https://docs.fedoraproject.org/en-US/Fedora/25/html/Networking_Guide/ch-Configure_Host_Names.html#sec_Understanding_Host_Names
[5]: https://en.wikipedia.org/wiki/Bridging_(networking)
[6]: https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s3-nfs-server-config-exportfs-nfsv4.html
[7]: https://bugzilla.redhat.com/show_bug.cgi?id=1542567
[8]: https://ipxe.org/
[9]: https://en.wikipedia.org/wiki/EFI_system_partition
[10]: https://fedoramagazine.org/wp-content/uploads/2018/11/netboot-liveuser-1024x641.png

View File

@ -0,0 +1,462 @@
[#]: collector: (lujun9972)
[#]: translator: (qhwdw)
[#]: reviewer:
[#]: publisher:
[#]: subject: (How to Build a Netboot Server, Part 1)
[#]: via: (https://fedoramagazine.org/how-to-build-a-netboot-server-part-1/)
[#]: author: (Gregory Bartholomew https://fedoramagazine.org/author/glb/)
[#]: url:
如何构建一台网络引导服务器(第一部分)
======
![](https://fedoramagazine.org/wp-content/uploads/2018/11/build-netboot-816x345.jpg)
有些计算机网络需要在各个物理机器上维护相同的软件和配置。学校的计算机实验室就是这样的一个环境。一台 [网络引导][1] 服务器能够被配置为基于网络去提供一个完整的操作系统,以便于客户端计算机从一个中央位置获取配置。本教程将向你展示构建一台网络引导服务器的一种方法。
本教程的第一部分将包括创建一台网络引导服务器和镜像。第二部分将展示如何去添加 Kerberos 验证的 home 目录到网络引导配置中。
### 初始化配置
首先去下载 Fedora 服务器的 [netinst][2] 镜像,将它刻录到一张光盘上,然后它将引导服务器去重新格式化。我们只需要一个典型的 Fedora Server 的“最小化安装”来作为我们的开端,安装完成后,我们可以使用命令行去添加我们需要的任何额外的包。
![][3]
> 注意:本教程中我们将使用 Fedora 28。其它版本在“最小化安装”中包含的包可能略有不同。如果你使用的是不同的 Fedora 版本,如果一个预期的文件或命令不可用,你可能需要做一些调试。
最小化安装的 Fedora Server 运行起来之后,以 root 用户登入并设置主机名字:
```javascript
$ MY_HOSTNAME=server-01.example.edu
$ hostnamectl set-hostname $MY_HOSTNAME
```
> 注意Red Hat 建议静态和临时名字应都要与这个机器在 DNS 中的完全合格域名相匹配,比如 host.example.com[了解主机名字][4])。
>
> 注意:本指南为了你“复制粘贴”友好。需要自定义的任何值都声明为一个 MY_* 变量,在你运行剩余命令之前,你可能需要调整它。如果你注销之后,变量的赋值将被清除。
>
> 注意Fedora 28 Server 在默认情况下往往会转储大量的日志到控制台上。你可以通过运行命令sysctl -w kernel.printk=0 去禁用控制台日志输出。
接下来,我们需要在我们的服务器上配置一个静态网络地址。运行下面的一系列命令将找到并重新配置你的默认网络连接:
```javascript
$ MY_DNS1=192.0.2.91
$ MY_DNS2=192.0.2.92
$ MY_IP=192.0.2.158
$ MY_PREFIX=24
$ MY_GATEWAY=192.0.2.254
$ DEFAULT_DEV=$(ip route show default | awk '{print $5}')
$ DEFAULT_CON=$(nmcli d show $DEFAULT_DEV | sed -n '/^GENERAL.CONNECTION:/s!.*:\s*!! p')
$ nohup bash << END
nmcli con mod "$DEFAULT_CON" connection.id "$DEFAULT_DEV"
nmcli con mod "$DEFAULT_DEV" connection.interface-name "$DEFAULT_DEV"
nmcli con mod "$DEFAULT_DEV" ipv4.method disabled
nmcli con up "$DEFAULT_DEV"
nmcli con add con-name br0 ifname br0 type bridge
nmcli con mod br0 bridge.stp no
nmcli con mod br0 ipv4.dns $MY_DNS1,$MY_DNS2
nmcli con mod br0 ipv4.addresses $MY_IP/$MY_PREFIX
nmcli con mod br0 ipv4.gateway $MY_GATEWAY
nmcli con mod br0 ipv4.method manual
nmcli con up br0
nmcli con add con-name br0-slave0 ifname "$DEFAULT_DEV" type bridge-slave master br0
nmcli con up br0-slave0
END
```
> 注意:上面最后的一组命令被封装到一个 “nohup” 脚本中,因为它将临时禁用网络。这个 nohup 命令将允许 nmcli 命令去完成运行,直到你的 SSH 连接断开。注意,连接恢复可能需要 10 秒左右的时间,如果你改变了服务器 IP 地址,你将需要重新启动一个新的 SSH 连接。
>
> 注意:上面的网络配置在默认的连接之上创建了一个 [网桥][5],这样我们在后面的测试中就可以直接运行一个虚拟机实例。如果你不想在这台服务器上去直接测试网络引导镜像,你可以跳过创建网桥的命令,并直接在你的默认网络连接上配置静态 IP 地址。
### 安装和配置 NFS4
从安装 nfs-utils 包开始:
```
$ dnf install -y nfs-utils
```
为发布 NFS 去创建一个顶级的 [伪文件系统][6],然后在你的网络上共享它:
```javascript
$ MY_SUBNET=192.0.2.0
$ mkdir /export
$ echo "/export -fsid=0,ro,sec=sys,root_squash $MY_SUBNET/$MY_PREFIX" > /etc/exports
```
SELinux 将干扰网络引导服务器的运行。在本教程中我们将不涉及为它配置例外的部分,因此我们直接禁用它:
```javascript
$ sed -i '/GRUB_CMDLINE_LINUX/s/"$/ audit=0 selinux=0"/' /etc/default/grub
$ grub2-mkconfig -o /boot/grub2/grub.cfg
$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
$ setenforce 0
```
> 注意:编辑 grub 命令行应该是不需要的,但在测试过程中发现,简单地编辑 /etc/sysconfig/selinux 被证明重启后是无效的,因此再次确保设置了 “selinux=0” 标志。
现在,在本地防火墙中为 NFS 服务添加一个例外,然后启动 NFS 服务:
```javascript
$ firewall-cmd --add-service nfs
$ firewall-cmd --runtime-to-permanent
$ systemctl enable nfs-server.service
$ systemctl start nfs-server.service
```
### 创建网络引导镜像
现在我们的 NFS 服务器已经启动运行了,我们需要为它提供一个操作系统镜像,以便于它提供给客户端计算机。我们将从一个非常小的镜像开始,等一切顺利之后再添加。
首先,创建一个存放我们镜像的新目录:
```
$ mkdir /fc28
```
使用 “dnf” 命令在新目录下用几个基础包去构建镜像:
```javascript
$ dnf -y --releasever=28 --installroot=/fc28 install fedora-release systemd passwd rootfiles sudo dracut dracut-network nfs-utils vim-minimal dnf
```
在上面的命令中省略了很重要的 “kernel” 包。在它们被安装完成之前,我们需要去调整一下 “initramfs” 镜像中包含的驱动程序集“kernel” 首次安装时将自动构建这个镜像。尤其是,我们需要禁用 “hostonly” 模式,以便于 initramfs 镜像能够在各种硬件平台上正常工作,并且我们还需要添加对网络和 NFS 的支持:
```javascript
$ echo 'hostonly=no' > /fc28/etc/dracut.conf.d/hostonly.conf
$ echo 'add_dracutmodules+=" network nfs "' > /fc28/etc/dracut.conf.d/netboot.conf
```
现在,安装 kernel
```javascript
$ dnf -y --installroot=/fc28 install kernel
```
设置一个阻止 kernel 被更新的规则:
```javascript
$ echo 'exclude=kernel-*' >> /fc28/etc/dnf/dnf.conf
```
设置 locale
```javascript
$ echo 'LANG="en_US.UTF-8"' > /fc28/etc/locale.conf
```
> 注意:如果 locale 没有正确配置,一些程序(如 GNOME Terminal将无法正常工作。
root 用户密码留空:
```javascript
$ sed -i 's/^root:\*/root:/' /fc28/etc/shadow
```
设置客户端的主机名字:
```javascript
$ MY_CLIENT_HOSTNAME=client-01.example.edu
$ echo $MY_CLIENT_HOSTNAME > /fc28/etc/hostname
```
禁用控制台日志输出:
```javascript
$ echo 'kernel.printk = 0 4 1 7' > /fc28/etc/sysctl.d/00-printk.conf
```
定义网络引导镜像中的本地 “liveuser” 用户:
```javascript
$ echo 'liveuser:x:1000:1000::/home/liveuser:/bin/bash' >> /fc28/etc/passwd
$ echo 'liveuser::::::::' >> /fc28/etc/shadow
$ echo 'liveuser:x:1000:' >> /fc28/etc/group
$ echo 'liveuser:!::' >> /fc28/etc/gshadow
```
在 sudo 中启用 “liveuser”
```javascript
$ echo 'liveuser ALL=(ALL) NOPASSWD: ALL' > /fc28/etc/sudoers.d/liveuser
```
启用自动 home 目录创建:
```livescript
$ dnf install -y --installroot=/fc28 authselect oddjob-mkhomedir
$ echo 'dirs /home' > /fc28/etc/rwtab.d/home
$ chroot /fc28 authselect select sssd with-mkhomedir --force
$ chroot /fc28 systemctl enable oddjobd.service
```
由于多个客户端将会同时挂载我们的镜像,我们需要去配置镜像工作在只读模式中:
```livescript
$ sed -i 's/^READONLY=no$/READONLY=yes/' /fc28/etc/sysconfig/readonly-root
```
配置日志输出到内存而不是持久存储中:
```livescript
$ sed -i 's/^#Storage=auto$/Storage=volatile/' /fc28/etc/systemd/journald.conf
```
配置 DNS
```livescript
$ MY_DNS1=192.0.2.91
$ MY_DNS2=192.0.2.92
$ cat << END > /fc28/etc/resolv.conf
nameserver $MY_DNS1
nameserver $MY_DNS2
END
```
解决编写本教程时存在的只读 root 挂载 bug[BZ1542567][7]
```livescript
$ echo 'dirs /var/lib/gssproxy' > /fc28/etc/rwtab.d/gssproxy
$ cat << END > /fc28/etc/rwtab.d/systemd
dirs /var/lib/systemd/catalog
dirs /var/lib/systemd/coredump
END
```
最后,为我们镜像创建 NFS 文件系统,并将它共享到我们的子网中:
```livescript
$ mkdir /export/fc28
$ echo '/fc28 /export/fc28 none bind 0 0' >> /etc/fstab
$ mount /export/fc28
$ echo "/export/fc28 -ro,sec=sys,no_root_squash $MY_SUBNET/$MY_PREFIX" > /etc/exports.d/fc28.exports
$ exportfs -vr
```
### 创建引导加载器
现在,我们已经有了可以进行网络引导的操作系统,我们需要一个引导加载器去从客户端系统上启动它。在本教程中我们使用的是 [iPXE][8].
> 注意:本节和接下来的节 — 使用 QEMU 测试 — 能在另外一台单独的计算机上来完成;它们不需要在网络引导服务器上来运行。
安装 git 并使用它去下载 iPXE
```livescript
$ dnf install -y git
$ git clone http://git.ipxe.org/ipxe.git $HOME/ipxe
```
现在我们需要去为我们的引导加载器创建一个指定的启动脚本:
```livescript
$ cat << 'END' > $HOME/ipxe/init.ipxe
#!ipxe
prompt --key 0x02 --timeout 2000 Press Ctrl-B for the iPXE command line... && shell ||
dhcp || exit
set prefix file:///linux
chain ${prefix}/boot.cfg || exit
END
```
启动 “file” 下载协议:
```livescript
$ echo '#define DOWNLOAD_PROTO_FILE' > $HOME/ipxe/src/config/local/general.h
```
安装 C 编译器以及相关的工具和库:
```livescript
$ dnf groupinstall -y "C Development Tools and Libraries"
```
构建引导加载器:
```livescript
$ cd $HOME/ipxe/src
$ make clean
$ make bin-x86_64-efi/ipxe.efi EMBED=../init.ipxe
```
记下新编译的引导加载器的存储位置。我们将在接下来的节中用到它:
```livescript
$ IPXE_FILE="$HOME/ipxe/src/bin-x86_64-efi/ipxe.efi"
```
### 用 QEMU 测试
这一节是可选的,但是你需要去复制下面显示在物理机器上的 [EFI 系统分区][9] 的布局,在网络引导时需要去配置它们。
> 注意:如果你想实现一个完全的无盘系统,你也可以复制那个文件到一个 TFTP 服务器,然后从 DHCP 上引用那台服务器。
为了使用 QEMU 去测试我们的引导加载器,我们继续去创建一个仅包含一个 EFI 系统分区和我们的启动文件的、很小的磁盘镜像。
从创建 EFI 系统分区所需要的目录布局开始,然后把我们在前面节中创建的引导加载器复制进去:
```livescript
$ mkdir -p $HOME/esp/efi/boot
$ mkdir $HOME/esp/linux
$ cp $IPXE_FILE $HOME/esp/efi/boot/bootx64.efi
```
下面的命令将识别我们的引导加载器镜像正在使用的内核版本,并将它保存到一个变量中,以备后续的配置命令去使用它:
```livescript
$ DEFAULT_VER=$(ls -c /fc28/lib/modules | head -n 1)
```
定义我们的客户端计算机将使用的引导配置:
```livescript
$ MY_DNS1=192.0.2.91
$ MY_DNS2=192.0.2.92
$ MY_NFS4=server-01.example.edu
$ cat << END > $HOME/esp/linux/boot.cfg
#!ipxe
kernel --name kernel.efi \${prefix}/vmlinuz-$DEFAULT_VER initrd=initrd.img ro ip=dhcp rd.peerdns=0 nameserver=$MY_DNS1 nameserver=$MY_DNS2 root=nfs4:$MY_NFS4:/fc28 console=tty0 console=ttyS0,115200n8 audit=0 selinux=0 quiet
initrd --name initrd.img \${prefix}/initramfs-$DEFAULT_VER.img
boot || exit
END
```
> 注意:上面的引导脚本展示了如何使用 iPXE 去网络引导 Linux 的最小示例。还可以做更多更复杂的配置。值得注意的是iPXE 支持交互式引导菜单,它可以让你配置默认选项和超时时间。比如,一个更高级一点 iPXE 脚本可以默认从本地磁盘引导一个操作系统,如果在倒计时结束之前用户按下了一个键,才会去网络引导一个操作系统。
复制 Linux 内核并分配 initramfs 给 EFI 系统分区:
```livescript
$ cp $(find /fc28/lib/modules -maxdepth 2 -name 'vmlinuz' | grep -m 1 $DEFAULT_VER) $HOME/esp/linux/vmlinuz-$DEFAULT_VER
$ cp $(find /fc28/boot -name 'init*' | grep -m 1 $DEFAULT_VER) $HOME/esp/linux/initramfs-$DEFAULT_VER.img
```
我们最终的目录布局应该看起来像下面的样子:
```livescript
esp
├── efi
│   └── boot
│   └── bootx64.efi
└── linux
├── boot.cfg
├── initramfs-4.18.18-200.fc28.x86_64.img
└── vmlinuz-4.18.18-200.fc28.x86_64
```
使用 QEMU 去使用我们的 EFI 系统分区,我们需要去创建一个小的 “uefi.img” 磁盘镜像来包含它,然后将它连接到 QEMU 作为主引导驱动器。
开始安装必需的工具:
```livescript
$ dnf install -y parted dosfstools
```
现在创建 “uefi.img” 文件,并将 “esp” 目录中文件复制进去:
```livescript
$ ESP_SIZE=$(du -ks $HOME/esp | cut -f 1)
$ dd if=/dev/zero of=$HOME/uefi.img count=$((${ESP_SIZE}+5000)) bs=1KiB
$ UEFI_DEV=$(losetup --show -f $HOME/uefi.img)
$ parted ${UEFI_DEV} -s mklabel gpt mkpart EFI FAT16 1MiB 100% toggle 1 boot
$ mkfs -t msdos ${UEFI_DEV}p1
$ mkdir -p $HOME/mnt
$ mount ${UEFI_DEV}p1 $HOME/mnt
$ cp -r $HOME/esp/* $HOME/mnt
$ umount $HOME/mnt
$ losetup -d ${UEFI_DEV}
```
> 注意:在物理计算机上,你只需要从 “esp” 目录中复制文件到计算机上已存在的 EFI 系统分区中。你不需要使用 “uefi.img” 文件去引导物理计算机。
>
> 注意:在一个物理计算机上,如果文件名已存在,你可以重命名 “bootx64.efi” 文件,如果你重命名了它,就需要去编辑计算机的 BIOS 设置,并添加重命令后的 efi 文件到引导列表中。
接下来我们需要去安装 qemu 包:
```livescript
$ dnf install -y qemu-system-x86
```
允许 QEMU 访问我们在本教程“初始化配置”一节中创建的网桥:
```livescript
$ echo 'allow br0' > /etc/qemu/bridge.conf
```
创建一个 “OVMF_VARS.fd” 镜像的副本去保存我们虚拟机的持久 BIOS 配置:
```livescript
$ cp /usr/share/edk2/ovmf/OVMF_VARS.fd $HOME
```
现在,启动虚拟机:
```livescript
$ qemu-system-x86_64 -machine accel=kvm -nographic -m 1024 -drive if=pflash,format=raw,unit=0,file=/usr/share/edk2/ovmf/OVMF_CODE.fd,readonly=on -drive if=pflash,format=raw,unit=1,file=$HOME/OVMF_VARS.fd -drive if=ide,format=raw,file=$HOME/uefi.img -net bridge,br=br0 -net nic,model=virtio
```
如果一切顺利,你将看到类似下图所示的结果:
![][10]
你可以使用 “shutdown” 命令关闭虚拟机回到我们的服务器上:
```livescript
$ sudo shutdown -h now
```
> 注意:如果出现了错误或虚拟机挂住了,你可能需要启动一个新的 SSH 会话去连接服务器,使用 “kill” 命令去终止 “qemu-system-x86_64” 进程。
### 镜像中添加包
镜像中添加包应该是一个很简单的问题,在服务器上 chroot 进镜像,然后运行 “dnf install <package_name>”。
在网络引导镜像中并不限制你能安装什么包。一个完整的图形化安装应该能够完美地工作。
下面是一个如何将最小化安装的网络引导镜像变成完整的图形化安装的示例:
```livescript
$ 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 -y groupinstall "Fedora Workstation"
$ dnf -y remove gnome-initial-setup
$ systemctl disable sshd.service
$ systemctl enable gdm.service
$ systemctl set-default graphical.target
$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
$ logout
$ for i in run sys proc dev/shm dev/pts dev; do umount /fc28/$i; done
```
可选,你可能希望去启用 “liveuser” 用户的自动登陆:
```livescript
$ sed -i '/daemon/a AutomaticLoginEnable=true' /fc28/etc/gdm/custom.conf
$ sed -i '/daemon/a AutomaticLogin=liveuser' /fc28/etc/gdm/custom.conf
```
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/how-to-build-a-netboot-server-part-1/
作者:[Gregory Bartholomew][a]
选题:[lujun9972][b]
译者:[qhwdw](https://github.com/qhwdw)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/glb/
[b]: https://github.com/lujun9972
[1]: https://en.wikipedia.org/wiki/Network_booting
[2]: https://dl.fedoraproject.org/pub/fedora/linux/releases/28/Server/x86_64/iso/
[3]: https://fedoramagazine.org/wp-content/uploads/2018/11/installation-summary-1024x768.png
[4]: https://docs.fedoraproject.org/en-US/Fedora/25/html/Networking_Guide/ch-Configure_Host_Names.html#sec_Understanding_Host_Names
[5]: https://en.wikipedia.org/wiki/Bridging_(networking)
[6]: https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s3-nfs-server-config-exportfs-nfsv4.html
[7]: https://bugzilla.redhat.com/show_bug.cgi?id=1542567
[8]: https://ipxe.org/
[9]: https://en.wikipedia.org/wiki/EFI_system_partition
[10]: https://fedoramagazine.org/wp-content/uploads/2018/11/netboot-liveuser-1024x641.png