1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ストレージ管理I/F: Swordfish API Emulator のコンテナ実行

Posted at

はじめに

ストレージ業界団体SNIAが提供するストレージ管理I/Fの標準仕様SwordfishAPI Emulator(Swordfish-API-Emulator)のコンテナイメージを用意したため、これの実行方法を紹介します。
なお、SwordfishのAPI Emulatorは、Swordfishの母体となるDMTFが提供するシステム管理I/Fの標準仕様[Redfish]のAPI Emulator(Redfish-Interface-Emulator)を活用しているため、本コンテナイメージには両API Emulatorが入っています。

Dockerでの実行方法

以下のコマンドでコンテナにてSwordfish-API-Emulatorを起動します。

$ docker run -p 5000:5000 --name swordfish ysakashita/swordfish-api-emulator:latest 

Webブラウザでhttp://localhost:5000/にアクセスします。
以下の画面が出てきたら、"here for a GPI Redfish browser." の here をクリックします。
(Swordfish-API-Emulatorはストレージ関連のリソースのみであり、エミュレータ本体はRedfish-Interface-Emulatorを利用するため、GUIではRedfishの画面となります)

スクリーンショット 2022-01-07 17.50.55.png

すると以下のようにAPI Emulatorで用意されているリソースにアクセスできます。
Namespaceは/redfish/v1となります。

スクリーンショット 2022-01-07 17.51.08.png

なお、curlでのアクセスを試したい方は、後述の補足に例を記載していますので、それらをご参照ください。

Kubernetesでの実行方法

Kubernetes上で起動させる場合は、以下のManifestを使いデプロイします。
なお、今回はminikubeでIngressをaddonで有効にした環境で試しています。

:pencil:

minikubeでのaddonを使ったIngressの有効化の方法 ``` $ minikube start $ minikube addons enable ingress ```
  • deploy-swordfish-api-emulator.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: swordfish
spec:
  replicas: 1
  selector:
    matchLabels:
      app: swordfish
  template:
    metadata:
      labels:
        app: swordfish
    spec:
      containers:
      - name: swordfish
        image: ysakashita/swordfish-api-emulator:latest
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 5000
  • svc-swordfish-api-emulator.yaml
apiVersion: v1
kind: Service
metadata:
  name: swordfish
spec:
  selector:
    app: swordfish
  ports:
  - port: 5000
    targetPort: 5000

今回は、Ingressも用意します。
Ingressのhostは環境にあわせて設定してください。

  • ing-swordfish-api-emurator.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: swordfish
  labels:
    name: swordfish
spec:
  rules:
  - host: swordfish.192.168.99.137.nip.io  # Please update much as your env.
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: swordfish
            port: 
              number: 5000

上記3つのManifestをデプロイします。

$ kubectl apply -f deploy-swordfish-api-emulator.yaml -f svc-swordfish-api-emulator.yaml -f ing-swordfish-api-emurator.yaml 

実行を確認します。

$ kubectl get ing,svc,pod
NAME                                  CLASS    HOSTS                             ADDRESS          PORTS   AGE
ingress.networking.k8s.io/swordfish   <none>   swordfish.192.168.99.137.nip.io   192.168.99.137   80      41s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    112d
service/swordfish    ClusterIP   10.110.217.188   <none>        5000/TCP   41s

NAME                             READY   STATUS    RESTARTS   AGE
pod/swordfish-7cdf5f6bc9-qm56p   1/1     Running   0          41s

