5

New Dynamic Disk Pool configuration and E-Series SANtricity

 2 years ago
source link: https://scaleoutsean.github.io/2022/09/12/new-ddp-and-e-series-santricity-web-restful-api.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

New Dynamic Disk Pool configuration and E-Series SANtricity

12 Sep 2022 -

9 minute read

Dynamic Disk Pools vs. Disk Groups

On E-Series or EF-Series drives, there are traditional disk groups where you configure traditional RAID. For example you can take two disk drives and configure RAID 1.

There’s also DDP about which I wrote before, where data protection is always RAID 6-like, meaning 8 strips of data, and 2 strips of parity. The difference vs. a RAID 6 Disk Group is that this allocation is fixed no matter how large a DDP gets. So whether you have 11 or 51 disks in a DDP, writes will be 8D2P in 128 KiB chunks.

New DDP configuration

Apparently, this has changed and “DDP containers for RAID 1- and RAID6-like volumes” are a thing since SANtricity version 11.70.1. From TR-4652:

New DDP configuration

If you can’t see the image clearly:

  • The minimum number of drives in a DDP is 8 when configured through the API and comprised of SSDs. It used to be, and still is, 11 when configured through the SANtricity Web management interface
  • Now we can use the API to create RAID 1-style volumes on DDPs, and these RAID 1-style volumes can coexist with RAID 6-style volumes in the same DDP (assuming DDP size is 11 or more)
  • DDP with 8-10 drives lets you create RAID 1-style volumes in 3+3 configuration (very similar to 6-drive RAID 10 in a “classic” E-Series Disk Group)
  • DDP with 11 or more drives creates RAID 1-style volumes as 5+5 configuration, so a DDP with less 11 disk drives that was expanded to 11 (or more) disk drives may have RAID 1 volumes of differing sizes and striping patterns

What does that mean?

It means several things:

  • we no longer have to configure a separate Disk Group just to get RAID 1 or 10 protection for some volumes (we also don’t need to provide a separate hot spare as DDPs don’t use hot spares)
  • if all we want is RAID 6 and RAID 1, this heterogeneous RAID type can make it easier from a sizing perspective as we can just create a big DDP out of all disks and call it a day
  • DDP has 1 or 2 disks worth of spare capacity which means we no longer have to quote a separate hot spare for “classic” RAID groups

Practical examples:

  • EF600 has 24 disk slots in controller shelf. If you need RAID 6 and RAID 1 volumes, we’d do something like 2 x RAID 6 (8D2P) and 2 x RAID 1 to use up all 24 slots, but if we needed less capacity, it could be harder to lay them out nicely. Maybe we’d do 1 x DDP for 11-20 drives instead of RAID 6, but we’d still have separate RAID 1 disk groups
  • Now we can use (for example) 1 x DDP with 15 drives, have RAID 10-like and RAID 6-like data in this one pool, and be able to grow it by one or more disks at a time while not having an idle Hot Spare or Cold Spare sitting there doing nothing

Before vs now:

  • Before: 2 x RAID 6 + 2 x RAID 1 = 24 disks, and one Cold Spare on the side
  • Now: 1 x DDP with RAID 6- and RAID 1-like volumes (11-24 drives, with 2 drives of spare capacity)

Things to note

If you start with a 9 drive DDP configured via the REST API, you won’t be able to create RAID 6-like volumes until you grow the DDP by two additional disk drives. But you can start with RAID 10-like volumes and migrate data to RAID 6-like volume later, if you don’t mind the extra work. Generally I wouldn’t recommend this, but there may be workloads (scale-out, etc.) where migration can be painless - add a new worker with new RAID 6 configuration, remove an old worker with old RAID 1 configuration, etc. until you’ve moved all data from RAID 1 to RAID 6 volumes on DDP.

If you start with a 10 drive DDP and RAID 10-like volumes, and later grow the DDP to 11 and beyond, new and old RAID 10 “containers” won’t be the same. Same as above, this may or may not be annoying. If you run scale-out services or can afford some downtime, this may be easy.

