mirror of
https://github.com/clearlinux/clear-linux-documentation.git
synced 2026-08-24 08:48:15 +00:00
Merge branch 'pxe' into 'master'
Network Boot Updating network boot documentation to include tested and verified configurations on the latest version of Clear. See merge request !147
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
+353
-576
@@ -1,637 +1,414 @@
|
||||
.. _network_boot:
|
||||
|
||||
Network booting
|
||||
################
|
||||
|
||||
Network booting is an important feature that every data center should have;
|
||||
it can be used, among other things, to install an operating system. To do this,
|
||||
a :abbr:`Pre-boot eXecution Environment (PXE)` is defined upon a foundation of
|
||||
industry-standard Internet protocols and services, namely TCP/IP, DHCP, and
|
||||
`TFTP`_.
|
||||
|
||||
Clear Linux* Project for Intel® Architecture uses UEFI to boot, so your target
|
||||
machine should be UEFI-capable. At present, the UEFI binary is not signed, so
|
||||
be sure to disable secure boot.
|
||||
|
||||
Network Booting
|
||||
###############
|
||||
|
||||
Network Setup Options
|
||||
=====================
|
||||
|CLOSIA| can boot from a :abbr:`PXE (pre-boot execution environment)`. PXE
|
||||
is an industry standard which describes the client-server interaction to
|
||||
network boot software using the DHCP and TFTP protocols. One possible use of
|
||||
this environment is to automatically install an operating system.
|
||||
|
||||
There are two basic network configurations:
|
||||
The PXE extension known as `iPXE`_\* adds support for additional protocols
|
||||
such as HTTP, iSCIS, :abbr:`AoE (ATA over Ethernet)`, and
|
||||
:abbr:`FCoE (Fiber Channel over Ethernet)`. iPXE can also be used to enable
|
||||
network-booting computers which lack built-in PXE support.
|
||||
|
||||
* Place all of your nodes behind a :abbr:`Network Address Traversal (NAT)`, or
|
||||
* Connect one node to your regular network and the other to a switch
|
||||
connecting all your machines. This option requires at least two network
|
||||
interfaces (dual NIC).
|
||||
This guide covers how to boot |CL| with iPXE using
|
||||
:abbr:`NAT (network address translation)`.
|
||||
|
||||
Note that lack of (or incorrectly-configured) NAT can expose your cluster to external
|
||||
networks. NAT allows you to control the traffic that goes to the external network.
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
A script for NAT setup can be found on this `gist`_. Be sure
|
||||
to export the DOMAIN and DNS variables to be the domain name of your internal
|
||||
network (example.com) and whatever DNS servers you want to use (8.8.8.8 and
|
||||
8.8.4.4 DNS can work for some situations).
|
||||
Before booting with iPXE, ensure the following preparations have been
|
||||
made:
|
||||
|
||||
* Your PXE server has an ethernet/LAN boot option.
|
||||
* Your PXE server has at least two network adapters.
|
||||
* Your PXE server is connected to a public network.
|
||||
* Your PXE server and PXE clients are connected to a switch on a private
|
||||
network.
|
||||
* Your PXE server has the secure boot option disabled.
|
||||
|
||||
Network Topologies
|
||||
==================
|
||||
.. note::
|
||||
|
||||
Dual NIC
|
||||
--------
|
||||
The secure boot option must be disabled because the UEFI binaries used to
|
||||
boot the |CLOSIA| are not signed.
|
||||
|
||||
.. code-block:: console
|
||||
The required computer and network setup are depicted in figure 1.
|
||||
|
||||
+----------+
|
||||
| External |
|
||||
| Network |
|
||||
+----------+-----------+----------------+----------------+
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
| Network | | PXE | | PXE | | PXE |
|
||||
| Boot | | Boot | | Boot | | Boot |
|
||||
| Server | | Client | | Client | | Client |
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+----------------+----------------+
|
||||
| Internal |
|
||||
| Network |
|
||||
+----------+
|
||||
.. figure:: _static/images/network-boot-setup.png
|
||||
:alt: NAT network topology
|
||||
|
||||
NAT
|
||||
---
|
||||
Figure 1: NAT network topology
|
||||
|
||||
.. code-block:: console
|
||||
Configuration
|
||||
=============
|
||||
|
||||
+----------+
|
||||
| External |
|
||||
| Network |
|
||||
+----------+
|
||||
|
|
||||
|
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
| Network | | PXE | | PXE | | PXE |
|
||||
| Boot | | Boot | | Boot | | Boot |
|
||||
| Server | | Client | | Client | | Client |
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+----------------+----------------+
|
||||
| Internal |
|
||||
| Network |
|
||||
+----------+
|
||||
The configuration to boot using iPXE has been automated with the
|
||||
:file:`configure-ipxe.sh` script which ran during the installation of the
|
||||
`Ister Cloud Init Service`_, thus quickly enabling a bulk provisioning
|
||||
setup. Before running the configuration script, modify
|
||||
:file:`parameters.conf` with your specific configurations.
|
||||
|
||||
Dual-NIC setup information will be added in the future. This guide currently
|
||||
only covers NAT setup.
|
||||
Figure 2 depicts the information flow enabled by the configuration script.
|
||||
|
||||
.. figure:: _static/images/network-boot-flow.png
|
||||
:alt: PXE information flow
|
||||
|
||||
PXE + iPXE
|
||||
===========
|
||||
Figure 2: PXE information flow
|
||||
|
||||
To retrieve data through other protocols such as HTTP, iSCSI, :abbr:`ATA over Ethernet
|
||||
(AoE)`, or :abbr:`Fiber Channel over Ethernet (FCoE)`, an open source network boot
|
||||
firmware called **iPXE** was created. iPXE provides a full PXE implementation,
|
||||
enhanced with additional features. It can be used to enable network booting from
|
||||
computers that lack built-in PXE support.
|
||||
#. Define the variables used to parameterize the configuration of an iPXE
|
||||
boot.
|
||||
|
||||
Clear Linux* Project for Intel Architecture can be configured to do network
|
||||
booting via HTTP, with the help of iPXE. The following sets up an iPXE
|
||||
environment using Clear Linux OS for Intel Architecture; these configuration
|
||||
options can also be applied elsewhere.
|
||||
.. code-block:: console
|
||||
|
||||
web_root=/var/www
|
||||
ipxe_root=$web_root/ipxe
|
||||
tftp_root=/srv/tftp
|
||||
|
||||
Step 1
|
||||
------
|
||||
external_iface=eno1
|
||||
internal_iface=eno2
|
||||
pxe_subnet=192.168.1
|
||||
pxe_internal_ip=$pxe_subnet.1
|
||||
pxe_subnet_mask_ip=255.255.255.0
|
||||
pxe_subnet_bitmask=24
|
||||
|
||||
Add the ``pxe-server`` bundle to your system; this has all the bits to run a PXE
|
||||
server.
|
||||
#. Add the ``pxe-server`` bundle to your system. This bundle has all the
|
||||
packages needed run a PXE server.
|
||||
|
||||
.. code-block:: console
|
||||
.. code-block:: console
|
||||
|
||||
# swupd bundle-add pxe-server
|
||||
swupd bundle-add pxe-server
|
||||
|
||||
Step 2
|
||||
------
|
||||
#. Create an iPXE hosting directory.
|
||||
|
||||
Configure the ``tftpd`` service using ``dnsmasq``. To do this, populate the
|
||||
:file:`/etc/dnsmasq.conf` file with the following entries:
|
||||
.. code-block:: console
|
||||
|
||||
.. code-block:: console
|
||||
rm -rf $ipxe_root
|
||||
mkdir -p $ipxe_root
|
||||
|
||||
# cat << EOF > /etc/dnsmasq.conf
|
||||
enable-tftp
|
||||
tftp-root=/srv/tftp/
|
||||
EOF
|
||||
#. Download the latest network-bootable release of |CL|, and extract the
|
||||
files.
|
||||
|
||||
Step 3
|
||||
-------
|
||||
.. code-block:: console
|
||||
|
||||
Copy the :file:`/usr/share/ipxe/undionly.kpxe` (legacy) and
|
||||
:file:`/usr/share/ipxe/ipxe-x86_64.efi` files, and place them in your TFTP
|
||||
directory.
|
||||
curl -o /tmp/clear-pxe.tar.xz
|
||||
https://download.clearlinux.org/current/clear-$(curl
|
||||
https://download.clearlinux.org/latest)-pxe.tar.xz
|
||||
tar -xJf /tmp/clear-pxe.tar.xz -C $ipxe_root
|
||||
ln -sf $(ls $ipxe_root | grep 'org.clearlinux.*') $ipxe_root/linux
|
||||
|
||||
You can also download the ``undionly.kpxe`` (legacy) and ``ipxe.efi`` (EFI)
|
||||
files from the `iPXE website`_.
|
||||
.. important::
|
||||
|
||||
.. code-block:: console
|
||||
Ensure that the initial ramdisk file is named :file:`initrd` and
|
||||
the kernel file is named :file:`linux`, which is a symbolic link to the
|
||||
actual kernel file.
|
||||
|
||||
# mkdir /srv/tftp/
|
||||
# cp /usr/share/ipxe/undionly.kpxe /srv/tftp/undionly.kpxe
|
||||
# cp /usr/share/ipxe/ipxe-x86_64.efi /srv/tftp/ipxe.efi
|
||||
#. Create an iPXE boot script. During an iPXE boot, the iPXE boot script
|
||||
directs the PXE client to the files needed to network-boot the latest
|
||||
release. Use the names given to the initial ramdisk and kernel
|
||||
files.
|
||||
|
||||
**Note**: If booting with a 32-bit UEFI, copy the
|
||||
:file:`/usr/share/ipxe/ipxe-i386.efi` file instead.
|
||||
.. code-block:: console
|
||||
|
||||
Step 4
|
||||
-------
|
||||
cat > $ipxe_root/ipxe_boot_script.txt << EOF
|
||||
#!ipxe
|
||||
kernel linux quiet init=/usr/lib/systemd/systemd-bootchart
|
||||
initcall_debug tsc=reliable no_timer_check noreplace-smp rw
|
||||
initrd=initrd
|
||||
initrd initrd
|
||||
boot
|
||||
EOF
|
||||
|
||||
Start the dnsmasq service with:
|
||||
#. The ``pxe-server`` bundle contains a lightweight web-server known as
|
||||
``nginx``. Create a configuration file for ``nginx`` to serve the latest
|
||||
release to PXE clients.
|
||||
|
||||
.. code-block:: console
|
||||
.. code-block:: console
|
||||
|
||||
# systemctl start dnsmasq.service
|
||||
mkdir -p /etc/nginx
|
||||
cat > /etc/nginx/nginx.conf << EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
location / {
|
||||
root $ipxe_root;
|
||||
autoindex on;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
Step 5
|
||||
-------
|
||||
#. Start ``nginx`` and enable startup on boot.
|
||||
|
||||
The kernel (linux), initramfs (initrd) and the iPXE scripts are transported via
|
||||
HTTP. Download the Linux kernel and initrd files, and put them in the http
|
||||
server root ``/var/www/pxe/``.
|
||||
.. code-block:: console
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# mkdir -p /var/www/pxe/
|
||||
# version=$(curl https://download.clearlinux.org/latest)
|
||||
# curl -o /var/www/pxe/clear-${version}-pxe.tar.xz https://download.clearlinux.org/current/clear-${version}-pxe.tar.xz
|
||||
# tar -xJf /var/www/pxe/clear-${version}-pxe.tar.xz -C /var/www/pxe/ && rm /var/www/pxe/clear-${version}-pxe.tar.xz
|
||||
# unset version
|
||||
|
||||
Step 6
|
||||
-------
|
||||
|
||||
Create an iPXE script named ``ipxe_boot_script.txt`` under the http server root
|
||||
:file:`/var/www/pxe/`.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# cat << EOF > /var/www/pxe/ipxe_boot_script.txt
|
||||
#!ipxe
|
||||
|
||||
kernel linux quiet rdinit=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp rw initrd=initrd
|
||||
initrd initrd
|
||||
boot
|
||||
EOF
|
||||
|
||||
If your kernel is not already named ``linux``, either rename the kernel or create a symlink.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# kernel=$(find /var/www/pxe/ -name 'org.clearlinux.*')
|
||||
# ln -s ${kernel} /var/www/pxe/linux
|
||||
# unset kernel
|
||||
|
||||
Step 7
|
||||
-------
|
||||
|
||||
Create a configuration file for the http service (nginx in this example) to
|
||||
serve the kernel, initramfs, and ipxe_boot_script in
|
||||
:file:`/etc/nginx/nginx.conf` with the following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# mkdir /etc/nginx/
|
||||
# cat << EOF > /etc/nginx/nginx.conf
|
||||
server {
|
||||
listen 80;
|
||||
server_name hostname;
|
||||
server_name_in_redirect off;
|
||||
location / {
|
||||
root /var/www/pxe;
|
||||
autoindex on;
|
||||
index index.html index.htm;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
Step 8
|
||||
-------
|
||||
|
||||
Start the nginx service:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# systemctl start nginx.service
|
||||
|
||||
Step 9
|
||||
-------
|
||||
|
||||
To use PXE chainloading, set up ISC DHCPD to first assign ``undionly.kpxe`` to any
|
||||
legacy PXE clients, and to then assign boot configuration to iPXE clients. Do this
|
||||
by telling ISC DHCPD to make the assignments based on the DHCP user class. Here’s
|
||||
one way to do this using the :file:`/etc/dhcpd.conf` file:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
allow booting;
|
||||
allow bootp;
|
||||
DHCPDARGS="interface";
|
||||
|
||||
# Set up a class to assign an "IP only" to devices attempting network boot.
|
||||
class "pxeclients" {
|
||||
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
|
||||
next-server 192.168.1.1;
|
||||
if exists user-class and option user-class = "iPXE" {
|
||||
filename "http://my.web.server/ipxe_boot_script.txt";
|
||||
} elsif exists client-arch and option client-arch = 9 {
|
||||
# client-arch = 9 (64-bit EFI)
|
||||
filename "ipxe.efi";
|
||||
} else {
|
||||
# client-arch = 0 (Standard PC BIOS)
|
||||
filename "undionly.kpxe";
|
||||
}
|
||||
}
|
||||
|
||||
# Private subnet, in case you aren't able to run your own network wide DHCP service.
|
||||
# Works when the machine you are network booting has two network interfaces,
|
||||
# one connected to the private PXE boot network and the other connected to an external
|
||||
# network.
|
||||
subnet 192.168.0.0 netmask 255.255.0.0 {
|
||||
pool {
|
||||
# These IPs will only be asigned to PXE clients
|
||||
allow members of "pxeclients";
|
||||
range 192.168.1.150 192.168.1.254;
|
||||
}
|
||||
|
||||
# If you are not doing the NAT setup do not add the following to this
|
||||
# section. These IPs will be assigned to the hosts when they boot and
|
||||
# after they have been installed
|
||||
range 192.168.1.2 192.168.1.149;
|
||||
default-lease-time 600;
|
||||
max-lease-time 7200;
|
||||
option subnet-mask 255.255.0.0;
|
||||
option broadcast-address 192.168.255.255;
|
||||
option routers 192.168.1.1;
|
||||
# If your external network runs its own DNS servers then replace the
|
||||
# following with those
|
||||
option domain-name-servers 8.8.8.8, 8.8.4.4;
|
||||
# You can leave this change this or remove it. It changes the FQDNs
|
||||
# of your hosts. So host bob can be accessed (from this machine) at
|
||||
# bob.example.com
|
||||
option domain-name "example.com";
|
||||
}
|
||||
|
||||
This ensures that either iPXE image (``undionly.kpxe`` for BIOS or ``ipxe.efi``
|
||||
for EFI) is handed out only when the DHCP request comes from a legacy PXE client
|
||||
or from a UEFI client, respectfully. Once iPXE loads, the DHCP server will direct it to
|
||||
boot from options configured in your ``http://my.web.server/real_boot_script.txt``
|
||||
file.
|
||||
|
||||
Note.
|
||||
|
||||
``192.168.1.1`` is set to the address your TFTP server is using.
|
||||
|
||||
``my.web.server`` is set to the address your web server is using.
|
||||
|
||||
``DHCPDARGS`` is set to the interface you are using.
|
||||
|
||||
If you are doing a NAT setup then you need to set ``interface`` to the interface
|
||||
connected to the internal network.
|
||||
|
||||
Step 10
|
||||
-------
|
||||
|
||||
There are several DHCP options specific to `iPXE`_ which are
|
||||
not recognized by the standard ISC DHCPD installation. To add suport for these
|
||||
options, add the following to the top of your :file:`/etc/dhcpd.conf`:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
###################################################
|
||||
# iPXE-specific options #
|
||||
# Source: http://www.ipxe.org/howto/dhcpd #
|
||||
###################################################
|
||||
option space ipxe;
|
||||
option client-arch code 93 = unsigned integer 16;
|
||||
option ipxe-encap-opts code 175 = encapsulate ipxe;
|
||||
option ipxe.priority code 1 = signed integer 8;
|
||||
option ipxe.keep-san code 8 = unsigned integer 8;
|
||||
option ipxe.skip-san-boot code 9 = unsigned integer 8;
|
||||
option ipxe.syslogs code 85 = string;
|
||||
option ipxe.cert code 91 = string;
|
||||
option ipxe.privkey code 92 = string;
|
||||
option ipxe.crosscert code 93 = string;
|
||||
option ipxe.no-pxedhcp code 176 = unsigned integer 8;
|
||||
option ipxe.bus-id code 177 = string;
|
||||
option ipxe.bios-drive code 189 = unsigned integer 8;
|
||||
option ipxe.username code 190 = string;
|
||||
option ipxe.password code 191 = string;
|
||||
option ipxe.reverse-username code 192 = string;
|
||||
option ipxe.reverse-password code 193 = string;
|
||||
option ipxe.version code 235 = string;
|
||||
option iscsi-initiator-iqn code 203 = string;
|
||||
# Feature indicators
|
||||
option ipxe.pxeext code 16 = unsigned integer 8;
|
||||
option ipxe.iscsi code 17 = unsigned integer 8;
|
||||
option ipxe.aoe code 18 = unsigned integer 8;
|
||||
option ipxe.http code 19 = unsigned integer 8;
|
||||
option ipxe.https code 20 = unsigned integer 8;
|
||||
option ipxe.tftp code 21 = unsigned integer 8;
|
||||
option ipxe.ftp code 22 = unsigned integer 8;
|
||||
option ipxe.dns code 23 = unsigned integer 8;
|
||||
option ipxe.bzimage code 24 = unsigned integer 8;
|
||||
option ipxe.multiboot code 25 = unsigned integer 8;
|
||||
option ipxe.slam code 26 = unsigned integer 8;
|
||||
option ipxe.srp code 27 = unsigned integer 8;
|
||||
option ipxe.nbi code 32 = unsigned integer 8;
|
||||
option ipxe.pxe code 33 = unsigned integer 8;
|
||||
option ipxe.elf code 34 = unsigned integer 8;
|
||||
option ipxe.comboot code 35 = unsigned integer 8;
|
||||
option ipxe.efi code 36 = unsigned integer 8;
|
||||
option ipxe.fcoe code 37 = unsigned integer 8;
|
||||
option ipxe.vlan code 38 = unsigned integer 8;
|
||||
option ipxe.menu code 39 = unsigned integer 8;
|
||||
option ipxe.sdi code 40 = unsigned integer 8;
|
||||
option ipxe.nfs code 41 = unsigned integer 8;
|
||||
|
||||
Step 11
|
||||
-------
|
||||
|
||||
Create an empty :file:`/var/db/dhcpd.leases` file.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# mkdir /var/db/
|
||||
# touch /var/db/dhcpd.leases
|
||||
|
||||
Step 12
|
||||
-------
|
||||
|
||||
If you are doing the NAT setup skip this we will do it at the end.
|
||||
|
||||
Start the dhcp service:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# systemctl start dhcp4.service
|
||||
|
||||
Step 13
|
||||
-------
|
||||
|
||||
From here on out we are doing NAT specific steps. Set your external and
|
||||
internal network interface names to variables for convenience.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# export external_iface=eno0
|
||||
# export internal_iface=eno1
|
||||
|
||||
Disable auto-starting dhcp for all interfaces
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# mkdir -p /etc/systemd/network/
|
||||
# cd /etc/systemd/network/
|
||||
# ln -s /dev/null 80-dhcp.network
|
||||
|
||||
Set your external and internal network interfaces to behave accordingly. You
|
||||
may need to change the external.network if the external network is not going to
|
||||
assign this machine an IP via dhcp. The internal network address corresponds to
|
||||
the settings in dhcpd.conf
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# cat << EOF > 80-external-dynamic.network
|
||||
[Match]
|
||||
Name=$external_iface
|
||||
[Network]
|
||||
DHCP=yes
|
||||
EOF
|
||||
# cat << EOF > 80-internal-static.network
|
||||
[Match]
|
||||
Name=$internal_iface
|
||||
[Network]
|
||||
Address=192.168.1.1/16
|
||||
EOF
|
||||
|
||||
Step 14
|
||||
-------
|
||||
|
||||
Configure iptables to forward all traffic coming from inside the NAT to the
|
||||
external network. Without this swupd will not be able to connect to the
|
||||
internet.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# cat << EOF > ~/natrules
|
||||
*nat
|
||||
:PREROUTING ACCEPT [5077:516379]
|
||||
:INPUT ACCEPT [5054:514369]
|
||||
:OUTPUT ACCEPT [147:7526]
|
||||
:POSTROUTING ACCEPT [114:5508]
|
||||
:PROXY - [0:0]
|
||||
-A POSTROUTING -o $external_iface -j MASQUERADE
|
||||
COMMIT
|
||||
*filter
|
||||
:INPUT ACCEPT [338542:30287508]
|
||||
:FORWARD ACCEPT [168279:154877988]
|
||||
:OUTPUT ACCEPT [49875:536021461]
|
||||
-A FORWARD -i $external_iface -o $internal_iface -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A FORWARD -i $internal_iface -o $external_iface -j ACCEPT
|
||||
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
|
||||
COMMIT
|
||||
EOF
|
||||
# iptables-restore ~/natrules
|
||||
# for unitfile in $(cd /usr/lib/systemd/system/; ls ip*)
|
||||
do
|
||||
systemctl enable ${unitfile}
|
||||
systemctl start ${unitfile}
|
||||
done
|
||||
systemctl start nginx
|
||||
systemctl enable nginx
|
||||
|
||||
Tell the kernel to forward packets. Without this the above rules do nothing.
|
||||
#. The ``pxe-server`` bundle contains iPXE firmware images which allow
|
||||
computers without an iPXE implementation to perform an iPXE boot. Create a
|
||||
TFTP hosting directory and populate it with the iPXE firmware images.
|
||||
|
||||
.. code-block:: console
|
||||
.. code-block:: console
|
||||
|
||||
# echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
# echo net.ipv4.ip_forward=1 > /etc/sysctl.conf
|
||||
rm -rf $tftp_root
|
||||
mkdir -p $tftp_root
|
||||
ln -sf /usr/share/ipxe/ipxe-x86_64.efi $tftp_root/ipxe-x86_64.efi
|
||||
ln -sf /usr/share/ipxe/undionly.kpxe $tftp_root/undionly.kpxe
|
||||
|
||||
Step 15
|
||||
-------
|
||||
#. The ``pxe-server`` bundle contains a lightweight TFTP server known as
|
||||
``dnsmasq``. Create a configuration file for ``dnsmasq`` to serve iPXE
|
||||
firmware images to PXE clients over TFTP.
|
||||
|
||||
Restart all your networking. If you did something wrong then you may loose
|
||||
connection if you are working over ssh.
|
||||
.. code-block:: console
|
||||
|
||||
.. code-block:: console
|
||||
cat > /etc/dnsmasq.conf << EOF
|
||||
enable-tftp
|
||||
tftp-root=$tftp_root
|
||||
EOF
|
||||
|
||||
# systemctl restart systemd-networkd
|
||||
# systemctl restart dhcp4.service
|
||||
#. Enable ``dnsmasq`` to start automatically on boot.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
PXE + GRUB
|
||||
==========
|
||||
systemctl enable dnsmasq
|
||||
|
||||
Another option for network booting Clear Linux* OS for Intel Architecture is to
|
||||
use the GRUB bootloader to boot in UEFI mode. The bootloader will get its files
|
||||
over TFTP; it does not require having another service to host the network boot
|
||||
artifacts. The following sets up up a PXE using the GRUB bootloader environment
|
||||
and Clear Linux OS for Intel Architecture, but the configuration options should
|
||||
apply elsewhere.
|
||||
.. note::
|
||||
|
||||
First, add the ``pxe-server`` bundle to your system with:
|
||||
At this point in the configuration process, ``dnsmasq`` is only being
|
||||
enabled to start automatically on boot but it is not started because
|
||||
its DNS server conflicts with the DNS stub listener of
|
||||
``systemd-resolved``.
|
||||
|
||||
.. code-block:: console
|
||||
#. Set ``dnsmasq`` to listen on a dedicated IP address. PXE clients on the
|
||||
private network will use this IP address for DNS resolution. Disable
|
||||
the DNS stub listener included with ``systemd-resolved`` to avoid a
|
||||
conflict with the ``dnsmasq`` DNS server.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
mkdir -p /etc/systemd
|
||||
cat > /etc/systemd/resolved.conf << EOF
|
||||
[Resolve]
|
||||
DNSStubListener=no
|
||||
EOF
|
||||
|
||||
cat >> /etc/dnsmasq.conf << EOF
|
||||
listen-address=$pxe_internal_ip
|
||||
EOF
|
||||
|
||||
.. note::
|
||||
|
||||
``dnsmasq`` is a lightweight implementation of a DNS server, a DHCP
|
||||
server, and a TFTP server. For the purposes of this guide, the DHCP
|
||||
server included with ``dnsmasq`` is not being used.
|
||||
|
||||
.. important::
|
||||
|
||||
Using the ``dnsmasq`` DNS server allows ``systemd-resolved`` to
|
||||
dynamically update the list of DNS servers for the private network from
|
||||
the public network. This setup effectively creates a pass-through DNS
|
||||
server which relies on the DNS servers listed in ``/etc/resolv.conf``.
|
||||
|
||||
#. Start ``dnsmasq`` and avoid conflicts with ``systemd-resolved``.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
systemctl stop systemd-resolved
|
||||
systemctl restart dnsmasq
|
||||
systemctl start systemd-resolved
|
||||
|
||||
#. Assign a static IP address to the network adapter for the private network.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
mkdir -p /etc/systemd/network
|
||||
|
||||
ln -sf /dev/null /etc/systemd/network/80-dhcp.network
|
||||
|
||||
cat > /etc/systemd/network/80-external-dynamic.network << EOF
|
||||
[Match]
|
||||
Name=$external_iface
|
||||
[Network]
|
||||
DHCP=yes
|
||||
EOF
|
||||
|
||||
cat > /etc/systemd/network/80-internal-static.network << EOF
|
||||
[Match]
|
||||
Name=$internal_iface
|
||||
[Network]
|
||||
DHCP=no
|
||||
Address=$pxe_internal_ip/$pxe_subnet_bitmask
|
||||
EOF
|
||||
|
||||
systemctl restart systemd-networkd
|
||||
|
||||
.. note::
|
||||
|
||||
By default, ``systemd-networkd`` uses DHCP for all network adapters.
|
||||
This functionality must be disabled prior to assigning a static IP
|
||||
address. Consequently, DHCP functionality for the network adapter
|
||||
connected to the public network is also disabled. Thus, this functionality must be explicitly re-enabled for the network adapter.
|
||||
|
||||
#. The ``pxe-server`` bundle contains a full DHCP server implementation
|
||||
compliant with the specifications defined by the
|
||||
:abbr:`ISC (Internet Systems Consortium)` known as ``dhcpd``. Configure
|
||||
``dhcpd`` to dynamically allocate IP addresses to PXE clients on the
|
||||
private network.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cat > /etc/dhcpd.conf << EOF
|
||||
option space ipxe;
|
||||
option ipxe-encap-opts code 175 = encapsulate ipxe;
|
||||
option ipxe.priority code 1 = signed integer 8;
|
||||
option ipxe.keep-san code 8 = unsigned integer 8;
|
||||
option ipxe.skip-san-boot code 9 = unsigned integer 8;
|
||||
option ipxe.syslogs code 85 = string;
|
||||
option ipxe.cert code 91 = string;
|
||||
option ipxe.privkey code 92 = string;
|
||||
option ipxe.crosscert code 93 = string;
|
||||
option ipxe.no-pxedhcp code 176 = unsigned integer 8;
|
||||
option ipxe.bus-id code 177 = string;
|
||||
option ipxe.bios-drive code 189 = unsigned integer 8;
|
||||
option ipxe.username code 190 = string;
|
||||
option ipxe.password code 191 = string;
|
||||
option ipxe.reverse-username code 192 = string;
|
||||
option ipxe.reverse-password code 193 = string;
|
||||
option ipxe.version code 235 = string;
|
||||
option iscsi-initiator-iqn code 203 = string;
|
||||
option ipxe.pxeext code 16 = unsigned integer 8;
|
||||
option ipxe.iscsi code 17 = unsigned integer 8;
|
||||
option ipxe.aoe code 18 = unsigned integer 8;
|
||||
option ipxe.http code 19 = unsigned integer 8;
|
||||
option ipxe.https code 20 = unsigned integer 8;
|
||||
option ipxe.tftp code 21 = unsigned integer 8;
|
||||
option ipxe.ftp code 22 = unsigned integer 8;
|
||||
option ipxe.dns code 23 = unsigned integer 8;
|
||||
option ipxe.bzimage code 24 = unsigned integer 8;
|
||||
option ipxe.multiboot code 25 = unsigned integer 8;
|
||||
option ipxe.slam code 26 = unsigned integer 8;
|
||||
option ipxe.srp code 27 = unsigned integer 8;
|
||||
option ipxe.nbi code 32 = unsigned integer 8;
|
||||
option ipxe.pxe code 33 = unsigned integer 8;
|
||||
option ipxe.elf code 34 = unsigned integer 8;
|
||||
option ipxe.comboot code 35 = unsigned integer 8;
|
||||
option ipxe.efi code 36 = unsigned integer 8;
|
||||
option ipxe.fcoe code 37 = unsigned integer 8;
|
||||
option ipxe.vlan code 38 = unsigned integer 8;
|
||||
option ipxe.menu code 39 = unsigned integer 8;
|
||||
option ipxe.sdi code 40 = unsigned integer 8;
|
||||
option ipxe.nfs code 41 = unsigned integer 8;
|
||||
|
||||
class "PXE-Chainload" {
|
||||
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
|
||||
|
||||
next-server $pxe_internal_ip;
|
||||
if exists user-class and option user-class = "iPXE" {
|
||||
filename "http://$pxe_internal_ip/ipxe_boot_script.txt";
|
||||
}
|
||||
elsif substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00007" or substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00008" or substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00009" {
|
||||
filename "ipxe-x86_64.efi";
|
||||
}
|
||||
elsif substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00000" {
|
||||
filename "undionly.kpxe";
|
||||
}
|
||||
}
|
||||
|
||||
subnet $pxe_subnet.0 netmask $pxe_subnet_mask_ip {
|
||||
authoritative;
|
||||
option routers $pxe_internal_ip;
|
||||
option domain-name-servers $pxe_internal_ip;
|
||||
|
||||
pool {
|
||||
allow members of "PXE-Chainload";
|
||||
range $pxe_subnet.128 $pxe_subnet.253;
|
||||
default-lease-time 600;
|
||||
max-lease-time 3600;
|
||||
}
|
||||
|
||||
pool {
|
||||
deny members of "PXE-Chainload";
|
||||
range $pxe_subnet.2 $pxe_subnet.127;
|
||||
default-lease-time 3600;
|
||||
max-lease-time 21600;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
This configuration provides the following important functions:
|
||||
|
||||
* Enables ``dhcpd`` to be iPXE-aware with `iPXE-specific options`_.
|
||||
* Directs PXE clients without an iPXE implementation to the TFTP server
|
||||
for acquiring architecture-specific iPXE firmware images to allow them
|
||||
to perform an iPXE boot.
|
||||
* Is only active on the network adapter which has an IP address on the
|
||||
defined subnet.
|
||||
* Directs PXE clients to the DNS server.
|
||||
* Directs PXE clients to the PXE server for routing via NAT.
|
||||
* Divides the private network into two pools of IP addresses, one for
|
||||
network booting and another for usage after boot; each with their own
|
||||
lease times.
|
||||
|
||||
.. important::
|
||||
|
||||
There are three providers of a DHCP server on the system at this point:
|
||||
``systemd-networkd``, ``dnsmasq``, and ``dhcpd``. ``dhcpd`` is used
|
||||
because it is maintained by ISC and is more flexible for iPXE booting.
|
||||
|
||||
#. Create a file where ``dhcpd`` can record the IP addresses it hands
|
||||
out to PXE clients.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
mkdir -p /var/db
|
||||
touch /var/db/dhcpd.leases
|
||||
|
||||
#. Start ``dhcpd`` and enable startup on boot.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
systemctl enable dhcp4
|
||||
systemctl restart dhcp4
|
||||
|
||||
#. Configure NAT to route traffic from the private network to the public
|
||||
network, effectively turning the PXE server into a router.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
iptables -t nat -F POSTROUTING
|
||||
iptables -t nat -A POSTROUTING -o $external_iface -j MASQUERADE
|
||||
systemctl enable iptables-save.service
|
||||
systemctl restart iptables-save.service
|
||||
systemctl enable iptables-restore.service
|
||||
systemctl restart iptables-restore.service
|
||||
|
||||
.. note::
|
||||
|
||||
The firewall masquerades or translates packets to make them appear as
|
||||
coming from the PXE server. Thus, it hides the PXE clients from the
|
||||
public network.
|
||||
|
||||
#. Tell the Linux kernel to forward network packets on to different
|
||||
interfaces. Otherwise, NAT will not work.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# swupd bundle-add pxe-server
|
||||
mkdir -p /etc/sysctl.d
|
||||
echo net.ipv4.ip_forward=1 > /etc/sysctl.d/80-nat-forwarding.conf
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
|
||||
#. Power on the PXE client and watch it boot the latest release of the
|
||||
|CLOSIA|
|
||||
|
||||
DHCP configuration
|
||||
------------------
|
||||
Congratulations you have successfully installed and configured PXE network-booting for |CL|.
|
||||
|
||||
Add the following content to your :file:`/etc/dhcpd.conf` file:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
allow booting;
|
||||
allow bootp;
|
||||
|
||||
# Set up a class so you can give out an IP only for devices is attempting network boot.
|
||||
{
|
||||
match if substring(option vendor-class-identifier, 0, ;
|
||||
next-server 192.168.1.1;
|
||||
grubx64.
|
||||
}
|
||||
|
||||
# Private subnet, in case you are able to run your own network wide DHCP service.
|
||||
# Works when the machine you are network booting has two network interfaces,
|
||||
# one connected to the private PXE boot network and the other connected to an external
|
||||
# network.
|
||||
subnet 192.168.1.0 netmask 255.255.255.0 {
|
||||
pool {
|
||||
allow members
|
||||
range 192.168.1.100 192.168.1.200;
|
||||
}
|
||||
}
|
||||
|
||||
.. _iPXE:
|
||||
http://ipxe.org/
|
||||
|
||||
Where ``192.168.1.1`` is set to the address your TFTP server is using, and ``grubx64.efi`` is set
|
||||
to the name of your grub bootloader file.
|
||||
.. _Ister Cloud Init Service:
|
||||
https://github.com/clearlinux/ister-cloud-init-svc
|
||||
|
||||
The subnet being used in this example is private; if the DHCPD service you use applies to your
|
||||
entire network, modify the configuration as needed. Also, if multiple devices (including those
|
||||
not using UEFI) are being supported by this DHCPD service, adding the following logic will allow
|
||||
selection of the filename fetched from the client:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
if exists client-arch and option client-arch = 9 {
|
||||
# client-arch = 9 (64-bit EFI)
|
||||
filename "grubx64.efi";
|
||||
} elsif exists client-arch and option client-arch = 6 {
|
||||
# client-arch = 6 (32-bit EFI)
|
||||
filename "grubx32.efi";
|
||||
} else {
|
||||
# client-arch = 0 (Standard PC BIOS)
|
||||
filename "pxelinux.0";
|
||||
}
|
||||
|
||||
Next, create an empty :file:`/var/db/dhcp.leases` file and start the dhcpd service with:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# mkdir -p /var/db
|
||||
# touch /var/db/dhcp.leases
|
||||
# systemctl start dhcp4.service
|
||||
|
||||
|
||||
GRUB configuration
|
||||
------------------
|
||||
|
||||
Create the GRUB bootloader file (:file:`grubx64.efi`) with the following
|
||||
command; it will create the file in your current directory.
|
||||
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# grub-mkimage -O x86_64-efi -o grubx64.efi all_video boot btrfs cat
|
||||
chain configfile echo efifwsetup efinet ext2 fat font gfxmenu gfxterm
|
||||
gzio halt hfsplus iso9660 jpeg linuxefi loadenv loopback lvm mdraid09
|
||||
mdraid1x minicmd multiboot multiboot2 normal part_apple part_msdos
|
||||
part_gpt password_pbkdf2 png reboot search search_fs_uuid search_fs_file
|
||||
search_label serial sleep syslinuxcfg test tftp usbserial_pl2303
|
||||
usbserial_ftdi xfs
|
||||
|
||||
|
||||
Next, a GRUB configuration file (:file:`grub.cfg`) should contain the
|
||||
following content:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
set pager=1
|
||||
|
||||
export menuentry_id_option
|
||||
|
||||
function load_video {
|
||||
if [ x$feature_all_video_module = xy ]; then
|
||||
insmod all_video
|
||||
else
|
||||
insmod efi_gop
|
||||
insmod efi_uga
|
||||
insmod ieee1275_fb
|
||||
insmod vbe
|
||||
insmod vga
|
||||
insmod video_bochs
|
||||
insmod video_cirrus
|
||||
fi
|
||||
}
|
||||
|
||||
terminal_output console
|
||||
if [ x$feature_timeout_style = xy ] ; then
|
||||
set timeout_style=menu
|
||||
set timeout=5
|
||||
else
|
||||
set timeout=5
|
||||
fi
|
||||
|
||||
menuentry 'Clear Linux Installation' --class gnu-linux --class gnu --class os {
|
||||
load_video
|
||||
set gfxpayload=keep
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod ext2
|
||||
linuxefi /linux
|
||||
initrdefi /initrd
|
||||
}
|
||||
|
||||
Where the Linux kernel is named ``linux`` and the initrd ``initrd``.
|
||||
|
||||
|
||||
TFTP configuration
|
||||
------------------
|
||||
|
||||
Clear Linux OS for Intel Archiecture uses ``dnsmasq`` to provide the tftpd
|
||||
service. It requires the following entries exist in :file:`/etc/dnsmasq.conf`:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
enable-tftp
|
||||
tftp-root=/srv/tftp/
|
||||
|
||||
The Linux kernel and initrd files can be downloaded from
|
||||
https://download.clearlinux.org/current/ (with a name like
|
||||
``clear-$version-pxe.tar.xz``) as a compressed tar file containing two
|
||||
clearly-labeled files that should be moved to the tftp root (``/srv/tftp/``,
|
||||
per the tftp server configuration), as ``linux`` and ``initrd`` respectively.
|
||||
The bootloader :file:`grubx64.efi` and its configuration file
|
||||
:file:`grub.cfg` should also be placed in the tftp root ``/srv/tftp/``.
|
||||
|
||||
Now start the tftp service with this command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
systemctl start dnsmasq.service
|
||||
|
||||
|
||||
.. _TFTP: http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf
|
||||
.. _gist: https://gist.github.com/pdxjohnny/d6945910bf7bed962438bf64e70a6a40
|
||||
.. _iPXE website: http://boot.ipxe.org/
|
||||
.. _iPXE: http://ipxe.org/
|
||||
.. _iPXE-specific options:
|
||||
http://www.ipxe.org/howto/dhcpd#ipxe-specific_options
|
||||
|
||||
Reference in New Issue
Block a user