以上で起動完了です。
Dockerの場合と同じくWebブラウザでアクセスします。
URLはIngressで作成したホストです(URL: http://swordfish.192.168.99.137.nip.io/)。

補足

2022/1/6時点のSwordfish-API-Emulatorでは、Staticなリソースとして/redfish/v1/Storage配下にIPAttachedDriveとして、SSDのドライブが1つだけと少し寂しいものとなっています。

  • curlでの取得例 (コンテナイメージ ysakashita/swordfish-api-emulator:latest)
$ curl -X GET http://swordfish.192.168.99.137.nip.io/redfish/v1/Storage |jq
...
{
  "@odata.id": "/redfish/v1/Storage",
  "@odata.type": "#StorageCollection.StorageCollection",
  "Members": [
    {
      "@odata.id": "/redfish/v1/Storage/IPAttachedDrive"
    }
  ],
  "Members@odata.count": 1,
  "Name": "Storage Collection"
}

$ curl -X GET http://swordfish.192.168.99.137.nip.io/redfish/v1/Storage/IPAttachedDrive | jq
...
{
  "@odata.id": "/redfish/v1/Storage/IPAttachedDrive",
  "@odata.type": "#Storage.v1_10_0.Storage",
  "Controllers": {
    "@odata.id": "/redfish/v1/Storage/IPAttachedDrive/Controllers"
  },
  "Description": "An NVM Express Subsystem is an NVMe device that contains one or more NVM Express controllers and may contain one or more namespaces.",
  "Drives": [
    {
      "@odata.id": "/redfish/v1/Chassis/IPAttachedDrive/Drives/IPAttachedDrive"
    }
  ],
  "Id": "1",
  "Identifiers": [
    {
      "DurableName": "nqn.2014-08.org.nvmexpress:uuid:6c5fe566-10e6-4fb6-aad4-8b4159f50245",
      "DurableNameFormat": "NQN"
    }
  ],
  "Links": {
    "Enclosures": [
      {
        "@odata.id": "/redfish/v1/Chassis/IPAttachedDrive"
      }
    ]
  },
  "Name": "NVMe IP Attached Drive Configuration",
  "Status": {
    "Health": "OK",
    "HealthRollup": "OK",
    "State": "Enabled"
  },
  "Volumes": {
    "@odata.id": "/redfish/v1/Storage/IPAttachedDrive/Volumes"
  }
}

$ curl -X GET http://swordfish.192.168.99.137.nip.io/redfish/v1/Chassis/IPAttachedDrive/Drives/IPAttachedDrive | jq
...
{
  "@odata.id": "/redfish/v1/Chassis/IPAttachedDrive/Drives/IPAttachedDrive",
  "@odata.type": "#Drive.v1_12_0.Drive",
  "Actions": {
    "#Drive.Reset": {
      "target": "/redfish/v1/Chassis/IPAttachedDrive/Drives/IPAttachedDrive/Actions/Drive.Reset"
    },
    "#Drive.SecureErase": {
      "target": "/redfish/v1/Chassis/IPAttachedDrive/Drives/IPAttachedDrive/Actions/Drive.SecureErase"
    }
  },
  "BlockSizeBytes": 512,
  "CapableSpeedGbs": 12,
  "CapacityBytes": 899527000000,
  "Description": "IP Attached drive.",
  "EncryptionAbility": "None",
  "FailurePredicted": false,
  "Id": "IPAttachedDrive",
  "Identifiers": [
    {
      "DurableName": "500003942810D13A",
      "DurableNameFormat": "NAA"
    }
  ],
  "Links": {
    "Volumes": [
      {
        "@odata.id": "/redfish/v1/Storage/IPAttachedDrive/Volumes/SimpleNamespace"
      }
    ]
  },
  "LocationIndicatorActive": true,
  "Manufacturer": "Contoso",
  "MediaType": "SSD",
  "Model": "ST9146802SS",
  "Name": "NVMe IPAttachedDrive Drive",
  "NegotiatedSpeedGbs": 12,
  "PartNumber": "SG0GP8811253178M02GJA00",
  "PhysicalLocation": {
    "PartLocation": {
      "LocationType": "Slot"
    }
  },
  "PredictedMediaLifeLeftPercent": 86,
  "Protocol": "NVMe",
  "Revision": "S20A",
  "SKU": "N/A",
  "SerialNumber": "72D0A037FRD26",
  "Status": {
    "Health": "OK",
    "State": "Enabled"
  },
  "StatusIndicator": "OK",
  "WriteCacheEnabled": true
}

そこで、少し古くはなりますが、2つのストレージのリソースが用意されていた2018/08時点のもののコンテナイメージ(ysakashita/swordfish-api-emulator:20180801)も用意しました。Docker or Kubernetesで実行するコンテナイメージのタグに20180801を指定してください。

  • curlでの取得例 (コンテナイメージ ysakashita/swordfish-api-emulator:20180801)
$ curl -X GET http://swordfish.192.168.99.137.nip.io/redfish/v1/StorageServices |jq
...
{
  "@Redfish.Copyright": "Copyright 2015-2016 SNIA. All rights reserved.",
  "@odata.context": "/redfish/v1/$metadata#StorageService.StorageService",
  "@odata.id": "/redfish/v1/StorageServices",
  "@odata.type": "#StorageServiceCollection.1.0.0.StorageServiceCollection",
  "Members": [
    {
      "@odata.id": "/redfish/v1/StorageServices/1"
    },
    {
      "@odata.id": "/redfish/v1/StorageServices/2"
    }
  ],
  "Members@odata.count": 2,
  "Name": "Storage Service Collection"
}

$ curl -X GET http://swordfish.192.168.99.137.nip.io/redfish/v1/StorageServices/1 |jq
...
{
  "@Redfish.Copyright": "Copyright 2014-2016 SNIA. All rights reserved.",
  "@odata.context": "/redfish/v1/$metadata#StorageServices/1",
  "@odata.id": "/redfish/v1/StorageServices/1",
  "@odata.type": "#StorageService.1.0.0.StorageService",
  "ClassesOfService": {
    "@odata.id": "/redfish/v1/StorageServices/1/ClassesOfService"
  },
  "ClientEndpointGroups": {
    "@odata.id": "/redfish/v1/StorageServices/1/ClientEndpointGroups"
  },
  "Description": "Description of storage",
  "Drives": {
    "@odata.id": "/redfish/v1/StorageServices/1/Drives"
  },
  "Endpoints": {
    "@odata.id": "/redfish/v1/StorageServices/1/Endpoints"
  },
  "Id": "1",
  "Links": {
    "DataProtectionLoSCapabilities": {
      "@odata.id": "/redfish/v1/StorageServices/1/DataProtectionLoSCapabilities"
    },
    "DataSecurityLoSCapabilities": {
      "@odata.id": "/redfish/v1/StorageServices/1/DataSecurityLoSCapabilities"
    },
    "DataStorageLoSCapabilities": {
      "@odata.id": "/redfish/v1/StorageServices/1/DataStorageLoSCapabilities"
    },
    "Enclosures": {
      "@odata.id": "/redfish/v1/Chassis/1"
    },
    "HostingSystem": {
      "@odata.id": "/redfish/v1/Systems/Complex"
    },
    "IOConnectivityLoSCapabilities": {
      "@odata.id": "/redfish/v1/StorageServices/1/IOConnectivityLoSCapabilities"
    },
    "IOPerformanceLoSCapabilities": {
      "@odata.id": "/redfish/v1/StorageServices/1/IOPerformanceLoSCapabilities"
    }
  },
  "Name": "My Storage Service",
  "Oem": {},
  "ServerEndpointGroups": {
    "@odata.id": "/redfish/v1/StorageServices/1/ServerEndpointGroups"
  },
  "Status": {
    "Health": "OK",
    "State": "Enabled"
  },
  "StorageGroups": {
    "@odata.id": "/redfish/v1/StorageServices/1/StorageGroups"
  },
  "StoragePools": {
    "@odata.id": "/redfish/v1/StorageServices/1/StoragePools"
  },
  "StorageSubsystems": {
    "@odata.id": "/redfish/v1/StorageServices/1/StorageSubsystems"
  },
  "Volumes": {
    "Members": [
      {
        "@odata.id": "/redfish/v1/StorageServices/1/Volumes"
      }
    ]
  }
}

$ curl -X GET http://swordfish.192.168.99.137.nip.io/redfish/v1/StorageServices/1/Volumes |jq
...
{
  "@Redfish.Copyright": "Copyright 2014-2016 SNIA. All rights reserved.",
  "@odata.context": "/redfish/v1/$metadata#VolumeCollection.VolumeCollection",
  "@odata.id": "/redfish/v1/StorageServices/1/Volumes",
  "@odata.type": "#VolumeCollection_1_0_0.VolumeCollection",
  "Members": [
    {
      "@odata.id": "/redfish/v1/StorageServices/1/Volumes/61001234876545676100123487654567"
    },
    {
      "@odata.id": "/redfish/v1/StorageServices/1/Volumes/65456765456761001234876100123487"
    },
    {
      "@odata.id": "/redfish/v1/StorageServices/1/Volumes/3"
    },
    {
      "@odata.id": "/redfish/v1/StorageServices/1/Volumes/4"
    },
    {
      "@odata.id": "/redfish/v1/StorageServices/1/Volumes/5"
    },
    {
      "@odata.id": "/redfish/v1/StorageServices/1/Volumes/6"
    }
  ],
  "Members@odata.count": 6,
  "Name": "Volumes",
  "Permissions": [
    {
      "Read": "True"
    },
    {
      "Write": "True"
    }
  ]
}

$ curl -X GET http://swordfish.192.168.99.137.nip.io/redfish/v1/StorageServices/1/Volumes/61001234876545676100123487654567 |jq
...
{
  "@Redfish.Copyright": "Copyright 2014-2016 SNIA. All rights reserved.",
  "@odata.context": "/redfish/v1/$metadata#Volume.Volume",
  "@odata.id": "/redfish/v1/StorageServices/1/Volumes/61001234876545676100123487654567",
  "@odata.type": "#Volume_1_0_0.Volume",
  "AccessCapabilities": [
    "Read",
    "Write"
  ],
  "BlockSizeBytes": 512,
  "Capacity": {
    "Data": {
      "AllocatedBytes": 10737418240,
      "ConsumedBytes": 0,
      "GuaranteedBytes": 536870912,
      "ProvisionedBytes": 1099511627776
    },
    "Metadata": {
      "AllocatedBytes": 536870912,
      "ConsumedBytes": 536870912,
      "GuaranteedBytes": 536870912,
      "ProvisionedBytes": 2199023255552
    },
    "Snapshot": {
      "AllocatedBytes": 21474836480,
      "ConsumedBytes": 0,
      "GuaranteedBytes": 536870912,
      "ProvisionedBytes": 2199023255552
    }
  },
  "CapacitySources": [
    {
      "Links": {
        "ClassOfService": {
          "@odata.id": "/redfish/v1/StorageServices/1/ClassesOfService/GoldBoston"
        },
        "ProvidingPool": {
          "Members": [
            {
              "@odata.id": "/redfish/v1/StorageServices/1/StoragePools/BasePool"
            }
          ]
        },
        "ProvidingVolume": null
      },
      "ProvidedCapacity": {
        "AllocatedBytes": 140759500062720,
        "ConsumedBytes": 70390755885056,
        "GuaranteedBytes": 17592722915328,
        "ProvisionedBytes": 565148976676864
      }
    }
  ],
  "Description": "Bob's Pizza Recipe",
  "Id": "61001234876545676100123487654567",
  "Identifiers": [
    {
      "DurableName": "61001234876545676100123487654567",
      "DurableNameFormat": "NAA6"
    }
  ],
  "LowSpaceWarningThresholdPercent": [
    70,
    80,
    90,
    null,
    null
  ],
  "Manufacturer": "SuperDuperStorageProvider",
  "Model": "Drive Model string",
  "Name": "Volume 1",
  "Status": {
    "Health": "Warning",
    "State": "Enabled"
  }
}

感想

今回は、SNIA日本支部の活動で、Swordfishを紹介する機会があったため、これにあわせてコンテナイメージを用意しました。Swordfish-API-Emulatorのドキュメントでは、Windowsの場合のセットアップしか記載がなくPythonのパッケージもセットアップが必要だったため、PCの環境を汚さないためにコンテナイメージを作りました。これによりWindows以外のOSを利用されている方や事前セットアップが面倒な方などでも、手軽にSwordfish-API-Emulatorが試せるかと思いますので、興味のある方は触ってみてください。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?