Disks in a DDP must have the same disk size.

Unlike “classic” disk groups, IO workload from RAID 10 and RAID 6 “volume containers” in a DDP is co-mingled, so it’s not possible to separate the workloads as clearly. So a little bit more caution is required when combining workloads on the same DDP group - unlike with “classic” RAID 1 and RAID 6 which share the controllers, here they share physical disks as well.

On the one hand, we lose the benefit of workload segregation on disk level and Full Stripe Write Acceleration (possible with “classic” RAID 6), but on the other we spread workloads across more disks and on the whole we may also gain from not over-sizing one RAID type with classic RAID, for example.

SANtricity Web Services Proxy

It’s a reverse proxy for one or more stand-alone or embedded (i.e. into E-Series or EF-Series controllers) SANtricty management interfaces.

You can run this thing locally on your “management workstation”, for example.

You can learn more about it here. One thing I’ve learned by randomly browsing TFM is that pre-REST SYMbol is exposed through Web Services proxy and you may want to disable it for additional security.

Web Proxy Container

Okay, so how do we use this thing if we don’t have it in our lab?

After some RTFM I found there’s no need to download anything by logging in anywhere - there’s a freely downloadable container image on the Web. Adjust the command to use 127.0.0.1 or a port inaccessible to external network. I’ll use 8443 as per the example from Docker Hub.

$ docker run -it -p8443:8443 -e ACCEPT_EULA=true netapp/eseries-webservices
Unable to find image 'netapp/eseries-webservices:latest' locally
latest: Pulling from netapp/eseries-webservices
8663204ce13b: Already exists 
bee9030860e0: Pull complete 
a16c61869286: Pull complete 
a790ba5de190: Pull complete 
Digest: sha256:df9d3265c13274606dfb7aa701bb006f81fb6d5bd2941bf4abd147494cb7d559
Status: Downloaded newer image for netapp/eseries-webservices:latest
...

Leave that console window open and elsewhere check the IP address and port.

$ docker ps -a                          
CONTAINER ID   IMAGE                       PORTS
92dd54394678   netapp/eseries-webservices  0.0.0.0:8443->8443/tcp, :::8443->8443/tcp

You know where to go…

SANtricity Web Services proxy

If you prefer to consume the docs offline, download them and shut down the container (assuming localhost:8443):

wget https://localhost:8443/docs/static_docs.zip

Or you can browse ‘em live at https://localhost:8443/um/en-US/root.html.

Web Services API with Swagger

Get to Swagger at https://localhost:8443/devmgr/docs/ (assuming localhost:8443).

Interestingly there’s nothing about Volume Groups or Pools. I guess that means Volumes is the section to look at.

Volumes section in SANtricity Swagger

I assume the right method is https://localhost:8443/devmgr/docs/#/Volumes/new-StoragePool.

{
  "raidLevel": "raidUnsupported",
  "diskDriveIds": [
    "string"
  ],
  "eraseSecuredDrives": true,
  "name": "string"
}

We may want to do something like:

{
  "raidLevel": "raid7",
  "diskDriveIds": [ "1,2,3,4,5,6,7,8" ],
  "eraseSecuredDrives": false,
  "name": "ddp1"
}

It’s a bit strange that diskDriveIds is a string. And WTF is RAID7?

Well, according to Cloud Insights documentation it’s how SANtricity reports DDPs.

Redundancy – RAID level or protection scheme. E-Series reports “RAID 7” for DDP pools

I had no idea… Anyway, because of that I guess we should use raid7 in raidLevel.

Then we’d create volumes. For that use POST /storage-systems/{system-id}/volumes to create a RAID 1 or 6 volume, which would look something like this:

