|
@@ -0,0 +1,170 @@
|
|
|
+# AWS NVME Notes
|
|
|
+
|
|
|
+In the nitro-based instances (m5, i3en, etc), AWS presents all drives as NVMe volumes. This
|
|
|
+provides better I/O performance, but can make life complicated when mapping drives from
|
|
|
+the terraform or web console to the device the machine actually sees.
|
|
|
+
|
|
|
+## Determining EBS Mapping
|
|
|
+The EBS mapping is stored in the NVMe metadata. You can grab it by running:
|
|
|
+```
|
|
|
+nvme id-ctrl --raw-binary /dev/nvmXXX | cut -c 3073-3104 | sed 's/ //g'
|
|
|
+```
|
|
|
+
|
|
|
+## Useful Scripts
|
|
|
+
|
|
|
+### /usr/local/bin/ebs-nvme-mapping:
|
|
|
+```
|
|
|
+#!/bin/bash
|
|
|
+#
|
|
|
+# Creates symbolic links from the nvme drives to /dev/sdX or /dev/xvdX.
|
|
|
+# This may not be compatible with instances that have local storage, such
|
|
|
+# as i3's
|
|
|
+PATH="${PATH}:/usr/sbin"
|
|
|
+
|
|
|
+for blkdev in $( nvme list | awk '/^\/dev/ { print $1 }' ) ; do
|
|
|
+ mapping=$(nvme id-ctrl --raw-binary "${blkdev}" 2>/dev/null | cut -c3073-3104 | sed 's/ //g')
|
|
|
+ if [[ "${mapping}" == xvd* ]]; then
|
|
|
+ ( test -b "${blkdev}" && test -L "/dev/${mapping}" ) || ln -s "${blkdev}" "/dev/${mapping}"
|
|
|
+ for partition in $( ls -1 ${blkdev}p* 2> /dev/null ) ; do
|
|
|
+ ln -s ${partition} /dev/${mapping}${partition/${blkdev}p/}
|
|
|
+ done
|
|
|
+ fi
|
|
|
+done
|
|
|
+```
|
|
|
+
|
|
|
+### /root/cf/define_logical_volume.sh:
|
|
|
+```
|
|
|
+#!/bin/bash
|
|
|
+#
|
|
|
+# Provides a simple way to create and format logical volumes for
|
|
|
+# nitro-based AWS instances based off their configured mount point.
|
|
|
+# NOTE: It does not create the fstab entry
|
|
|
+#
|
|
|
+# Syntax: define_logical_volume.sh <LABEL> <VOLGROUP> <LOGICALVOL> <DEVICE>
|
|
|
+# Sample: define_logical_volume.sh SPLUNKFROZEN vg_frozen lv_frozen xvdj
|
|
|
+LABEL=$1
|
|
|
+VOLGRP=$2
|
|
|
+LOGVOL=$3
|
|
|
+DEVICE=$4
|
|
|
+# Iterate over all the nvme devices, looking for those in /dev
|
|
|
+for blkdev in $( nvme list | awk '/^\/dev/ {print $1 }' ); do
|
|
|
+ # For each device grab the desired device name from the vendor data
|
|
|
+ mapping=$(nvme id-ctrl --raw-binary "${blkdev}" 2>/dev/null | cut -c3073-3104 | sed 's/ //g')
|
|
|
+ # If the desired device name is one of those currently requested
|
|
|
+ if `echo $* | egrep -q "\<${mapping}\>"`; then
|
|
|
+ # Repoint our device variable to the real device
|
|
|
+ DEVICE="$blkdev"
|
|
|
+ # Then partition it for use
|
|
|
+ parted $DEVICE --script -- mklabel gpt
|
|
|
+ parted -a optimal $DEVICE mkpart primary 0% 100%
|
|
|
+ partprobe
|
|
|
+ sleep 1
|
|
|
+ fi
|
|
|
+done
|
|
|
+vgcreate $VOLGRP ${DEVICE}p1
|
|
|
+lvcreate -l 100%FREE -n ${LOGVOL} ${VOLGRP}
|
|
|
+mkfs.ext4 -L $LABEL /dev/mapper/${VOLGRP}-${LOGVOL}
|
|
|
+```
|
|
|
+
|
|
|
+### /root/cf/define_swap_volume.sh:
|
|
|
+```
|
|
|
+#!/bin/bash
|
|
|
+# Create a simple way to prepare and initialize a swap
|
|
|
+# volume on AWS nitro based instances.
|
|
|
+# NOTE: Unlike create_logical_volume, this script DOES
|
|
|
+# create an fstab entry.
|
|
|
+#
|
|
|
+# Syntax: define_swap_volume.sh <LABEL> <DEVICE>
|
|
|
+# Sample: define_swap_volume.sh SWAP xvdb
|
|
|
+LABEL=$1
|
|
|
+DEVICE=$2
|
|
|
+# Iterate over all the nvme devices, looking for those in /dev
|
|
|
+for blkdev in $( nvme list | awk '/^\/dev/ {print $1 }' ); do
|
|
|
+ # For each device grab the desired device name from the vendor data
|
|
|
+ mapping=$(nvme id-ctrl --raw-binary "${blkdev}" 2>/dev/null | cut -c3073-3104 | sed 's/ //g')
|
|
|
+ # If the desired device name is one of those currently requested
|
|
|
+ if `echo $* | egrep -q "\<${mapping}\>"`; then
|
|
|
+ # Repoint our device variable to the real device
|
|
|
+ DEVICE="$blkdev"
|
|
|
+ # Then partition it for use
|
|
|
+ parted $DEVICE --script -- mklabel gpt
|
|
|
+ parted -a optimal $DEVICE mkpart primary 0% 100%
|
|
|
+ partprobe
|
|
|
+ sleep 1
|
|
|
+ mkswap -L $LABEL $DEVICE
|
|
|
+ swapon $DEVICE
|
|
|
+ echo "LABEL=$LABEL swap swap defaults,nofail 0 2" >> /etc/fstab
|
|
|
+ fi
|
|
|
+done
|
|
|
+```
|
|
|
+
|
|
|
+### /usr/local/sbin/initialize_nvme_storage.sh:
|
|
|
+```
|
|
|
+#!/bin/bash
|
|
|
+#
|
|
|
+# This needs to be called every boot, before Splunk starts. It
|
|
|
+# initializes local storage as RAID-0.
|
|
|
+#
|
|
|
+# NOTE: This determines which NVMe drives are local based on
|
|
|
+# whether they are 2.5TB or 7.5TB! THIS IS NOT A GOOD
|
|
|
+# WAY, but works in a pinch. If you create 2.5TB EBS
|
|
|
+# volumes, you're in for some trouble.
|
|
|
+if [ ! -b /dev/md0 ]; then
|
|
|
+ # We are fresh or on new hardware. Recreate the RAID.
|
|
|
+ rm -f /etc/mdadm.conf 2> /dev/null
|
|
|
+ DEVICES=$( nvme list | egrep "[72].50 TB" | awk '{print $1}' )
|
|
|
+ NUM=$( nvme list | egrep "[72].50 TB" | wc -l )
|
|
|
+ mdadm --create --force --verbose /dev/md0 --level=0 --name=SMARTSTORE_CACHE --raid-devices=${NUM} ${DEVICES}
|
|
|
+ mkfs -t xfs /dev/md0
|
|
|
+ mkdir -p /opt/splunk/var/lib/splunk 2> /dev/null
|
|
|
+ chown splunk:splunk /opt/splunk 2> /dev/null
|
|
|
+ mdadm --verbose --detail --scan | tee -a /etc/mdadm.conf
|
|
|
+fi
|
|
|
+# Alternatively, could be mounted to /opt/splunk/var
|
|
|
+mount /dev/md0 /opt/splunk/var/lib/splunk
|
|
|
+```
|
|
|
+
|
|
|
+### /etc/systemd/system/ephemeral-init.service:
|
|
|
+```
|
|
|
+# Configures the splunk initialization script to run on
|
|
|
+# boot.
|
|
|
+# Because splunk is started by an init.d script, we
|
|
|
+# cannot set dependencies in here, and instead must
|
|
|
+# also modify the splunk init script.
|
|
|
+[Unit]
|
|
|
+#DefaultDependencies=no
|
|
|
+#After=sysinit.target local-fs.target
|
|
|
+#Before=base.target
|
|
|
+RequiresMountsFor=/opt/splunk
|
|
|
+
|
|
|
+[Service]
|
|
|
+ExecStart=/usr/local/sbin/initialize_nvme_storage.sh
|
|
|
+
|
|
|
+[Install]
|
|
|
+WantedBy=default.target
|
|
|
+```
|
|
|
+
|
|
|
+### /etc/init.d/splunkd
|
|
|
+The splunk init script needs to be modified to wait for
|
|
|
+the instance storage RAID array to become active. To do
|
|
|
+so, modify the `splunk_start()` function in the script
|
|
|
+to begin with:
|
|
|
+```
|
|
|
+# WaitForMount BEGIN
|
|
|
+ echo Waiting for mount point...
|
|
|
+ count=0
|
|
|
+ while ! mountpoint -q /opt/splunk/var/lib/splunk
|
|
|
+ do
|
|
|
+ echo "Mount point not ready. Sleep 1 second..."
|
|
|
+ sleep 1
|
|
|
+ count=`expr $count + 1`
|
|
|
+ if test $count -eq 90
|
|
|
+ then
|
|
|
+ echo "timed out!"
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
+ done
|
|
|
+# WaitForMount END
|
|
|
+ echo Starting Splunk...
|
|
|
+```
|
|
|
+
|