Installing Stackland on Yandex BareMetal via PXE
This tutorial describes how to install Yandex Cloud Stackland on Yandex BareMetal servers using PXE network boot. This method sees servers download the installation environment over the network, so you do not need to manually attach an ISO image to each server via a KVM console.
For general requirements as to cluster resources, DNS, disks, and network ranges, see the Installation guide. For a basic use case on preparing BareMetal servers, see Installing Stackland on Yandex BareMetal. This guide outlines the differences specific to PXE-based installation.
Introduction
For PXE installation, you will need:
- One bastion server running Ubuntu 22.04 or later, which will host
sladmwith built-in DHCP and TFTP servers for network boot. - At least three servers for the future Stackland cluster, connected to the same private network as the bastion.
- PXE file archive:
stackland-pxe-amd64-<version>.zip. sladmutility version supporting the--dhcp-interfaceand--pxe-folderinstallation parameters.key.jsonprovided with your Stackland distribution for accessing components and generating secrets.- Cluster configuration specifying the static IP addresses and MAC addresses of all node network interfaces.
Warning
Do not run other DHCP servers in the private subnet used for PXE boot. When creating the BareMetal private subnet, make sure DHCP is disabled.
The examples below employ 192.168.22.0/24 as the subnet. The bastion is assigned address 192.168.22.1, and the cluster nodes receive addresses 192.168.22.2, 192.168.22.3, and 192.168.22.4. Replace these with addresses from your infrastructure.
Get your private subnet ready
Create a private subnet for the bastion and cluster servers as described in the base guide, but disable automatic IP assignment via DHCP.
When creating the subnet, specify:
- Private subnet CIDR (e.g.,
192.168.22.0/24). - IP assignment via DHCP disabled.
Assign static IP addresses to cluster nodes in the Stackland configuration. During installation, sladm will assign these IPs to the nodes using its built-in DHCP server.
Rent servers
Rent desired BareMetal servers as in the base use case:
-
Rent a bastion server.
When creating your server:
- Select Ubuntu 24.04.
- Connect the server to the private subnet you created in the previous step.
- Assign your server a public IP address for SSH access.
- Set a password for the
rootuser and add an SSH key.
-
Rent at least three servers for your new Stackland cluster.
When creating each server:
- Select No operating system.
- Connect the server to the same private subnet.
- Select No address for the public address.
After renting the servers, record the MAC address of the network interface for each cluster server. You can find it on the server's page under Private network → MAC address. You will need these values in the StacklandHostsList configuration.
Configure the bastion
On the bastion, set up VPN, routing, DNS, and NTP as described in Configuring network access and Installing additional services.
If the bastion's private interface does not have an IP address from the subnet hosting your cluster servers, configure that IP manually and persist the setting in the OS network configuration.
For Ubuntu with netplan, add the private address to the configuration of the corresponding interface. In the example below, the private interface is named eth1:
network:
version: 2
ethernets:
eth1:
addresses:
- 192.168.22.1/24
dhcp4: false
Apply the configuration and verify the address:
sudo netplan apply
ip -brief addr show eth1
Replace eth1 and 192.168.22.1/24 with your interface name and subnet address.
To prepare PXE files and set permissions for sladm, install additional utilities on the bastion:
sudo apt install wget unzip libcap2-bin -y
On the bastion, allow incoming DHCP and TFTP traffic from the private subnet. If using ufw, run this command:
sudo ufw allow from 192.168.22.0/24 to any port 67 proto udp
sudo ufw allow from 192.168.22.0/24 to any port 69 proto udp
sudo ufw allow from 192.168.22.0/24 to any port 53 proto udp
sudo ufw allow from 192.168.22.0/24 to any port 123 proto udp
Replace 192.168.22.0/24 with your private subnet's CIDR. Ports 53 and 123 are only required if DNS and NTP for cluster nodes also run on the bastion.
Verify that IPv4 forwarding is enabled on the bastion and that NAT is configured for the private subnet, as described in the base guide.
sysctl net.ipv4.ip_forward
sudo iptables -t nat -S POSTROUTING
Download and unpack PXE files
Download the stackland-pxe-amd64-<version>.zip archive from the link provided with your Stackland distribution and unpack it on the bastion:
unzip stackland-pxe-amd64-<version>.zip
ls -lh pxe/
If a checksum is provided alongside the archive, verify it before extraction:
sha256sum -c stackland-pxe-amd64-<version>.zip.sha256
In the pxe/ directory, you should see these files:
ipxe.pxe: iPXE bootloader for BIOSipxe.efi: iPXE bootloader for UEFIvmlinuz: Linux kernelinitramfs.xz: Initial ramdisk
The ipxe.pxe and ipxe.efi bootloaders are distributed under the GPLv2 license. The iPXE source code is available in the ipxe
Download and install sladm as described in Downloading required files.
Verify that your sladm version supports PXE installation:
sladm install --help | grep -E 'dhcp-interface|pxe-folder'
After preparing the files on the bastion, keep all installation artifacts in a single working directory:
yc-bms-pxe/
├── sladm
├── key.json
├── stackland-pxe-amd64-<version>.zip
├── pxe/
│ ├── initramfs.xz
│ ├── ipxe.efi
│ ├── ipxe.pxe
│ └── vmlinuz
└── config/
├── cluster.yaml
├── hosts.yaml
└── secrets.yaml
The secrets.yaml file will be generated after running sladm secrets add, as described below.
Configure DNS
Configure the cluster DNS zone and the node hostname zone as described in here.
In this example, the node hostnames correspond to the following addresses:
node1.baremetal.internal:192.168.22.2node2.baremetal.internal:192.168.22.3node3.baremetal.internal:192.168.22.4
Prepare the cluster configuration
Create a config/ directory and prepare configuration files. The general format is described in Initial configuration.
For PXE installation, each node's configuration must specify:
- MAC address of the network interface used for the node's PXE boot.
- Static IP address for that interface in CIDR format.
Before creating your StacklandHostsList, prepare a mapping table of servers, interfaces, and addresses:
| Server | FQDN | MAC address of the private PXE interface | Static IP | Role | Installation disk |
|---|---|---|---|---|---|
node1 |
node1.baremetal.internal |
06:2a:b7:15:de:f1 |
192.168.22.2/24 |
combined |
/dev/sda |
node2 |
node2.baremetal.internal |
0e:9d:6b:fc:42:88 |
192.168.22.3/24 |
combined |
/dev/sda |
node3 |
node3.baremetal.internal |
02:5e:c3:a8:07:d9 |
192.168.22.4/24 |
combined |
/dev/sda |
The MAC address must belong to the private interface used for the server's PXE boot. If multiple network boot options appear in your KVM console, select the one matching this MAC address.
Warning
Do not use dhcp: true for interfaces performing PXE boot. The built-in sladm DHCP server only assigns static addresses defined in the configuration.
Example configuration for a three-node cluster with each node having the combined role:
apiVersion: v1alpha1
kind: StacklandClusterConfig
metadata:
name: main
spec:
platform:
type: "baremetal"
loadBalancer:
type: "cilium-l2"
ipPools:
- cidrs:
- 192.168.22.128/25
cluster:
baseDomain: "stackland.internal"
networking:
hostsNetwork:
- cidr: 192.168.22.0/25
clusterNetwork:
- cidr: 172.16.0.0/16
servicesNetwork:
- cidr: 10.96.0.0/12
virtualIPs:
api: 192.168.22.127
storage:
defaultStorageClass: "stackland-ssd"
genericHostConfig:
disksConfig:
- installDisk:
name: "/dev/sda"
networkConfig:
routes:
- to: "0.0.0.0/0"
via: "192.168.22.1"
iface: "eth0"
resolvers:
- "192.168.22.1"
timeservers:
- "192.168.22.1"
---
apiVersion: v1alpha1
kind: StacklandHostsList
metadata:
name: main
spec:
hosts:
- hostname: "node1.baremetal.internal"
role: "combined"
networkConfig:
interfaces:
- macaddress: "06:2a:b7:15:de:f1"
name: "eth0"
addresses:
- interface: "eth0"
ip: "192.168.22.2/24"
- hostname: "node2.baremetal.internal"
role: "combined"
networkConfig:
interfaces:
- macaddress: "0e:9d:6b:fc:42:88"
name: "eth0"
addresses:
- interface: "eth0"
ip: "192.168.22.3/24"
- hostname: "node3.baremetal.internal"
role: "combined"
networkConfig:
interfaces:
- macaddress: "02:5e:c3:a8:07:d9"
name: "eth0"
addresses:
- interface: "eth0"
ip: "192.168.22.4/24"
Save the configuration in the config/ folder and create the secrets file:
sladm secrets add --out config/secrets.yaml --license-key key.json
chmod 600 key.json config/secrets.yaml
Learn more about preparing secrets here.
Start PXE installation
To start the installation with the --dhcp-interface parameter, sladm must have a permission to open privileged UDP port 67, which is used by the DHCP server. If you also include --pxe-folder, sladm opens UDP port 69 for the TFTP server as well. We recommend granting this permission to the sladm binary once:
sudo setcap 'cap_net_bind_service=+ep' ./sladm
If sladm is not in the current directory, specify the path to its binary. A less recommended alternative is to run the installation command via sudo.
Start installation on the bastion:
sladm install \
--config config/ \
--dhcp-interface <interface_name> \
--pxe-folder ./pxe \
--installation-timeout 3h
Command parameters:
--config: Path to the directory with configuration files.--dhcp-interface: The bastion's network interface connected to the private subnet hosting the cluster servers. You can use this parameter without--pxe-folder: in this mode, network boot is unavailable, but the system loaded from the ISO image will automatically set up the network using DHCP.--pxe-folder: Path to the directory with PXE files. It is used together with the--dhcp-interfaceparameter for network boot.--installation-timeout: Installation timeout. For PXE installations on BareMetal servers, consider increasing this value, as selecting a boot device via the KVM may take extra time.
For example, if the bastion's private interface is named eth1, the command would be:
sladm install \
--config config/ \
--dhcp-interface eth1 \
--pxe-folder ./pxe \
--installation-timeout 3h
Note
Once started, sladm first downloads images from cr.yandex. This may take a while. The installation and network boot start only after the download completes.
To make network boot available immediately after you start installation, download these images in advance:
sladm pull \
--config config/ \
--image-bundle full
Once started, sladm waits for nodes to boot over the network and connect to the installation process.
Boot servers over the network
For each cluster server, perform the following steps:
- Connect to the KVM console.
- Open the boot device selection menu.
- Select network boot: Network Boot, PXE Boot, or UEFI PXE IPv4 for the private interface whose MAC address is listed in
StacklandHostsList. - Wait for the Stackland installation environment to load.
If the server opens UEFI Shell, select exit, return to the boot menu, and select network boot. Do not set UEFI Shell as the primary boot option. If both IPv4 and IPv6 options are available, select IPv4.
After network boot, the server receives an IP address from the built-in sladm DHCP server and loads the installation environment via TFTP. The rest of the installation proceeds automatically.
In sladm logs, you should see received DHCP requests and TFTP file transfers. For example:
INFO DHCP: Received request {"mac": "06:2a:b7:15:de:f1", "message_type": "DISCOVER"}
INFO DHCP: Processing request from known MAC {"mac": "06:2a:b7:15:de:f1", "hostname": "node1", "ip": "192.168.22.2"}
INFO TFTP read request {"client": "192.168.22.2:49152", "filename": "ipxe.efi"}
INFO TFTP transfer completed {"client": "192.168.22.2:49152", "filename": "ipxe.efi"}
After installation, the node will boot from its local disk.
Expected stages in sladm logs:
- DHCP request from a known MAC address.
- TFTP download of
boot.ipxe,vmlinuz, andinitramfs.xz. - The Talos API becomes available at the node's IP on port 50000.
- The Kubernetes API becomes available at the virtual IP on port 6443.
- The Stackland components become ready.
Installation is complete when sladm reports successful completion of the reconcile cycle and saves the administrator kubeconfig. If installation was interrupted after node boot or during platform component setup, re-run sladm install with the same configuration file. The installer will resume from the last completed stage.
If nodes are already installed, booted from local disks, and accessible via the Talos API, you do not need PXE boot to restart them. If this is the case, leave out both --dhcp-interface and --pxe-folder to ensure the DHCP and TFTP services do not start.
sladm install \
--config config/ \
--installation-timeout 3h
Verify the installation
Cluster verification is identical to the base use case. Perform the actions described in these sections:
Additionally, verify that all nodes and platform components are ready:
kubectl get nodes
kubectl get componentinstallations.stackland.yandex.cloud
kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded
In a successful installation:
- All nodes are
Ready. - All
ComponentInstallationresources areReady. - The pod search command returns no unexpected resources.
Check for warnings in Kubernetes events:
kubectl get events -A --field-selector type=Warning --sort-by=.lastTimestamp
Old Kubernetes events may persist after an issue has been resolved. Do not delete them until diagnostics are complete. If sladm install succeeded, all components are ready, and the warning no longer recurs, you can safely remove the stale event:
kubectl delete event -n <namespace> <event_name>