{
  "poolId": "ddp1",
  "name": "raid10logdisk",
  "sizeUnit": "gb",
  "size": "100",
  "segSize": 0,
  "dataAssuranceEnabled": false,
  "owningControllerId": "controller1",
  "raidLevel": "raid1",
  "metaTags": [
    {
      "key": "workload",
      "value": "database"
    }
  ],
  "blockSize": 0
}

I don’t know if this is correct because I can’t try, but I’ll update this example if I find out for sure later.

After that we’d use methods from Mapping section to create a host group, add a host or hosts to it, and map the volume to this group.

Examples of automation with Python

TFM says there are samples of automation scripts in the samples directory. Enter your docker container to see them.

/opt/netapp/webservices_proxy # cd /opt/netapp/webservices_proxy/samples/restapi/python

/opt/netapp/webservices_proxy # ls -la
total 80
drwxr-xr-x    2 root     root          4096 May 16 23:54 .
drwxr-xr-x    3 root     root          4096 May 16 23:54 ..
-rwxr-xr-x    1 root     root          2773 May 16 23:54 async_mirroring.py
-rwxr-xr-x    1 root     root          5055 May 16 23:54 configuration.py
-rwxr-xr-x    1 root     root          2448 May 16 23:54 consistency_groups.py
-rwxr-xr-x    1 root     root          1963 May 16 23:54 copies.py
-rwxr-xr-x    1 root     root          1094 May 16 23:54 device_alerts.py
-rwxr-xr-x    1 root     root           329 May 16 23:54 device_alerts_email.py
-rwxr-xr-x    1 root     root          1634 May 16 23:54 device_asup.py
-rwxr-xr-x    1 root     root           418 May 16 23:54 device_asup_logs.py
-rwxr-xr-x    1 root     root           793 May 16 23:54 event_monitoring.py
-rwxr-xr-x    1 root     root          1021 May 16 23:54 hardware_inventory.py
-rwxr-xr-x    1 root     root          1498 May 16 23:54 pools.py
-rwxr-xr-x    1 root     root            17 May 16 23:54 requirements.txt
-rwxr-xr-x    1 root     root          4243 May 16 23:54 restlibs.py
-rwxr-xr-x    1 root     root          1928 May 16 23:54 snapshots.py
-rwxr-xr-x    1 root     root           955 May 16 23:54 symbol.py
-rwxr-xr-x    1 root     root          1120 May 16 23:54 volumes.py

/opt/netapp/webservices_proxy # less pools.py

There is nothing too revealing in there, but fine - we know we need to get drives or just name drive IDs if we can view them in the Web UI, and POST this to target.

drives_req = {
          "driveCount": 11,
          "interfaceType": "fibre"
driveSet = map(lambda d: d['driveRef'], drives)
generic_post('pools', {'diskDriveIds' : driveSet,
    'name' : 'pool1',
    'raidLevel' : "raid5"}, array_id=array['id'])

Unfortunately there’s nothing about valid inputs or DDP-related examples, so without anything to go by I assume that Cloud Insights has a point and raid7 would be what we want.

If you’re starting with Python you can first try the example from Docker Hub:

def main():
    """Issue a simple request to list the monitored systems"""
    result = requests.get('https://dot.org.com:443/devmgr/v2/storage-systems',
                          headers={'Accept': 'application/json'},
                          auth=('rw', 'myp@ass'))
    pprint(result.json())

PowerShell users can take a look at E-series PowerShell Toolkit.

Summary

The new DDP features are smaller minimum pool size (8, limited to RAID 1-only volumes) and the ability to provision RAID 1 and RAID 6 in same DDP (with 11 or more drives).

These provide additional flexibility and improve the economics of E-Series:

  • Create RAID 1-style volumes in DDP for easier capacity management
  • Grow RAID 1-style volumes in DDP by growing DDP by as little as one drive at a time
  • Avoid Hot or Cold Spares for configurations that have RAID 1 (now on DDP) compared to before where a Hot or Cold Spare had to be allocated even for the smallest RAID 1 Disk Group - especially convenient and economical for single-shelf SSD configurations

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK