Storage Virtual Machines (SVM) are the entity in clustered Data ONTAP which the storage consumer actually interacts with. As the name implies, they are a virtual entity, however they are not a virtual machine like you would expect. There are no CPU, RAM, or other cache assignments that must be made. Instead, we assign storage resources to the SVM, such as aggregates and data LIF(s), which the SVM then uses to provision FlexVols and make them available via the desired protocol.
In this post we will look at how to configure an SVM using PowerShell.
- Create an SVM
- Aggregate Access
- SVM DNS Service
- Configuring Data LIF(s)
- Configuring Protocols
Create an SVM
# create a new SVM $splat = @{ # a name for the SVM "Name" = $svmName; # the name of the root volume, easy to keep track of # by using the SVM name in the name of the root vol "RootVolume" = "$($svmName)_root"; # the aggregate to create the root volume on "RootVolumeAggregate" = $rootAggrName; # the NSS setting, use "file" if unsure "NameServerSwitch" = "file"; # will vary based on how you're accessing the volumes # unix = NFS, iSCSI, and/or FC/FCoE # ntfs = CIFS/SMB # mixed = all of the above "RootVolumeSecurityStyle" = "unix"; # language, C.UTF-8 is a good default if unsure "Language" = "C.UTF-8"; } New-NcVserver @splat
Destroying SVMs can be a complex task, as all of the resources it uses must be removed first. Vidad Cosonock has created a script here that will automate removing an SVM, I highly recommend using that to simplify removing the SVM.
Aggregate Access
Limiting the aggregates that the SVM has access to can be beneficial when in a multitenant environment so that you can dedicate disks to specific tasks/customers. However, it can also be useful regardless of your use of mutlitenancy by preventing volumes from being created on root aggregates.
# show assigned aggregates (Get-NcVserver $svmName).AggrList
Managing aggregate access is done by modifying the SVM properties. We can wrap that into functions to make it even easier:
function Add-SvmAggrAccess { [CmdletBinding(SupportsShouldProcess=$true)] param( [parameter( Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [System.String]$Vserver , [parameter( Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [Alias('Name')] [System.String[]]$Aggregate ) process { # get the current aggr list $aggrList = (Get-NcVserver -Name $svmName).AggrList # add the new aggr to the list $aggrlist += $Aggregate if ($PSCmdlet.ShouldProcess($Vserver, "Adding aggregate $($Aggregate) to approved list")) { # update the assigned aggregate list Set-NcVserver -Name $Vserver -Aggregates $aggrList } } } function Remove-SvmAggrAccess { [CmdletBinding(SupportsShouldProcess=$true)] param( [parameter( Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [System.String]$Vserver , [parameter( Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [Alias('Name')] [System.String[]]$Aggregate ) process { # remove the aggr from the list of current aggrs $aggrlist = (Get-NcVserver -Name $svmName).AggrList | ?{ $_ -notin $Aggregate } if ($PSCmdlet.ShouldProcess( $Vserver, "Removing aggregate $($Aggregate) from approved list" )) { # update the assigned aggregate list Set-NcVserver -Name $Vserver -Aggregates $aggrList } } }
Using these functions it’s now quite easy to modify the aggregates that an SVM has permission to use:
# add an aggregate to the SVM Get-NcVserver $svmName | Add-SvmAggrAccess $aggrName # remove an aggregate from the SVM's access Get-NcAggr $aggrName | Remove-SvmAggrAccess $svmName
Finally, let’s add only non-root aggregates to the SVM:
# get the root aggrs $rootAggrs = Get-NcVol | ?{ $_.VolumeStateAttributes.IsNodeRoot -eq $true } | %{ $_.Aggregate } # remove them from the access list Remove-SvmAggrAccess -Name $svmName -Aggregate $rootAggrs # get the non-root aggregates $nonRootAggrs = Get-NcAggr | ?{ $_.Name -notin $rootAggrs }).Name # add them to the access list Add-SvmAggrAccess -Name $svmName -Aggregate $nonRootAggrs
SVM DNS Service
# configure new DNS Get-NcVserver $svmName | New-NcNetDns -Domains foo.bar,your.company -NameServers 8.8.8.8,8.8.4.4 # modify DNS configuration Get-NcVserver $svmName | Set-NcNetDns -Domains foo.bar -NameServers $ns1,$ns2
Configuring Data LIF(s)
Before we can enable data access protocols we need to have a way of accessing the data. NetApp uses logical network interfaces, known as LIFs, assigned to the SVM. Let’s look at creating LIFs for the different protocols:
- NFS / CIFS / SMB
# Splatting is a convenient way to keep parameters readable $splat = @{ # I prefer a simple naming convention to quickly identify LIFs 'Name' = "$($nodeName)_$($svmName)_FILE_$($instanceNum)"; # where to create the LIF 'Vserver' = $svmName; 'Node' = $nodeName; 'Port' = $portName; # the type of LIF 'Role' = "data"; # alternatively only one or the other can be provided 'DataProtocols' = "nfs","cifs"; # finally, the IP information 'Address' = $ipAddress; 'Netmask' = $subnetMask; } New-NcNetInterface @splat
- iSCSI
# for block based protocols we want to have one LIF per node so # that ALUA can work its magic. if you're using cDOT 8.3 and Subnets # then creating the LIFs is quite easy Get-NcNode | Foreach-Object { # create a LIF on each node $splat = @{ # keep a nice and easy naming convention 'Name' = "$($_.Node)_$($svmName)_ISCSI"; # where to create the LIF 'Vserver' = $svmName; 'Node' = $_.Node; 'Port' = $portName; # the type of LIF 'Role' = "data"; 'DataProtocols' = "iscsi"; # Using a subnet, ONTAP will allocate the IP address. # The gateway and subnet mask are provided when the # subnet is created, and the Broadcast Domain will # ensure that we can failover the LIF 'Subnet' = $subnetName; } New-NcNetInterface @splat }
- FC / FCoE
# Like with iSCSI, we want to create an FCP / FCoE LIF # on each node in the cluster Get-NcNode | Foreach-Object { # create a LIF on each node $splat = @{ # keep a nice and easy naming convention 'Name' = "$($_.Node)_$($svmName)_FC"; # where to create the LIF 'Vserver' = $svmName; 'Node' = $_.Node; 'Port' = $portName; # the type of LIF 'Role' = "data"; # the protocol 'DataProtocols' = "fcp"; # for fcp WWPNs will be automatically generated } New-NcNetInterface @splat }
Configuring Procotols
A newly created SVM will not have any protocols assigned to it. Adding and configuring the protocols is a few simple commands.
- NFS
# configuring the protocol is a bit different because there are # so many options we create an object and set the options there $nfsServiceConfig = Get-NcNfsService -Template # enable the nfs service $nfsServiceConfig.IsNfsAccessEnabled = $true # enable nfsv3 $nfsServiceConfig.IsNfsv3Enabled = $true # disable nfsv2, v4.0, v4.1 $nfsServiceConfig.IsNfsv2Enabled= $false $nfsServiceConfig.IsNfsv40Enabled = $false $nfsServiceConfig.IsNfsv41Enabled = $false # apply the config Get-NcVserver $svmName | Add-NcNfsService -Attributes $nfsServiceconfig
- SMB / CIFS
# create the CIFS/SMB server and join it to the domain Add-NcCifsServer -VserverContext $svmName ` -Domain $domainName -AdminCredential (Get-Credential) # start CIFS/SMB server Get-NcVserver $svmName | Start-NcCifsServer
- iSCSI
# add the service to the SVM Get-NcVserver $svmName | Add-NcIscsiService # start the service Get-NcVerver $svmName | Enable-NcIscsi
- FC / FCoE
# add the service to the SVM Add-NcFcpService -VserverContext $svmName # start the service Get-NcVserver $svmName | Enable-NcFcp
The post NetApp PowerShell Toolkit 101: Storage Virtual Machine Configuration appeared first on The Practical Administrator.