This is a post from the “Teach the Expert” (TTE) series.
If you are looking for an easy way to edit the iSCSI kernel port configuration on the VMware ESXi host, PowerCLI is the ideal solution. In this post, you will learn how to use PowerCLI to configure the iSCSI kernel port and how to enable or disable the iSCSI kernel port. We will also give some examples of using PowerCLI to configure iSCSI kernel port settings. So, let’s get started!
The challenge
In order to better understand the management of iSCSI with PowerCLI connections, we will use a fictitious scenario:
- The hosts of a cluster have redundant kernel ports vmk2 and vmk3 for connecting an iSCSI-based storage array.
- Port binding is activated.
- The MTU is configured to 9000 system-wide.
- On some hosts, the IP address and the subnet of the kernel ports are now to be changed and the kernel port moved to a different distributed portgroup with a different VLAN.
- The new distributed portgroup already exists and the VLAN is configured.
- The process should be carried out without downtime.
- The storage array accepts connections from the new subnet and the target portal is configured.
Preparations and prerequisites
First, we need to make sure that the old iSCSI connection is redundant. We will remove one of the two paths and create a new one. In the meantime, the connection to the LUN must not be interrupted.
Check the iSCSI connection
We check the iSCSI connection with netcat. The target IP in our example is 10.0.200.12. The netcat command can be abbreviated to nc . The parameter -z performs a port scan on the target address instead of sending data. The port number for iSCSI connections is 3260 by default.
nc -z 10.0.200.12 3260
If contact is successfully established, the message appears:
Connection to 10.0.200.12 3260 port [tcp/*] succeeded!
Alternatively, the source address can also be defined using netcat. The parameter -s (source) defines the source port.
nc -s 10.0.200.101 -z 10.0.200.12 3260
Test the correct MTU
Jumbo frames with a Maximum Transmission Unit (MTU) of 9000 bytes are always a popular source of errors. It is therefore worth carrying out a brief check. For this purpose, we send a correspondingly large PING packet to the destination address and specify that it must not be fragmented. It must therefore fit through the line in one piece. The parameter -d means ‘don’t fragment’.
We specify the size of the ping packet with the parameter -s (size). To check an MTU of 9000 bytes, we send a packetsize of 8972 bytes. The reason why we do not send 9000 bytes is that on Linux/Unix systems the ping implementation has a 28 byte overhead (8 byte ICMP header + 20 byte IP header). This means that our packet size can only be 8972 bytes. 28 bytes of overhead are added on top and so we end up with 9000 bytes.
We first send a ping from kernel port vmk2 and then from vmk3, which are the two iSCSI kernel ports in our example. We use the -I parameter to select the source interface vmk2 or vmk3.
vmkping -s 8972 -d -I vmk2 10.0.200.12
vmkping -s 8972 -d -I vmk3 10.0.200.12
If the pings pass through without loss, the MTU 9000 is correctly configured along the entire path from the source to the destination.
Moving the first kernel port
We saw in the last section that our iSCSI connection is redundant and functional. We can now remove one of the two kernel ports and create a new one.
First, we need to establish a connection to vCenter in PowerCLI.
Connect-VIServer vc.lab.local
In the Windows login window, we enter the user and password and authenticate against vCenter in PowerCLI.
Remove port binding
Before we can remove a kernel port, we have to remove the port binding. We can either do this directly on the esxcli or address the esxcli via PowerCLI.
esxcli
Below we see the command as it would look on the ESXCLI.
esxcli iscsi networkportal remove -A vmhba64 -f $true -n vmk2
This is of course a break in the workflow. Our aim is to stay within PowerCLI and execute commands there as scripts.
PowerCLI
To do this, we need to integrate the esxcli into PowerCLI.
$esxcli = Get-EsxCli -VMhost esx1.lab.local -V2
We can now use the $esxcli variable in PowerCLI. We need some parameters that we have to pass with the Invoke() method.
$host = esx1.lab.local $hba = $host | Get-VMHostHba -Type IScsi $kernelport = vmk2 $binding = @{adapter=$hba; force=$true; nic=$kernelport}
The variable $hba then contains e.g. vmhba64 or vmhba65 (software iSCSI adapter).
$esxcli.iscsi.networkportal.remove.Invoke($binding)
Remove kernel port
Once the port binding has been removed, the kernel port can now be deleted from the host.
Get-VMHost -Name $host | Get-VMHostNetworkAdapter -VMKernel -Name $kernelport | Remove-VMHostNetworkAdapter -Confirm:$false
Create a new kernel port
To create a kernel port on the PowerCLI, we need additional parameters. In our example, the name of the vSwitch should be DSwitch-IP-Storage and the name of the port group for iSCSI connection 1 should be dvPG-iSCSI1.
$vSwitch = DSwitch-IP-Storage
$pg = dvPG-iSCSI1
$kportip = 10.0.5.21
New-VMHostNetworkAdapter -VMHost $host -PortGroup $pg -VirtualSwitch $vSwitch -IP $kportip -SubnetMask "255.255.255.0" -Mtu 9000 -Confirm:$false
Set port binding
Port binding needs to be configured again for the new iSCSI kernel port. Again, we need the esxcli in PowerCLI and a list of parameters.
$host = esx1.lab.local
$hba = $host | Get-VMHostHba -Type IScsi
$kernelport = vmk2
$binding = @{adapter=$hba; force=$true; nic=$kernelport}
$esxcli = Get-EsxCli -V2 -VMHost $host
$esxcli.iscsi.networkportal.add.Invoke($binding)
Finally, all HBAs should be rescanned. In a script, we should give the system some time before triggering a rescan on the HBA. Otherwise error messages could be generated unnecessarily.
Start-Sleep -Seconds 3
Get-VMHost -name $host | Get-VMHostStorage -RescanAllHba
Move second kernel port
The procedure is almost identical to moving the first kernel port. You only need to replace vmk2 with vmk3 and adjust the kernel port IP addresses.
Tips
I have developed the commands here step by step for direct execution on the CLI. Of course, this would be too tedious and error-prone for multiple hosts. Ideally, you should pass parameters such as host name, kernel port, kernel port IP and the name of the port group with a CSV file that is read by the script.
First, the script for deleting the first kernel port is executed. We pass it a CSV file with all hosts and their first kernel port. The CSV file could look like this, for example:
host;kernelport;portip;pg
10.1.10.101;vmk2;192.168.1.11;dvPG-iSCSI1
10.1.10.102;vmk2;192.168.1.12;dvPG-iSCSI1
10.1.10.103;vmk2;192.168.1.13;dvPG-iSCSI1
10.1.10.104;vmk2;192.168.1.14;dvPG-iSCSI1
The kernel port IP and port group parameters are not necessary for the deletion process. However, I have deliberately kept the CSV for deletion and creation in the same format. This makes editing easier and the CSVs can be generated by copying.
The script for creating the new iSCSI kernel port is then executed and a CSV with new port data is transferred.
host;kernelport;portip;pg
10.1.10.101;vmk2;10.0.5.21;dvPG-iSCSI1
10.1.10.102;vmk2;10.0.5.22;dvPG-iSCSI1
10.1.10.103;vmk2;10.0.5.23;dvPG-iSCSI1
10.1.10.104;vmk2;10.0.5.24;dvPG-iSCSI1
This replaces one kernel port and the procedure can be continued with the second kernel port. There are also discrete CSV files for removing the vmk3 and recreating the vmk3.