Install DPU Software¶
In the same directory dpu-install
created in previous step.
1. Download BF Bundle¶
The BlueField bundle includes Operating System, Drivers, and DPU software tools. Nvidia DOCA download
2. Create bf config¶
The dpu-config.sh script will produce a BlueField install config file.
Show content of dpu-config.sh
Bash
#!/bin/bash -x
generate_bluefield_config() {
bf_conf_template=$(cat << 'EOFBFTEMPLATE'
# UPDATE_DPU_OS - Update/Install BlueField Operating System (Default: yes)
UPDATE_DPU_OS="yes"
# ubuntu_PASSWORD - Hashed password to be set for "ubuntu" user during BFB installation process.
# Relevant for Ubuntu BFB only. (Default: is not set)
ubuntu_PASSWORD='{{PASSWORD}}'
###############################################################################
# Other misc configuration
###############################################################################
# MAC address of the rshim network interface (tmfifo_net0).
NET_RSHIM_MAC={{NET_RSHIM_MAC}}
# bfb_modify_os – SHELL function called after the file system is extracted on the target partitions.
# It can be used to modify files or create new files on the target file system mounted under
# /mnt. So the file path should look as follows: /mnt/<expected_path_on_target_OS>. This
# can be used to run a specific tool from the target OS (remember to add /mnt to the path for
# the tool).
bfb_modify_os()
{
# Set hostname
local hname="{{HOSTNAME}}"
echo ${hname} > /mnt/etc/hostname
echo "127.0.0.1 ${hname}" >> /mnt/etc/hosts
# Overwrite the tmfifo_net0 interface to set correct IP address
# This is relevant in case of multiple DPU system.
cat << EOFNET > /mnt/var/lib/cloud/seed/nocloud-net/network-config
version: 2
renderer: NetworkManager
ethernets:
tmfifo_net0:
dhcp4: false
addresses:
- {{IP_ADDRESS}}/{{IP_MASK}}
oob_net0:
dhcp4: true
EOFNET
# Modules for kubernetes and DPDK
cat << EOFMODULES >> /mnt/etc/modules-load.d/custom.conf
overlay
br_netfilter
vfio_pci
EOFMODULES
# sysctl settings for kubernets
cat << EOFSYSCTL >> /mnt/etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOFSYSCTL
# Provision hugepages as part of grub boot
# Default to 2M hugepage size and provision 24.5 GB of hugepages
# TMM requires 1.5GB of hugepages per thread (CPU core) totaling
# 24GB to run on all 16 threads of the DPU.
local hpage_grub="default_hugepagesz=2MB hugepagesz=2M hugepages=12544"
sed -i -E "s|^(GRUB_CMDLINE_LINUX_DEFAULT=\")(.*)\"|\1${hpage_grub}\"|" /mnt/etc/default/grub
ilog "$(chroot /mnt env PATH=$PATH /usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg)"
# Provision SF to be used by the TMM on each PF
# First clear out the current configurations for default SFs
# These default SFs do not have trust mode set to.
: > /mnt/etc/mellanox/mlnx-sf.conf
# Then add new SFs with trust mode enabled.
for pciid in $(lspci -nD 2> /dev/null | grep 15b3:a2d[26c] | awk '{print $1}')
do
cat << EOFSF >> /mnt/etc/mellanox/mlnx-sf.conf
/sbin/mlnx-sf --action create --enable-trust --device $pciid --sfnum 0 --hwaddr $(uuidgen | sed -e 's/-//;s/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')
/sbin/mlnx-sf --action create --enable-trust --device $pciid --sfnum 1 --hwaddr $(uuidgen | sed -e 's/-//;s/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')
EOFSF
done
# OVS changes
# 1. Change bridge names to follow internal document as sf_external for pf0
# and sf_internal for pf1.
sed -i -E "s|^(OVS_BRIDGE1=\")(.*)\"|\1sf_external\"|" /mnt/etc/mellanox/mlnx-ovs.conf
sed -i -E "s|^(OVS_BRIDGE2=\")(.*)\"|\1sf_internal\"|" /mnt/etc/mellanox/mlnx-ovs.conf
# 2. Add the new created SFs, "sfnum 1" to their corresponding bridges.
# Also include the virtual functions that are going to be created on host.
# These vfs may not exist yet.
sed -i -E 's|^(OVS_BRIDGE1_PORTS=")[^"]*(")|\1p0 en3f0pf0sf1\2|' /mnt/etc/mellanox/mlnx-ovs.conf
sed -i -E 's|^(OVS_BRIDGE2_PORTS=")[^"]*(")|\1p1 en3f1pf1sf1 pf1vf0\2|' /mnt/etc/mellanox/mlnx-ovs.conf
# Cloud-init for upgrading containerd and runc
cat << EOFCLOUDINIT >> /mnt/var/lib/cloud/seed/nocloud-net/user-data
write_files:
- path: /etc/containerd/config.toml
content: |
version = 2
root = "/var/lib/containerd"
state = "/run/containerd"
oom_score = 0
[grpc]
max_recv_message_size = 16777216
max_send_message_size = 16777216
[debug]
address = ""
level = "info"
format = ""
uid = 0
gid = 0
[plugins]
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "registry.k8s.io/pause:3.10"
max_container_log_line_size = 16384
enable_unprivileged_ports = false
enable_unprivileged_icmp = false
enable_selinux = false
disable_apparmor = false
tolerate_missing_hugetlb_controller = true
disable_hugetlb_controller = true
image_pull_progress_timeout = "5m"
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
snapshotter = "overlayfs"
discard_unpacked_layers = true
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
runtime_engine = ""
runtime_root = ""
base_runtime_spec = "/etc/containerd/cri-base.json"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
systemdCgroup = true
binaryName = "/usr/local/sbin/runc"
- path: /var/tmp/setup-script.sh
permissions: '0755'
encoding: base64
content: |
IyEvYmluL2Jhc2gKClRNUERJUj0kKG1rdGVtcCAtZCkKL3Vzci9zYmluL250cHdhaXQgLXYKc3lzdGVtY3RsIHN0b3AgY29udGFpbmVyZCBrdWJlbGV0IGt1YmVwb2RzLnNsaWNlCnJtIC1yZiAvdmFyL2xpYi9jb250YWluZXJkLyoKcm0gLXJmIC9ydW4vY29udGFpbmVyZC8qCnJtIC1mIC91c3IvbGliL3N5c3RlbWQvc3lzdGVtL2t1YmVsZXQuc2VydmljZS5kLzkwLWt1YmVsZXQtYmx1ZWZpZWxkLmNvbmYKYXB0IC15IHB1cmdlIGt1YmVsZXQga3ViZWFkbSB8fCB0cnVlCmN1cmwgLS1vdXRwdXQtZGlyICR7VE1QRElSfSAtTE8gaHR0cHM6Ly9naXRodWIuY29tL29wZW5jb250YWluZXJzL3J1bmMvcmVsZWFzZXMvZG93bmxvYWQvdjEuMi4xL3J1bmMuYXJtNjQKaW5zdGFsbCAtbSA3NTUgJHtUTVBESVJ9L3J1bmMuYXJtNjQgL3Vzci9sb2NhbC9zYmluL3J1bmMKY3VybCAtLW91dHB1dC1kaXIgJHtUTVBESVJ9IC1MTyBodHRwczovL2dpdGh1Yi5jb20vY29udGFpbmVyZC9jb250YWluZXJkL3JlbGVhc2VzL2Rvd25sb2FkL3YxLjcuMjMvY29udGFpbmVyZC0xLjcuMjMtbGludXgtYXJtNjQudGFyLmd6CnRhciBDenh2ZiAvdXNyL2xvY2FsLyAke1RNUERJUn0vY29udGFpbmVyZC0xLjcuMjMtbGludXgtYXJtNjQudGFyLmd6Ci91c3IvbG9jYWwvYmluL2N0ciBvY2kgc3BlYyA+IC9ldGMvY29udGFpbmVyZC9jcmktYmFzZS5qc29uCmN1cmwgLUwgLW8gL2V0Yy9zeXN0ZW1kL3N5c3RlbS9jb250YWluZXJkLnNlcnZpY2UgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2NvbnRhaW5lcmQvY29udGFpbmVyZC9tYWluL2NvbnRhaW5lcmQuc2VydmljZQpzeXN0ZW1jdGwgZGFlbW9uLXJlbG9hZApzeXN0ZW1jdGwgZW5hYmxlIC0tbm93IGNvbnRhaW5lcmQKbWtkaXIgLXAgL2V0Yy9hcHQva2V5cmluZ3MKY3VybCAtZnNTTCBodHRwczovL3BrZ3MuazhzLmlvL2NvcmU6L3N0YWJsZTovdjEuMjkvZGViL1JlbGVhc2Uua2V5IHwgZ3BnIC0tZGVhcm1vciAtbyAvZXRjL2FwdC9rZXlyaW5ncy9rdWJlcm5ldGVzLWFwdC1rZXlyaW5nLmdwZwphcHQtZ2V0IHVwZGF0ZSAmJiBhcHQtZ2V0IGluc3RhbGwgLXkga3ViZWxldCBrdWJlYWRtIGt1YmVjdGwKc3lzdGVtY3RsIGRhZW1vbi1yZWxvYWQKc3lzdGVtY3RsIGVuYWJsZSAtLW5vdyBrdWJlbGV0CnJtIC1yZiAke1RNUERJUn0K
runcmd:
- [ /var/tmp/setup-script.sh ]
EOFCLOUDINIT
}
# bfb_post_install()
# {
# log ===================== bfb_post_install =====================
# mst start
# mst_device=$(/bin/ls /dev/mst/mt*pciconf0 2> /dev/null)
# # Setting SF enable per Nvidia documentation
# # Ref: https://docs.nvidia.com/doca/sdk/nvidia+bluefield+dpu+scalable+function+user+guide/index.html
# # and DPDK documentation
# # Ref: https://doc.dpdk.org/guides-21.11/nics/mlx5.html
# log "Setting SF enable and BAR size for $mst_device"
# for mst_device in /dev/mst/mt*pciconf*
# do
# log "Disable port owner from ARM side for $mst_device"
# mlxconfig -y -d $mst_device s PF_BAR2_ENABLE=0 PER_PF_NUM_SF=1 PF_TOTAL_SF=252 PF_SF_BAR_SIZE=12
# done
# }
EOFBFTEMPLATE
)
read -p "Enter the number of DPUs (default: 1): " num_dpus
num_dpus=${num_dpus:-1}
read -p "Enter the base hostname (default: dpu): " base_hostname
base_hostname=${base_hostname:-dpu}
echo "Enter the Ubuntu password minimum 12 characters (e.g. 'a123456AbCd!'): "
# Password policy reference: https://docs.nvidia.com/networking/display/bluefielddpuosv490/default+passwords+and+policies#src-3432095135_DefaultPasswordsandPolicies-UbuntuPasswordPolicy
read -s clear_password
ubuntu_password=$(openssl passwd -1 "${clear_password}")
read -p "Enter tmfifo_net IP subnet mask. Useful if you have more than 1 DPU (default: 30): " ip_mask
ip_mask=${ip_mask:-30}
base_ip=${base_ip:-192.168.100}
read -p "Do you want the DPU mgmt interface oob_net0 to use DHCP? (yes/no, default: yes): " use_dhcp
use_dhcp=${use_dhcp:-yes}
if [[ "$use_dhcp" =~ ^([nN][oO]|[nN])$ ]]; then
read -p "Enter the static IP for oob_net0: " oob_ip
read -p "Enter the subnet mask for oob_net0: " oob_mask
fi
for ((i=1; i<=num_dpus; i++)); do
hostname="${base_hostname}-${i}"
ip_address="${base_ip}.$(( i + 1 ))"
net_rshim_mac=00:1a:ca:ff:ff:1${i}
output_file="bfb_config_${hostname}.conf"
echo "Generating configuration for ${hostname} with IP ${ip_address}..."
echo "$bf_conf_template" | sed -e "s/{{HOSTNAME}}/${hostname}/g" \
-e "s|{{PASSWORD}}|${ubuntu_password}|g" \
-e "s/{{IP_ADDRESS}}/${ip_address}/g" \
-e "s/{{IP_MASK}}/${ip_mask}/g" \
-e "s/{{NET_RSHIM_MAC}}/${net_rshim_mac}/g" \
> "${output_file}"
cat << EOL
Configuration for ${hostname} is ${output_file}
To use the config run:
bfb-install --rshim rshim$(( i - 1 )) --config ${output_file} --bfb <bf-bundle-path>
EOL
done
}
generate_bluefield_config
Run the script to generate BlueField configuration.
Bash Session
host# chmod +x dpu-config.sh && ./dpu-config.sh
Enter the number of DPUs (default: 1): 1
Enter the base hostname (default: dpu): test-lab
Enter the Ubuntu password minimum 12 characters (e.g. 'a123456AbCd!'):
Enter tmfifo_net IP subnet mask. Useful if you have more than 1 DPU (default: 30):
Generating configuration for test-lab-1 with IP 192.168.100.2...
Configuration for test-lab-1 is bfb_config_test-lab-1.conf
To use the config run:
bfb-install --rshim rshim0 --config bfb_config_test-lab-1.conf --bfb <bf-bundle-path>
The script produced a file named bfb_config_test-lab-1.conf
based on input.
3. Install BF Bundle¶
Use bfb-install
tool to install the bf-bundle. The following example assumes bf-bundle bf-bundle-2.9.0-83_24.10_ubuntu-22.04_dev.20241121.bfb
Install bf-bundle on DPU
host# bfb-install --rshim rshim0 --config bfb_config_test-lab-1.conf --bfb bf-bundle-2.9.0-83_24.10_ubuntu-22.04_dev.20241121.bfb
Follow status of DPU installation on /dev/rshim0/misc
until DPU is reported ready.
Bash Session
host# cat /dev/rshim0/misc
DISPLAY_LEVEL 2 (0:basic, 1:advanced, 2:log)
BF_MODE Unknown
BOOT_MODE 1 (0:rshim, 1:emmc, 2:emmc-boot-swap)
BOOT_TIMEOUT 300 (seconds)
USB_TIMEOUT 40 (seconds)
DROP_MODE 0 (0:normal, 1:drop)
SW_RESET 0 (1: reset)
DEV_NAME pcie-0000:53:00.2
DEV_INFO BlueField-3(Rev 1)
OPN_STR N/A
UP_TIME 9628(s)
SECURE_NIC_MODE 0 (0:no, 1:yes)
FORCE_CMD 0 (1: send Force command)
---------------------------------------
Log Messages
---------------------------------------
INFO[PSC]: PSC BL1 START
INFO[BL2]: start
INFO[BL2]: boot mode (emmc)
INFO[BL2]: VDD_CPU: 870 mV
INFO[BL2]: VDDQ: 1120 mV
INFO[BL2]: DDR POST passed
INFO[BL2]: UEFI loaded
INFO[BL31]: start
INFO[BL31]: lifecycle GA Secured
INFO[BL31]: runtime
INFO[BL31]: MB ping success
INFO[UEFI]: eMMC init
INFO[UEFI]: eMMC probed
INFO[UEFI]: UPVS valid
INFO[UEFI]: PCIe enum start
INFO[UEFI]: PCIe enum end
INFO[UEFI]: UEFI Secure Boot (disabled)
INFO[UEFI]: PK configured
INFO[UEFI]: Redfish enabled
INFO[UEFI]: DPU-BMC RF credentials not found
INFO[UEFI]: exit Boot Service
INFO[MISC]: Linux up
INFO[MISC]: DPU is ready
4. Join the DPU to the Kubernetes cluster¶
4.1. Get the join token from controller node/host¶
Bash Session
host# kubeadm token create --print-join-command
kubeadm join 10.144.50.50:6443 --token ************************* --discovery-token-ca-cert-hash sha256:*************************
4.2. Join the Kubernetes cluster on the DPU¶
Bash Session
dpu# kubeadm join 10.144.50.50:6443 --token ************************* --discovery-token-ca-cert-hash sha256:*************************