NVMeとConnectX-4で始めるNVMe over RDMA (RoCEv2)入門

目次

概要

近年、NVMe over Fabric (=NVMeoF) という言葉をよく聞くようになりました。
この Fabric 自体は NVMe のプロトコルをネットワーク上に流すことでリモートホスト上からターゲットホストの NVMe Disk に直接IO操作を行うものです。
同じような目的を持ったプロトコルとしては iSCSI などがあげられます。
しかし、SCSI 自体が近年目覚ましく進化したフラッシュストレージ (=SSD) の性能に追いつけていないのが現状です。
この問題に対処するため、より効率的なプロトコルとして新たに NVMe プロトコルが策定されました。
NVMe over Fabric は効率的な NVMe プロトコルを利用することにより iSCSI よりも高速にIOを裁くことができるメリットがあり、注目されています。

NVMe over Fabric は通信に使用するプロトコルとして Infiniband や Ethernet 、さらには FibreChannel を選択することができます。
加えて、RDMA(=Remote Direct Memory Access) などの技術を用いることでより高速・低遅延を実現しています。

RDMA 自体は Infiniband の技術です。
しかし、RDMA を Ethernet 上で利用するための技術として、RoCE (RDMA over Converged Ethernet) があります。
この RoCE は v1 と v2 が存在し、RoCEv1 は Link Layer のプロトコルであるため異なるネットワークセグメント間において接続することができませんでした。
しかし RoCEv2 では Internet Layer のプロトコルとなったため、ルーティングが可能となり、異なるネットワークセグメント間においても使用することができるようになりました。

まとめると、低遅延でかつより高速にリモートホスト上の NVMe にアクセスするための技術として、NVMe over RDMA があり、これを Ethernet 上で利用するために RoCEv2を用いる必要があるということです。

また、RoCE 自体は途中経路上のスイッチにも設定が必要です。
このため、RDMA を用いずに TCP で直接接続するプロトコルとして、NVMe over TCP が存在します。
しかし、Mellanox (NVIDIA) の ConnectX-4 以降においてはスイッチの設定を不要とする Zero Touch RoCE が使用でき、より簡単に環境構築が可能となりました。

今回はそんな ConnectX-4 を用いながら、実際に NVMe over RDMA (RoCEv2) な環境を構築し、軽くパフォーマンスなどを見ていきます。
(NVMe over TCPについては後日検証します。)

環境

今回の検証に使用した環境です。
マシンは2台用意し、それぞれをターゲット(Server)側、Initiator(Client)側としています。

ターゲット側

詳細
Machine HPE ProLiant DL380 Gen10
CPU Intel Xeon Silver 4208 x2
Memory DDR4 ECC RDIMM 128GB (16GB x8 2400MHz)
NIC Mellanox ConnectX-4 100Gb(Ethernet) MCX415A-CCAT
NVMe Intel DC P4600 1.6TB U.2 x2
OS Ubuntu Server 22.04 LTS

Initiator側

詳細
Machine Fujitsu Primergy RX2540 M4
CPU Intel Xeon Gold 6148 x1
Memory DDR4 ECC RDIMM 128GB (32GB x4 2666MHz)
NIC Mellanox ConnectX-4 100Gb(Ethernet) MCX415A-CCAT
OS Ubuntu Server 22.04 LTS

Mellanoxドライバのインストール

事前に、RDMAに対応した Mellanox ドライバである OFED をインストールしておく必要があります。
ドライバは公式サイトからダウンロードできます。

# tar -xzvf MLNX_OFED_LINUX-5.6-2.0.9.0-ubuntu22.04-x86_64.tgz
# cd MLNX_OFED_LINUX-5.6-2.0.9.0-ubuntu22.04-x86_64
# ./mlnxofedinstall --with-nvmf
# /etc/init.d/openibd restart

インストール完了後、念のために initramfs を更新しておきます。
しなかった場合、この後に行うカーネルモジュールの読み込みでエラーになる場合があります。

# update-initramfs -u
# reboot

RoCEv2サポートの確認

念のため、公式サイトを参考にNICがRoCEv2に対応していることを確認しておきます。
ネットワークインタフェース名を確認しておきます。

# cat /sys/class/infiniband/mlx5_0/ports/1/gid_attrs/ndevs/0
ens5np0
# cat /sys/class/infiniband/mlx5_0/ports/1/gid_attrs/ndevs/1
ens5np0

今回は 0 と 1 が該当するものでした。
続いて、確認した情報をもとにサポートしているかどうかを確認します。

# cat /sys/class/infiniband/mlx5_0/ports/1/gid_attrs/types/0
IB/RoCE v1
# cat /sys/class/infiniband/mlx5_0/ports/1/gid_attrs/types/1
RoCE v2

RoCE v2をサポートしていることが確認できました。

カーネルモジュールのロード

ターゲット側、Initiator側の両方でカーネルモジュールを読み込んでおきます。

# modprobe mlx5_core
# lsmod | grep mlx
mlx5_ib               434176  0
ib_uverbs             135168  6 rdma_ucm,mlx5_ib
ib_core               417792  8 rdma_cm,ib_ipoib,iw_cm,ib_umad,rdma_ucm,ib_uverbs,mlx5_ib,ib_cm
mlx5_core            1888256  1 mlx5_ib
mlxdevm               172032  1 mlx5_core
mlxfw                  32768  1 mlx5_core
psample                20480  1 mlx5_core
tls                   106496  2 bonding,mlx5_core
mlx_compat             69632  11 rdma_cm,ib_ipoib,mlxdevm,iw_cm,ib_umad,ib_core,rdma_ucm,ib_uverbs,mlx5_ib,ib_cm,mlx5_core
pci_hyperv_intf        16384  1 mlx5_core
# modprobe nvmet
# modprobe nvmet-rdma
# modprobe nvme-rdma
# lsmod | grep nvme
nvme_rdma              40960  0
nvme_fabrics           24576  1 nvme_rdma
nvmet_rdma             57344  0
nvmet                 135168  1 nvmet_rdma
rdma_cm               122880  3 nvme_rdma,nvmet_rdma,rdma_ucm
ib_core               417792  10 rdma_cm,ib_ipoib,nvme_rdma,nvmet_rdma,iw_cm,ib_umad,rdma_ucm,ib_uverbs,mlx5_ib,ib_cm
nvme                   49152  2 nvmet,nvmet_rdma
nvme_core             122880  4 nvmet,nvme,nvme_rdma,nvme_fabrics
mlx_compat             69632  17 rdma_cm,ib_ipoib,mlxdevm,nvmet,nvme,nvme_rdma,nvmet_rdma,iw_cm,nvme_core,nvme_fabrics,ib_umad,ib_core,rdma_ucm,ib_uverbs,mlx5_ib,ib_cm,mlx5_core

ネットワーク設定

この段階でネットワーク設定を行っておきます。
手順については省略します。
なお、今回は次のような構成にしています。

ターゲット側 10.0.0.1/24 ---------- 10.0.0.2/24 Initiator側

nvme-cliのインストール

ターゲット側とInitiator側の両方に nvme-cli をインストールしておきます。

# apt install nvme-cli

ターゲット側の設定

今回は、ターゲット側のソフトウェアとして SPDK (=Storage Performance Development Kit) を用います。
git から clone してビルドします。

root@target:~# git clone https://github.com/spdk/spdk
root@target:~# cd spdk/
root@target:~/spdk# git submodule update --init
root@target:~/spdk# scripts/pkgdep.sh --rdma
root@target:~/spdk# ./configure --with-rdma --enable-debug
root@target:~/spdk# make

テストを実施しておきます。
All unit tests passed の表示を確認できればOKです。

root@target:~/spdk# ./test/unit/unittest.sh
<省略>
=====================
All unit tests passed
=====================
WARN: lcov not installed or SPDK built without coverage!
WARN: neither valgrind nor ASAN is enabled!

テストをパスしたことが確認出来たら、NVMeドライバの変更を行います。
変更には、SPDK 内の setup.sh を用います。
先に現在の状態を確認します。

root@dev0003:~/spdk# scripts/setup.sh status
Hugepages
node     hugesize     free /  total
node0   1048576kB        0 /      0
node0      2048kB        0 /      0
node1   1048576kB        0 /      0
node1      2048kB        0 /      0

Type     BDF             Vendor Device NUMA    Driver           Device     Block devices
I/OAT    0000:00:04.0    8086   2021   0       ioatdma          -          -
I/OAT    0000:00:04.1    8086   2021   0       ioatdma          -          -
I/OAT    0000:00:04.2    8086   2021   0       ioatdma          -          -
I/OAT    0000:00:04.3    8086   2021   0       ioatdma          -          -
I/OAT    0000:00:04.4    8086   2021   0       ioatdma          -          -
I/OAT    0000:00:04.5    8086   2021   0       ioatdma          -          -
I/OAT    0000:00:04.6    8086   2021   0       ioatdma          -          -
I/OAT    0000:00:04.7    8086   2021   0       ioatdma          -          -
NVMe     0000:39:00.0    8086   0a54   0       nvme             nvme0      nvme0n1
NVMe     0000:3a:00.0    8086   0a54   0       nvme             nvme1      nvme1n1
I/OAT    0000:80:04.0    8086   2021   1       ioatdma          -          -
I/OAT    0000:80:04.1    8086   2021   1       ioatdma          -          -
I/OAT    0000:80:04.2    8086   2021   1       ioatdma          -          -
I/OAT    0000:80:04.3    8086   2021   1       ioatdma          -          -
I/OAT    0000:80:04.4    8086   2021   1       ioatdma          -          -
I/OAT    0000:80:04.5    8086   2021   1       ioatdma          -          -
I/OAT    0000:80:04.6    8086   2021   1       ioatdma          -          -
I/OAT    0000:80:04.7    8086   2021   1       ioatdma          -          -

現在はカーネル上の ioatdma や nvme で制御が行われていることがわかります。
続いて、念のため NVMe をフォーマットして初期化しておきます。
検証環境では、以前ブロックデバイスとして使用していたディスクを使用したためか、この後の操作で Active devices: data@nvme0n1, so not binding PCI dev といったような表示となりドライバの変更を行うことが出来ませんでした。
フォーマットは次のコマンドで実施できます。
(使用するすべてのNVMeに対して実施しました。)

root@target:~# nvme format /dev/nvme0n1

先ほどの setup.sh をオプションなしで実行することで uio_pci_generic に変更します。

root@target:~/spdk# scripts/setup.sh
0000:39:00.0 (8086 0a54): nvme -> uio_pci_generic
0000:3a:00.0 (8086 0a54): nvme -> uio_pci_generic
0000:00:04.7 (8086 2021): ioatdma -> uio_pci_generic
0000:00:04.6 (8086 2021): ioatdma -> uio_pci_generic
0000:00:04.5 (8086 2021): ioatdma -> uio_pci_generic
0000:00:04.4 (8086 2021): ioatdma -> uio_pci_generic
0000:00:04.3 (8086 2021): ioatdma -> uio_pci_generic
0000:00:04.2 (8086 2021): ioatdma -> uio_pci_generic
0000:00:04.1 (8086 2021): ioatdma -> uio_pci_generic
0000:00:04.0 (8086 2021): ioatdma -> uio_pci_generic
0000:80:04.7 (8086 2021): ioatdma -> uio_pci_generic
0000:80:04.6 (8086 2021): ioatdma -> uio_pci_generic
0000:80:04.5 (8086 2021): ioatdma -> uio_pci_generic
0000:80:04.4 (8086 2021): ioatdma -> uio_pci_generic
0000:80:04.3 (8086 2021): ioatdma -> uio_pci_generic
0000:80:04.2 (8086 2021): ioatdma -> uio_pci_generic
0000:80:04.1 (8086 2021): ioatdma -> uio_pci_generic
0000:80:04.0 (8086 2021): ioatdma -> uio_pci_generic

変更が行われたか確認しておきます。
uio_pci_generic になっていればOKです。

root@target:~/spdk# scripts/setup.sh status
Hugepages
node     hugesize     free /  total
node0   1048576kB        0 /      0
node0      2048kB     1024 /   1024
node1   1048576kB        0 /      0
node1      2048kB        0 /      0

Type     BDF             Vendor Device NUMA    Driver           Device     Block devices
I/OAT    0000:00:04.0    8086   2021   0       uio_pci_generic  -          -
I/OAT    0000:00:04.1    8086   2021   0       uio_pci_generic  -          -
I/OAT    0000:00:04.2    8086   2021   0       uio_pci_generic  -          -
I/OAT    0000:00:04.3    8086   2021   0       uio_pci_generic  -          -
I/OAT    0000:00:04.4    8086   2021   0       uio_pci_generic  -          -
I/OAT    0000:00:04.5    8086   2021   0       uio_pci_generic  -          -
I/OAT    0000:00:04.6    8086   2021   0       uio_pci_generic  -          -
I/OAT    0000:00:04.7    8086   2021   0       uio_pci_generic  -          -
NVMe     0000:39:00.0    8086   0a54   0       uio_pci_generic  -          -
NVMe     0000:3a:00.0    8086   0a54   0       uio_pci_generic  -          -
I/OAT    0000:80:04.0    8086   2021   1       uio_pci_generic  -          -
I/OAT    0000:80:04.1    8086   2021   1       uio_pci_generic  -          -
I/OAT    0000:80:04.2    8086   2021   1       uio_pci_generic  -          -
I/OAT    0000:80:04.3    8086   2021   1       uio_pci_generic  -          -
I/OAT    0000:80:04.4    8086   2021   1       uio_pci_generic  -          -
I/OAT    0000:80:04.5    8086   2021   1       uio_pci_generic  -          -
I/OAT    0000:80:04.6    8086   2021   1       uio_pci_generic  -          -
I/OAT    0000:80:04.7    8086   2021   1       uio_pci_generic  -          -

続いて、ターゲットプログラムを起動します。
なお、この後の作業では Shell が最低2つ必要になりますので、事前に用意しておくことをおすすめします。

root@target:~/spdk# ./build/bin/nvmf_tgt

起動したら、もう一方の Shell で設定を投入していきます。
まず初めに、RDMA の設定を投入します。
次のコマンドは、I/O ユニットサイズを 8192byte 、最大 I/O ユニットサイズを 131072 、カプセル内のデータサイズを 8192byte としています。

root@dev0003:~/spdk# scripts/rpc.py nvmf_create_transport -t RDMA -u 8192 -i 131072 -c 8192

続いて、ブロックデバイスの設定を行います。
SPDK では Malloc を使用して RAM ディスクを作成して試すこともできます。
ここでは、両方の手順について記述しておきます。

Malloc を使用する場合

root@target:~/spdk# scripts/rpc.py bdev_malloc_create -b Malloc0 512 512
Malloc0
root@target:~/spdk# scripts/rpc.py nvmf_create_subsystem nqn.2016-06.io.spdk:cnode1 -a -s SPDK00000000000001 -d SPDK_Controller1
root@target:~/spdk# scripts/rpc.py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 Malloc0
root@target:~/spdk# scripts/rpc.py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t rdma -a 10.0.0.1 -s 4420

NVMe を使用する場合
bdev_nvme_attach_controller 実施時の -a オプションはPCIeのIDを指定します。
このIDは setup.sh status で確認でき、今回の例では 0000:39:00.0 または 0000:3a:00.0 です。

root@target:~/spdk# scripts/rpc.py bdev_nvme_attach_controller -b NVMe0 -a 0000:39:00.0 -t pcie
root@target:~/spdk# scripts/rpc.py bdev_nvme_get_controllers
[
  {
    "name": "nvme0",
    "ctrlrs": [
      {
        "state": "enabled",
        "trid": {
          "trtype": "PCIe",
          "traddr": "39:00.0"
        },
        "cntlid": 0,
        "host": {
          "nqn": "nqn.2014-08.org.nvmexpress:uuid:e00e3bdd-93c6-4f3b-83be-0f9965b91e97",
          "addr": "",
          "svcid": ""
        }
      }
    ]
  }
]
root@target:~/spdk# scripts/rpc.py nvmf_create_subsystem nqn.2016-06.io.spdk:cnode1 -a -s SPDK00000000000001 -d SPDK_Controller1
<ここで名前を確認しておく>
root@target:~/spdk# scripts/rpc.py bdev_get_bdevs | grep "name"
<確認した名前を使用>
root@target:~/spdk# scripts/rpc.py nvmf_subsystem_add_ns nqn.2016-06.io.spdk:cnode1 NVMe0n1
root@target:~/spdk# scripts/rpc.py nvmf_subsystem_add_listener nqn.2016-06.io.spdk:cnode1 -t rdma -a 10.0.0.1 -s 4420

双方において、listen するアドレスとして 10.0.0.1 を使用し、ポート番号は 4420 を使用していますが、それぞれを環境に合わせて変更してください。
(なお、本来であればポート番号はRoCEv2用にIANAで予約された 4791 を使用するべきだと思います。)

ここからの手順は NVMe を使用した場合の例です。手順は同様ですが、表示が若干異なる場合があります。

ここまでの設定は nvmf_tgt を停止すると初期化されてしまうため、エクスポートしておきます。

root@target:~/spdk# scripts/rpc.py save_config > setting.json

エクスポートした設定は nvmf_tgt を起動する際に読み込ませることができます。

root@target:~/spdk# ./build/bin/nvmf_tgt -c setting.json

Initiator側の設定

Initiator 側で Discover を実施して検出できるか確認します。

root@initiator:~# nvme discover -t rdma -a 10.0.0.1 -s 4420

Discovery Log Number of Records 1, Generation counter 1
=====Discovery Log Entry 0======
trtype:  rdma
adrfam:  ipv4
subtype: nvme subsystem
treq:    not required
portid:  0
trsvcid: 4420
subnqn:  nqn.2016-06.io.spdk:cnode1
traddr:  10.0.0.1
rdma_prtype: not specified
rdma_qptype: connected
rdma_cms:    rdma-cm
rdma_pkey: 0x0000

無事検出出来たので、接続します。

root@initiator:~# nvme connect -t rdma -n "nqn.2016-06.io.spdk:cnode1" -a 10.0.0.1 -s 4420

認識しているか確認します。

root@initiator:~# nvme list
Node                  SN                   Model                                    Namespace Usage                      Format           FW Rev
--------------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1          SPDK00000000000001   SPDK_Controller1                         1           1.60  TB /   1.60  TB    512   B +  0 B   22.09

無事認識していることが確認できました。

fioを用いてベンチマーク

Initiator 側から NVMe に IO 負荷をかけてベンチマークを実施します。
ベンチマークには fio を用います。

root@initiator:~# apt install fio

シーケンシャルリードでベンチマークをまわしてみます。

root@initiator:~# fio --name=seqread --rw=read --filename=/dev/nvme0n1 --direct=1 --ioengine=libaio --bs=32m --numjobs=2 --size=10G --group_reporting
seqread: (g=0): rw=read, bs=(R) 32.0MiB-32.0MiB, (W) 32.0MiB-32.0MiB, (T) 32.0MiB-32.0MiB, ioengine=libaio, iodepth=1
...
fio-3.28
Starting 2 processes
Jobs: 2 (f=2): [R(2)][100.0%][r=3200MiB/s][r=100 IOPS][eta 00m:00s]
seqread: (groupid=0, jobs=2): err= 0: pid=3997: Sun Jun 26 07:40:59 2022
  read: IOPS=100, BW=3222MiB/s (3378MB/s)(20.0GiB/6357msec)
    slat (usec): min=7776, max=17896, avg=10373.59, stdev=1942.05
    clat (usec): min=4888, max=11913, avg=9478.44, stdev=1901.61
     lat (usec): min=17439, max=22960, avg=19853.26, stdev=319.36
    clat percentiles (usec):
     |  1.00th=[ 5342],  5.00th=[ 6456], 10.00th=[ 7635], 20.00th=[ 7898],
     | 30.00th=[ 8029], 40.00th=[ 8160], 50.00th=[ 8586], 60.00th=[11076],
     | 70.00th=[11338], 80.00th=[11469], 90.00th=[11600], 95.00th=[11731],
     | 99.00th=[11863], 99.50th=[11863], 99.90th=[11863], 99.95th=[11863],
     | 99.99th=[11863]
   bw (  MiB/s): min= 3200, max= 3328, per=99.99%, avg=3221.33, stdev=24.36, samples=24
   iops        : min=  100, max=  104, avg=100.67, stdev= 0.76, samples=24
  lat (msec)   : 10=53.75%, 20=46.25%
  cpu          : usr=0.19%, sys=14.35%, ctx=10189, majf=0, minf=16408
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=640,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
   READ: bw=3222MiB/s (3378MB/s), 3222MiB/s-3222MiB/s (3378MB/s-3378MB/s), io=20.0GiB (21.5GB), run=6357-6357msec

Disk stats (read/write):
  nvme0n1: ios=0/0, merge=0/0, ticks=0/0, in_queue=0, util=0.00%

3.3GB/s となっており、これは使用したNVMeの公称値とほぼ同様です。

続いて、シーケンシャルライトを試します。

root@initiator:~# fio --name=seqwrite --rw=write --filename=/dev/nvme0n1 --direct=1 --ioengine=libaio --bs=32m --numjobs=2 --size=10G --group_reporting
seqwrite: (g=0): rw=write, bs=(R) 32.0MiB-32.0MiB, (W) 32.0MiB-32.0MiB, (T) 32.0MiB-32.0MiB, ioengine=libaio, iodepth=1
...
fio-3.28
Starting 2 processes
Jobs: 2 (f=2): [W(2)][100.0%][w=1345MiB/s][w=42 IOPS][eta 00m:00s]
seqwrite: (groupid=0, jobs=2): err= 0: pid=4369: Sun Jun 26 08:39:02 2022
  write: IOPS=40, BW=1303MiB/s (1366MB/s)(20.0GiB/15720msec); 0 zone resets
    slat (usec): min=10077, max=40126, avg=24915.36, stdev=5671.09
    clat (usec): min=10707, max=43728, avg=24162.18, stdev=5742.35
     lat (usec): min=30520, max=65408, avg=49078.53, stdev=3970.34
    clat percentiles (usec):
     |  1.00th=[12125],  5.00th=[13960], 10.00th=[16909], 20.00th=[19268],
     | 30.00th=[20579], 40.00th=[22414], 50.00th=[23987], 60.00th=[26084],
     | 70.00th=[27919], 80.00th=[29754], 90.00th=[31327], 95.00th=[32637],
     | 99.00th=[35914], 99.50th=[37487], 99.90th=[43779], 99.95th=[43779],
     | 99.99th=[43779]
   bw (  MiB/s): min= 1152, max= 1408, per=99.99%, avg=1302.71, stdev=33.82, samples=62
   iops        : min=   36, max=   44, avg=40.71, stdev= 1.06, samples=62
  lat (msec)   : 20=26.56%, 50=73.44%
  cpu          : usr=3.30%, sys=3.68%, ctx=10582, majf=0, minf=19
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,640,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
  WRITE: bw=1303MiB/s (1366MB/s), 1303MiB/s-1303MiB/s (1366MB/s-1366MB/s), io=20.0GiB (21.5GB), run=15720-15720msec

Disk stats (read/write):
  nvme0n1: ios=0/0, merge=0/0, ticks=0/0, in_queue=0, util=0.00%

こちらも 1.3GB/s となっており公称値と同等です。

EthernetSwitchを挟む

NVMeをもう1台分設定したうえで、経路上に Ethernet Switch を挟んでみます。
使用する Switch は Azure/SONiC を搭載したホワイトボックススイッチです。

ブロックデバイスの設定と同様の手順をターゲット側に実施し、NVMeの設定を追加しておきます。
追加後の Initiator 側からの Discover 結果は次のようになります。

root@initiator:~# nvme discover -t rdma -a 10.0.0.1 -s 4420

Discovery Log Number of Records 2, Generation counter 2
=====Discovery Log Entry 0======
trtype:  rdma
adrfam:  ipv4
subtype: nvme subsystem
treq:    not required
portid:  0
trsvcid: 4420
subnqn:  nqn.2016-06.io.spdk:cnode1
traddr:  10.0.0.1
rdma_prtype: not specified
rdma_qptype: connected
rdma_cms:    rdma-cm
rdma_pkey: 0x0000
=====Discovery Log Entry 1======
trtype:  rdma
adrfam:  ipv4
subtype: nvme subsystem
treq:    not required
portid:  0
trsvcid: 4420
subnqn:  nqn.2016-06.io.spdk:cnode2
traddr:  10.0.0.1
rdma_prtype: not specified
rdma_qptype: connected
rdma_cms:    rdma-cm
rdma_pkey: 0x0000

2つの NVMe を認識していることがわかります。
本来であれば Switch 側に QoS 等の設定が必要なはずですが、今回使用した ConnectX-4 の Zero Touch RoCEv2 によって Switch 側の設定なしに機能しているようです。

複数のInitiatorからIO負荷をかける

複数の Intiator でそれぞれ1台ずつ NVMe を接続した状態で同時に IO 負荷をかけてみます。
結果は次のようになりました。

Initiator 1 : Run status group 0 (all jobs):
   READ: bw=3221MiB/s (3377MB/s), 3221MiB/s-3221MiB/s (3377MB/s-3377MB/s), io=200GiB (215GB), run=63589-63589msec
Initiator 2 : Run status group 0 (all jobs):
   READ: bw=3223MiB/s (3380MB/s), 3223MiB/s-3223MiB/s (3380MB/s-3380MB/s), io=200GiB (215GB), run=63538-63538msec

それぞれのディスクで 3.3GB/s を確認できます。
この程度では特に問題なく動作するようです。
この時、 Switch 側のトラフィック量は次のようになっていました。

admin@sonic:~$ show interfaces counters
      IFACE    STATE       RX_OK        RX_BPS    RX_UTIL    RX_ERR    RX_DRP    RX_OVR       TX_OK        TX_BPS    TX_UTIL    TX_ERR    TX_DRP    TX_OVR
-----------  -------  ----------  ------------  ---------  --------  --------  --------  ----------  ------------  ---------  --------  --------  --------
  Ethernet0        U  51,631,461  6616.61 MB/s     52.93%         0         2         0   4,696,866    13.35 MB/s      0.11%         0         0         0
  Ethernet4        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0
  Ethernet8        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0
 Ethernet12        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0
 Ethernet16        U   2,788,576  6529.03 KB/s      0.05%         0         0         0  31,156,784  3302.67 MB/s     26.42%         0         0         0
 Ethernet20        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0
 Ethernet24        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0
 Ethernet28        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0
 Ethernet32        U   1,907,040  6825.01 KB/s      0.05%         0         0         0  20,460,390  3315.02 MB/s     26.52%         0         0         0
 Ethernet36        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0
 Ethernet40        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0
 Ethernet44        D           0      0.00 B/s      0.00%         0         0         0           0      0.00 B/s      0.00%         0         0         0

Ethernet0 がターゲット側のインタフェースであり、 6.6GB/s を観測しており、先ほどのベンチマーク結果と一致しています。

まとめ

今回は、SPDK を利用して NVMe over RDMA ターゲットを構築するとともに、Initiator から接続を行って検証を行うとともに、簡単なパフォーマンス測定を行いました。
検証に使用した環境では十分に性能が発揮できているようです。
後日、NVMe over TCP の検証も行う予定なので、その際にベンチマーク結果などを確認できればと思います。

100GbEを試す Mellanox ConnectX-4 + 100G-CWDM4

目次

背景

前回はお借りした機材を利用して100GbEをテストしました。
今回は、手元に Mellanox ConnectX-4 があったので、こちらを再度簡単にテストしてみることにします。

検証機材

今回は、NICとケーブルを前回と異なるものでテストします。
(ちなみに前回はお借りした機材でしたが今回はすべて私物です。)

詳細
Machine Fujitsu Primergy CX2550 M2
CPU Intel Xeon E5-2690v4 x2
Memory DDR4 ECC RDIMM 128GB
NIC Mellanox ConnectX-4 100Gb(Ethernet) MCX415A-CCAT
Cable Intel QSFP28 100G-CWDM4 module (SPTSBP2CLCKS)
OS Ubuntu Server 20.04.4 LTS

Mellanox ConnectX-4 MCX415A-CCAT

Intel QSFP28 100G-CWDM4 module

準備

初めに、ドライバをインストールします。
手順は前回と同様です。
Mellanoxのドライバは公式サイトからダウンロードできます。

IPアドレスについて、前回と同様に 10.0.0.1/2410.0.0.2/24 を使用し、以下のように直結することにします。

10.0.0.1/24 ---------- 10.0.0.2/24

設定はnetplanを用いて行いました。

2つのNIC間は100G-CWDM4モジュールとシングルモードファイバー(duplex)を用いて接続しました。

リンクアップを確認

ethtool コマンドを用いて、100Gbpsでリンクアップしているか確認します。

$ ethtool ens11np0
Settings for ens11np0:
        Supported ports: [ FIBRE ]
        Supported link modes:   1000baseKX/Full
                                10000baseKR/Full
                                40000baseKR4/Full
                                40000baseCR4/Full
                                40000baseSR4/Full
                                40000baseLR4/Full
                                25000baseCR/Full
                                25000baseKR/Full
                                25000baseSR/Full
                                50000baseCR2/Full
                                50000baseKR2/Full
                                100000baseKR4/Full
                                100000baseSR4/Full
                                100000baseCR4/Full
                                100000baseLR4_ER4/Full
        Supported pause frame use: Symmetric
        Supports auto-negotiation: Yes
        Supported FEC modes: None BaseR RS
        Advertised link modes:  1000baseKX/Full
                                10000baseKR/Full
                                40000baseKR4/Full
                                40000baseCR4/Full
                                40000baseSR4/Full
                                40000baseLR4/Full
                                25000baseCR/Full
                                25000baseKR/Full
                                25000baseSR/Full
                                50000baseCR2/Full
                                50000baseKR2/Full
                                100000baseKR4/Full
                                100000baseSR4/Full
                                100000baseCR4/Full
                                100000baseLR4_ER4/Full
        Advertised pause frame use: Symmetric
        Advertised auto-negotiation: Yes
        Advertised FEC modes: RS
        Link partner advertised link modes:  Not reported
        Link partner advertised pause frame use: No
        Link partner advertised auto-negotiation: Yes
        Link partner advertised FEC modes: Not reported
        Speed: 100000Mb/s
        Duplex: Full
        Port: FIBRE
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: on
Cannot get wake-on-lan settings: Operation not permitted
        Current message level: 0x00000004 (4)
                               link
        Link detected: yes

Speed: 100000Mb/s の表示が確認でき、100Gbpsでリンクアップしていることが確認できます。

計測

計測ツールは iperf (iperf2) です。
iperf3 での計測はこの結果から今回は省略します。
今回は最初からMTU9000で計測を行います。

計測結果です。

$ iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:  128 KByte (default)
------------------------------------------------------------
[ ID] Interval       Transfer     Bandwidth
[  4] local 10.0.0.2 port 5001 connected with 10.0.0.1 port 51694
[  9] local 10.0.0.2 port 5001 connected with 10.0.0.1 port 51700
[  5] local 10.0.0.2 port 5001 connected with 10.0.0.1 port 51696
[  7] local 10.0.0.2 port 5001 connected with 10.0.0.1 port 51698
[  4]  0.0-10.0 sec  28.0 GBytes  24.1 Gbits/sec
[  9]  0.0-10.0 sec  27.8 GBytes  23.9 Gbits/sec
[  5]  0.0-10.0 sec  27.0 GBytes  23.2 Gbits/sec
[  7]  0.0-10.0 sec  28.3 GBytes  24.2 Gbits/sec
[SUM]  0.0-10.0 sec   111 GBytes  95.3 Gbits/sec

95.3Gbits/set と、おおよそ100Gbpsの速度が出ていることが確認できました。

まとめ

今回は、Mellanox ConnectX-4 NICとIntel製の100G-CWDM4モジュールを用いて100GbEのテストを行いました。
当初は100G-SR4モジュールを用いる予定でしたが、ファイバーのコストが高いため、ファイバーのコストを安く抑えられる上にモジュール単体のコストが安い100G-CWDM4モジュールを用いてテストを実施しました。

結果として、しっかり100GbEにふさわしい速度が出ていることが確認できました。
しかしながら、100G NICともなるとそれなりに発熱します。
今回検証に使用したマシンはアイドル時でも部屋のカーテンがなびくほどのファンを搭載していますが、QSFP28モジュールやNICはギリギリ触れないぐらいの温度となっていました。
一般的なPCで使用する場合には冷却方法を慎重に検討する必要がありそうです。

自宅ラック勢が語るおうちクラウド運用経験談

この記事は、CyberAgent 22 新卒 Advent Calendar 2021の19日目の記事です。

目次

概要

本記事では、自宅でサーバーやネットワーク機器を運用する筆者が、普段の運用をどのように行っているかを紹介します。
また、後半では運用していく中で発生したトラブル経験などを紹介します。

サーバーとは

サーバーと言われてどのようなものを想像するでしょうか。
一般的に、自宅サーバーなどと言われると自宅に中古のデスクトップPCなどを用意してサーバーとして運用するような形を想像する方が多いと思います。
しかし、コンピューターにはサーバー用に設計されたものが存在します。
これらはデータセンターなどで運用され、サイズ等が規格化されておりラックサーバーなどと呼ばれています。
また、これを搭載するための専用のラックが存在しており、ユニット数(U)でいくつかの種類があります。このラックを使用することで、上方向へ積み上げてサーバーを設置することが可能になります。
ラックサーバー自体は当然、一般家庭に設置することを想定したデバイスではありませんから、静音性より冷却性能の方が重要です。そのため、基本的に静音性とは無縁です。

(サーバーラックに搭載されたラックサーバーの例)

自宅サーバーを運用するメリット

では、デスクトップPCなどを使用する場合を含め自宅でサーバーを運用するメリットは何でしょうか。
まず一つ目は、学習機会を得られるということです。
AWSやGCPといったパブリッククラウドを利用するのと違い、自宅でサーバーを運用するには、物理レイヤーからすべて自分で設計や構築を行う必要があります。
パブリッククラウドが普及した近年では、手間が掛かる事から嫌厭されがちですが、学習することに重点を置けば、より多くの学習機会が得られるというメリットがあると言えます。
その中では、ネットワークに関する知識のほか、ハードウェアに関する知識も必要となります。そして、こういったレイヤーの知識は経験も重要です。この経験は、実際に運用していく中で原因切り分けなどを実施することで身に付く部分が多い分野でもあります。

もう一つは、シビアにコストを気にする必要が無くなるということです。
パブリッククラウドでは、インスタンスの起動時間や通信量による課金でコストが掛かります。例えば、パッケージを再インストールしたい場合などに、追加でコストが発生するわけです。(ローカルにキャッシュされている場合を除く)
つまり、何かを試すたびにコストが少しずつ掛かっていきます。
しかし、自宅サーバーであれば初期投資こそ掛かるものの、継続的なランニングコストは基本的には電気代のみです。
少なくとも通信量による従量課金は気にする必要はなくなるでしょう。また、24時間運用を前提としていれば、何か検証したい項目が出てきたとしてもスペックさえ余裕があれば自由に検証することができます。
ある意味定額で使えますから、従量課金を気にする必要がなくなります。

そして、パブリッククラウドでは手が出せないよなスペックのサーバーを使用することが出来るというメリットもあります。
月数万~数十万円するような構成のサーバーを、自宅サーバーであれば自由に、それも複数台使うことが出来ます。
また、Proxmoxなどを導入する事によって、簡単に仮想化基盤を構築することが出来ます。

なぜラックサーバーなのか

大きな理由の一つは、管理面です。
サーバー用に設計されたマシンでは、BMCと呼ばれるICチップが提供する管理機能が充実しています。この管理機能は、サーバー上で動作するOS等に関係なく、ネットワーク経由で電源の操作やコンソール画面の確認に加えてメモリやCPUなどのステータスやログなども確認することができます。
このような管理機能が存在することで、ネットワーク経由での管理がしやすくなります。

もう一つは、24時間365日動作し続けることが前提となっているハードウェアのため、耐久性が非常に高いことです。
加えて、ECCメモリと呼ばれるエラー訂正機能のあるメモリを使用しているため、長時間の安定した動作が期待できます。

機材選定と設計

サーバーを運用するうえで、機材の選定と設計は重要です。
筆者の環境では、機材選定時に下記の項目を重視しています。

  • 消費電力
  • 冷却ファンが発する騒音が許容範囲内か
  • CPUやメモリなどの性能
  • 拡張性や搭載可能なストレージの種類(サーバーの場合)
  • 使用可能なプロトコルやL2,L3でのパケット処理性能(ネットワーク機器の場合)

自宅でサーバーを運用する際に気を付けなければならないことは、消費電力や冷却ファンが発する騒音です。
高スペックなサーバーを運用する際は消費電力を気にしておく必要があります。
また、私のようにラックサーバーを使用する場合、多くのラックサーバーは掃除機レベルの騒音を出すため、自身の生活や近隣への影響がないか注意をしておく必要があります。

また、サーバーを使用する目的に応じてCPUやメモリなど、必要な性能を決めておく必要があります。
私の場合は基本的に仮想化基盤として使用することがほとんどです。そのため、ある程度の計算資源を持つサーバーを複数台用意して運用しています。

加えて、拡張性も重要です。
例えば、10GbE以上の高速なネットワークを構築する場合、それらの通信に必要なNIC(=ネットワークインターフェースカード)を搭載可能か確認しておく必要があります。
また、SASやU.2といったSATA以外の接続規格を持つストレージ製品を使用する場合、それらが接続可能であるか調査しておく必要があります。

(100GbEを検証したときの記事

ネットワーク機器では、使用可能なプロトコルやL2, L3でのパケット処理性能を調査しておく必要があります。
比較的安価なネットワーク機器の場合、OSPFは使用可能だがBGPは使用できないといったように、使用可能なプロトコルに制限があるケースがあります。
また、L3でのルーティング性能に限界がある場合もあります。このあたりについて、事前に調査し目的を果たせるデバイスであるかを確認したうえで入手しています。

(40GbEスイッチを検証したときの記事

構築と運用

ラックサーバーはとても重く20kg ~ 40kgの重量がある製品が多いです。
そのため、床面の耐荷重やダメージについて考慮しておく必要があります。また、重量物ですので設置の際にも注意が必要です。
私の場合、構造用合板を敷くことで荷重分散と床面へのダメージ軽減を図っています。

また、運用面においても定期的なメンテナンスは重要です。
特に物理レベルでは、埃の除去やケーブル等に過度な力が掛かっていないかなどをチェックし、事故や障害を未然に防ぎます。

現在のおうちクラウド

筆者の現在の自宅環境では、下記のような構成を運用しています。

  • サーバー8台
  • 合計352vCPU
  • 合計1.3TBメモリ
  • Enterprise SSD 20TB~

これらのサーバーはLACPによって冗長化された10GbE以上のネットワークで接続されています。
また、OpenStackをベースとする仮想化基盤として使用しており、ストレージとしてSSDを採用することでVMを快適に使用できるようにしています。
また、これだけの計算資源を持つ環境ですので、高スペックなVMを沢山建てることが出来ています。

トラブル&事件集

筆者が自宅サーバーを運用する中で経験したトラブルや事件について、抜粋して一部紹介します。

サーバー発煙事件

運用中に突然サーバーが停止し、電源の再投入を実施したところメモリのVRMと思われる部分が焼損した事件です。
半導体チップの焼ける匂いが部屋に充満した事件で、改めて安全管理について検討するきっかけとなった事件でした。
当時はヒヤヒヤしました。今だから笑って話せる事件です。

過去のまとめ

ファームウェアにバグはつきもの

プログラムは、規模が大きくなればなるほどバグが発生するリスクが高まります。ファームウェアのバグによる影響を受けたケースは何件かありますが、特に厄介だったのが特定のパケットの一部だけ破損する問題でした。
この問題は、PPP(PPPoE)パケットのうち、上りパケットだけが破損するというもので、ファームウェアをダウングレードすることで解決しました。
しかし、パケットの一部だけが破損するという厄介な状況であったため、当初はそもそもパケットが破損しているという事にたどり着くのに時間がかかったうえ、設定等を疑った為解決に時間を要した問題でした。(当時該当するバグの情報がなかった)

リンクが上がらない

SFPコネクタを使用したネットワーク接続では、対向機器との相性問題に遭遇することがしばしばあります。
特にDAC(=Direct Attach Cable)では問題が顕著に発生します。
こういった、規格上は接続可能であるのに実際にはうまく使用できないケースは、物理層では多々発生します。

パケットロスト事件

この問題は、特定の経路を通るパケットが40%程度ロストするといった問題でした。
原因は、光ファイバーでの光の受光強度が高すぎたため、物理レベルでデータが壊れることでした。
当初はMTUなどの設定を疑っていたのですが、各パラーメーターを見ているうちにFCS(=Frame Check Sequence)エラーが多発していることに気付き、光モジュールの組み合わせを変更することで解決しましたが、物理レベルでのパケット破損を初めて経験した出来事でした。

(SFP+ 光モジュール)

さいごに

筆者が自宅サーバーを運用する中で感じたメリットを踏まえて、ラックサーバーを導入した理由や運用について紹介しました。
思ったより文字ばかりになってしまったなと思っているところですが、どこにあるか分からない需要にマッチしていれば幸いです。
最後までお読みいただきありがとうございました。

EdgeRouter製品におけるIPv6トンネル接続のスループット

目次

概要

本記事では、Ubiquiti Networks社が提供するEdgeRouter製品でIPv6トンネル接続を行った場合のスループットについてまとめます。

検証機器

次のリストに示すデバイスでテストを行いました。

  • EdgeRouter-X
  • EdgeRouter-Lite
  • EdgeRouter-8
  • EdgeRouter-4

検証環境

検証に使用するトンネル接続には、IPIP6及びIP6GREを使用し、スループットの計測はiperf3を使用して計測を行いました。
構成はローカルでP2Pで接続されたIPv6ネットワーク上に検証機器で示したデバイスを接続しています。
また、対向のデバイスは一般的なラックマウントサーバにVyOSをインストールして使用し、計測上のボトルネックとならないことを確認しています。

なお、都合上、検証機器上にiperf3サーバを立てる形で計測しています。そのため、多少の負荷がルータにかかる状態である点に注意してください。

計測結果

Model IPIP6 IP6GRE 備考:CPU
EdgeRouter-X 136Mbps 138Mbps MediaTek MT7621AT (880 MHz, 2 cores)
EdgeRouter-Lite 85Mbps 84Mbps Cavium CN5020 (500 MHz, 2 cores)
EdgeRouter-8 243Mbps 246Mbps Cavium CN6120 (880 MHz, 2 cores)
EdgeRouter-4 912Mbps 914Mbps Cavium CN7130 (1 GHz, 4 cores)

まとめ

計測結果より、搭載されているCPUの世代やクロックがスループットに大きく影響していることが読み取れます。
加えて、EdgeRouter-4はファンレスで消費電力もEdgeRouter-8と比べると各段と少なく、とにかく性能が欲しい場合には選択肢の1つとなるでしょう。
もちろん、国内でも容易に入手可能で安価なEdgeRouter-Xでもそれなりのスループットが確保できると言えるため、選択肢として十分有力でしょう。

参考になれば幸いです。

NTT西日本 フレッツ光でNGN網内のRTT計測結果

目次

概要

フレッツ光を契約し、フレッツ・v6オプションを申し込むことで利用できるNGN網内での通信について、RTT(ラウンドトリップタイム)を計測したので、その結果をまとめます。

計測環境

  • エリア:NTTフレッツ西日本管内
  • 計測拠点:
    • 京都府京都市内A(以下KYT-Aと表記)
    • 京都府京都市内B(以下KYT-Bと表記)
    • 京都府京都市内C(以下KYT-Cと表記)
    • 大阪府南部(以下OSKと表記)
    • 島根県松江市(以下SMNと表記)

なお、拠点「KYT-A」及び拠点「KYT-B」については、地理的状況から同じ局舎へ収容されているものと推定しています。
加えて、諸事情により全拠点間を網羅的にテストはしていません。

計測方法

  • フレッツ・v6オプションによるIPv6アドレスを収容しているルータ機器間で、ICMPを用いて計測
  • 特に明記がない場合はすべてIPv6のみで通信
  • ICMPでのテストは各10回実行(-cオプションで10を指定)

京都府内での計測結果

まず、地理的に同じ局舎へ収容されていると推定される拠点「KYT-A」と拠点「KYT-B」間での計測結果が次のようになります。

$ sudo ping6 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX -c 10
PING 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX(240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX) 56 data bytes
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=1 ttl=61 time=2.35 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=2 ttl=61 time=2.23 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=3 ttl=61 time=2.80 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=4 ttl=61 time=2.38 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=5 ttl=61 time=2.39 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=6 ttl=61 time=2.42 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=7 ttl=61 time=2.97 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=8 ttl=61 time=2.83 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=9 ttl=61 time=3.02 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=10 ttl=61 time=2.76 ms

--- 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9014ms
rtt min/avg/max/mdev = 2.236/2.619/3.029/0.277 ms

平均値が 2.619ms となっています。

続いて、拠点「KYT-A」と拠点「KYT-C」間での計測結果です。

$ sudo ping6 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX -c 10
PING 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX(2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX) 56 data bytes
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=1 ttl=61 time=2.76 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=2 ttl=61 time=2.40 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=3 ttl=61 time=2.74 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=4 ttl=61 time=2.79 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=5 ttl=61 time=2.69 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=6 ttl=61 time=2.18 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=7 ttl=61 time=2.73 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=8 ttl=61 time=2.78 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=9 ttl=61 time=2.20 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=10 ttl=61 time=2.81 ms

--- 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9014ms
rtt min/avg/max/mdev = 2.188/2.612/2.813/0.240 ms

平均値が 2.612ms となっています。

最後に、拠点「KYT-B」と拠点「KYT-C」間での計測結果です。

$ sudo ping6 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX -c 10
PING 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX(240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX) 56 data bytes
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=1 ttl=61 time=2.65 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=2 ttl=61 time=2.65 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=3 ttl=61 time=2.79 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=4 ttl=61 time=3.24 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=5 ttl=61 time=2.77 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=6 ttl=61 time=3.18 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=7 ttl=61 time=2.66 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=8 ttl=61 time=2.79 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=9 ttl=61 time=3.21 ms
64 bytes from 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=10 ttl=61 time=2.68 ms
--- 240b:250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9011ms
rtt min/avg/max/mdev = 2.654/2.866/3.245/0.241 ms

平均値が 2.866ms となっています。

京都大阪間での計測結果

拠点「KYT-A」と拠点「OSK」間での計測結果です。
大阪側の計測拠点は「大阪府南部地域」にあります。京都市内-大阪市内間のおおよそ2倍の物理的距離があります。

$ sudo ping6 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX -c 10
PING 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX(2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX) 56 data bytes
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=1 ttl=58 time=6.20 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=2 ttl=58 time=6.10 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=3 ttl=58 time=6.07 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=4 ttl=58 time=5.71 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=5 ttl=58 time=6.37 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=6 ttl=58 time=6.28 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=7 ttl=58 time=6.33 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=8 ttl=58 time=6.28 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=9 ttl=58 time=6.27 ms
64 bytes from 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=10 ttl=58 time=6.30 ms

--- 2001:a250:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9012ms
rtt min/avg/max/mdev = 5.713/6.193/6.377/0.201 ms

平均値が 6.193ms となっています。

京都島根間での計測結果

拠点「KYT-A」と拠点「SMN」間での計測結果です。

$ sudo ping6 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX -c 10
PING 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX(2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX) 56 data bytes
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=1 ttl=57 time=18.0 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=2 ttl=57 time=18.1 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=3 ttl=57 time=18.1 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=4 ttl=57 time=18.1 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=5 ttl=57 time=18.3 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=6 ttl=57 time=18.3 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=7 ttl=57 time=18.3 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=8 ttl=57 time=17.7 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=9 ttl=57 time=17.8 ms
64 bytes from 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX: icmp_seq=10 ttl=57 time=17.8 ms

--- 2409:253:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9012ms
rtt min/avg/max/mdev = 17.774/18.092/18.331/0.218 ms

平均値が 18.092ms となっています。

まとめ

NTT西日本がフレッツ光サービス内で提供するNGN網でのRTTの計測を行いました。
京都市内での計測データでは、2.5~3.0ms程度となっています。
これらの3拠点は地理的に非常に近いため、このような数値が出るのは納得できます。
なお、拠点「KYT-A」と拠点「KYT-B」間でISPより割当されるIPv4アドレスを用いて行ったテストでは、平均値は10.638msとなっており、ISP間でトランジットされていると考えれば至極妥当な結果となっていました。

また、京都大阪間がおよそ6ms程度である事が分かりました。
大阪側の拠点は大阪市内ではなく大阪府南部地域にあります。物理的距離は大阪市内までの距離のおよそ2倍程度あります。
この2拠点間でのIPv4でのテスト結果の平均値は7.751msとなっており、NGN網内での優位性をさほど感じられませんでした。
理由として、この2拠点は共に同じISPを利用してIPv4アドレスの割当を受けており、外部とのトランジット無しでISP内のみで通信が行われていると考えられます。

加えて、京都島根間では18ms以上かかる事が分かりました。

これらの結果の平均値を、物理的な直線距離とあわせてグラフにしたものが以下になります。
実際には、網内で通過する機器数やその機器の伝送遅延等が異なると考えられ、また、サンプル数が非常に少ない為あてになるとは言えません。
(青点が各計測結果、青破線は近似直線を示しています。)

ある程度距離に対して比例の関係にあるように見えますが、やはりサンプル数が少ないため参考程度にとどめておくべきでしょう。

個人的な感想としては、光で通信しているにしてはかなり遅いという印象を受けました。
NGN網内で様々な機器を通過し、その伝送遅延が大きいためでしょうか。

今後も、計測可能な対象があれば計測してみたいと思います。

EdgeRouterでIPIP6やIP6GREを設定する

目次

概要

本記事では、Ubiquiti Networks社が提供しているEdgeRouterにおける、IPIP6トンネルやIP6GREトンネルの設定について、例を示します。
なお、EdgeRouterで使用されるEdgeOSのバージョンは v2.0.9-hotfix.1 を使用したものです。

IPIP6

IPIP6はIPv4 over IPv6となります。
IPIP6の設定例は次のようになります。

set interfaces ipv6-tunnel v6tun0 address 10.0.0.0/31
set interfaces ipv6-tunnel v6tun0 encapsulation ipip6
set interfaces ipv6-tunnel v6tun0 local-ip 'fd00::1'
set interfaces ipv6-tunnel v6tun0 remote-ip 'fd00::2'

上記の設定項目については、次のようになります。
address v6tun0が持つトンネル内の終端IPアドレスを指定します。
encapsulation トンネル方式を指定します。この例ではipip6を使用します。
local-ip トンネル接続に使用する自IPv6アドレスを指定します。
remote-ip トンネル接続に使用する対抗側のIPv6アドレスを指定します。

上記設定を施したのち、 show interfaces ipv6-tunnel を実行した結果を以下に示します。

ipv6-tunnel v6tun0 {
    address 10.0.0.0/31
    encapsulation ipip6
    local-ip fd00::1
    remote-ip fd00::2
}

IP6GRE

IP6GREの設定例は次のようになります。

set interfaces ipv6-tunnel v6tun0 address 10.0.0.0/31
set interfaces ipv6-tunnel v6tun0 encapsulation ip6gre
set interfaces ipv6-tunnel v6tun0 local-ip 'fd00::1'
set interfaces ipv6-tunnel v6tun0 remote-ip 'fd00::2'

上記の設定項目については、次のようになります。
address v6tun0が持つトンネル内の終端IPアドレスを指定します。
encapsulation トンネル方式を指定します。この例ではip6greを使用します。
local-ip トンネル接続に使用する自IPv6アドレスを指定します。
remote-ip トンネル接続に使用する対抗側のIPv6アドレスを指定します。

上記設定を施したのち、 show interfaces ipv6-tunnel を実行した結果を以下に示します。

ipv6-tunnel v6tun0 {
    address 10.0.0.0/31
    encapsulation ip6gre
    local-ip fd00::1
    remote-ip fd00::2
}

VyOSとEdgeRouterにおけるBGPの設定と挙動の差異

目次

概要

本記事では、VyOSとEdgeRouterそれぞれにおいてBGPを設定する場合の設定項目の差異と、挙動の違いについてまとめます。
隅々まで調査したわけではなく、利用する中で判明した点をまとめたものですので、完璧ではないことを予めご理解ください。

VyOS

VyOSとは、オープンソースで提供されるソフトウェアルータです。
Debianをベースとして開発されており、ルーティングなどのネットワークの基本的な機能から、各種VPNプロトコルやトンネリングプロトコルなどを扱うことが出来ます。
vyos.io

EdgeRouter

EdgeRouterは、Ubiquiti Networks社が発売しているネットワーク機器のブランドです。
低価格でありながら高機能であり、またライセンス料などが発生しないという特徴を持つ製品です。
中身はVyOSベースとなっているようなので、基本的にVyOSのドキュメントを参考にすることが出来ます。

本記事では、EdgeOS v2.0.9-hotfix.1 を例に取り上げていきます。

BGP設定周りのコマンド体系

VyOSでは1.2系列からBGP設定周りのコマンド体系が一部変更となっています。
例えば、広報するネットワークを明記する場合、VyOS 1.2系以降では次のように記述します。

set protocols bgp address-family ipv4-unicast network 192.168.1.0/24

しかし、VyOS 1.1.8以前、またはEdgeRouterにおいては、address-family の下に ipv4-unicast という設定項目は存在しません。
したがって、VyOS 1.1.8以前、またはEdgeRouterにおいては次のように記述する必要があります。

set protocols bgp 65001 network 192.168.1.0/24

network項目で設定したネットワークの広報動作の違い

上記で例を示した network で指定した広報したいネットワークの広報動作についても、VyOSとEdgeRouterで挙動の違いがみられます。
VyOSの場合、こちらのページに次のような記述があります。

By default, the BGP prefix is advertised even if it’s not present in the routing table. This behaviour differs from the implementation of some vendors.

これは、この network で設定したネットワークについては、そのネットワークがルーティングテーブル上に存在しない場合でも広報を行うことを示していると解釈できます。
しかしながら、EdgeRouter環境においてはこの挙動に違いがみられます。
例として、先ほどのネットワークの設定を、先に述べたコマンド体系の違いを考慮した上で次のような設定をEdgeRouterへ流し込んだとします。

protocols {
    bgp 65001 {
        neighbor 10.0.0.2 {
            remote-as 65002
        }
        network 192.168.1.0/24 {
        }
    }
}

上記設定の場合、VyOSのドキュメントを信用する限り、192.168.1.0/24というネットワークがルーティングテーブル上に存在しなくてもremote-asであるAS65002に対してこのネットワークが広報されることになります。
ここで、上記設定を流し込んだEdgeRouter上でルーティングテーブルを確認してみると以下のようになっていたとします。

$ show ip route
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
       O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       > - selected route, * - FIB route, p - stale info

IP Route Table for VRF "default"
K    *> 0.0.0.0/0 [20/0] via XXX.XXX.XXX.XXX, eth0, 07:09:35

すなわち、192.168.1.0/24というネットワークはルーティングテーブル上に存在しないという事です。
この状態で、自ASが広報しているネットワークを確認してみると、次のようになります。

$ show ip bgp neighbors 10.0.0.2 advertised-routes

結果を書き忘れたわけではありません。広報しているネットワークが存在しない場合、説明書きすら表示されません。
ということで、ルーティングテーブル上に存在しなくても広報されるはずの192.168.1.0/24というネットワークは、EdgeRouter環境においては広報されない、という事になります。
この点、VyOSと挙動が異なるようですので注意が必要です。

実際には、ルーティングテーブル上に無いネットワークを広報することは危険であると考えられます。したがって、VyOSのドキュメントに記載があるように、他ベンダーやEdgeRouterにおいてこのような実装がなされていること自体は不思議ではありません。
(多くの場合、redistributeなどの指定を行うと思います。)
また、VyOSのドキュメントには、次の設定を行うことで、ルーティングテーブル上に存在しないネットワークを広報しなくなるという旨の記載があります。

set protocols bgp parameters network-import-check

もう少し調査してみると、EdgeRouterには上記の設定項目は存在しないことが分かります。これは、デフォルトでこのチェックが行われていることを暗示していると言えます。
また、次のような設定項目が存在することを確認できます。

set protocols bgp 4220101001 parameters disable-network-import-check

コマンド名から推察するに、デフォルトで有効になっている「ルーティングテーブル上に存在するかどうかのチェック」を無効化するコマンドであると考えられます。
しかし、EdgeRouterを展開するUbiquiti Networksのコミュニティサイトのこのページには、次のような記述があります。

The list below shows other config settings that are no longer supported.
~~中略~~
protocols bgp <> parameters disable-network-import-check

つまり、EdgeOS v1.8.0以降では上記設定はサポートされなくなっています。
実際、上記設定を EdgeOS v2.0.9-hotfix.1 に流し込んでみても、挙動は変化しませんでした。

では、対象のネットワークがルーティングテーブル上に存在する場合は正しく広報が行われるのか。
試しに、次のような設定をしてみます。

set protocols static route 192.168.1.0/24 blackhole

上記は、192.168.1.0/24を宛先無しで静的ルート登録を行うものです。
先ほどと同様にルーティングテーブルを確認してみます。

$ show ip route
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
       O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       > - selected route, * - FIB route, p - stale info

IP Route Table for VRF "default"
K    *> 0.0.0.0/0 [20/0] via XXX.XXX.XXX.XXX, eth0, 07:09:35
S    *> 192.168.1.0/24 [1/0] is a summary, Null

これで、ルーティングテーブルに192.168.1.0/24というネットワークが登録されました。(多少無理矢理ですが…)
少し待ってから、先ほどと同様に自ASが広報しているネットワークについて確認してみます。

$ show ip bgp neighbors 10.0.0.2 advertised-routes
BGP table version is 45, local router ID is XXX.XXX.XXX.XXX
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal
Origin codes: i - IGP, e - EGP, ? - incomplete

    Network          Next Hop            Metric    LocPrf       Weight Path
*>  192.168.1.0/24   10.0.0.1                      100          32768    i

Total number of prefixes 1

ルーティングテーブルに登録された192.168.1.0/24というネットワークが広報されていることが確認できます。

ということで、EdgeRouterではルーティングテーブル上に存在しないネットワークは、たとえ指定したとしても広報されず、この動作はVyOSとは異なる というお話でした。

まとめ

EdgeRouterでBGPを扱うサンプルは割と散見されるのですが、「とりあえずBGPを動かしてみた」といった感じで実際の挙動に触れていないものが多かったので書いてみました。
VyOS 1.2系以降と、VyOS 1.1.8系以前やEdgeRouterでは、BGP周りのコマンド体系に違いがあります。
VyOSの情報を参考とする場合、注意が必要です。
また、BGP設定内の network で設定した挙動について、VyOSとEdgeRouterで違いがあることも確認できました。
実際、設定中にこの問題に直面したので、実験等でこの設定をされる際には注意が必要です。(ハマります)

kolla-ansibleを使ってOpenStack環境を構築してみる all-in-one編

目次

2021/01/09 インスタンスにパスワードを設定する箇所の誤りを修正しました。

kolla-ansibleとは

公式ページ

OpenStack 環境のデプロイメントツールです。
更に、完全にカスタマイズ可能であることも大きな特徴です。
加えて、CentOS や Ubuntu などの多くの Linux ディストリビューションに対応しているのも大きな特徴と言えます。
なお、デプロイには Ansible が利用されます。

他にも devstack や microstack など数多くのデプロイメントツールが存在しますが、これらは開発環境向けで、カスタマイズが困難であったり、再起動したら壊れてしまうものなど、扱いにくいのが現状です。
また、 kolla-ansible と同様に Ansible を利用して OpenStack 環境の構築を行う openstack-ansible なども存在しますが、こちらも筆者環境での検証では再起動したら壊れてしまうものでした。

そこで、今回は kolla-ansible を利用してみることにしました。
なお、 kolla-ansible ではすべてのコンポーネントを1つのサーバ上で動作させる all-in-one 構成と、複数のサーバをクラスタリングして利用する multinode 構成を選択することができます。
今回は all-in-one 構成を構築してみます。
multinode 構成については、次回以降取り扱う予定です。

インストール準備

kolla-ansible では CentOS や Ubuntu などを利用することができますが、本記事では Ubuntu 20.04 LTS を利用しています。

事前に python3 などを用意しておく必要がありますので、必要なパッケージとともに導入します。

$ sudo apt update
$ sudo apt install python3-dev libffi-dev gcc libssl-dev
$ sudo apt install python3-pip

インストールされた pip3 が最新バージョンであるか確認します。

$ sudo pip3 install -U pip

続いて、 Ansible をインストールします。

$ sudo apt install ansible

kolla 及び kolla-ansible のインストールを行います。
なお、ここでは apt でインストールする方法と、 github から落としてくる方法の2つが選択できますが、2020/12/29時点では apt からインストールするとUbuntu 20.04 LTSは動作対象外との旨が表示され先に進むことができなくなりますので、ここでは github から落としてきて利用します。

$ git clone https://github.com/openstack/kolla
$ git clone https://github.com/openstack/kolla-ansible
$ sudo pip3 install ./kolla
$ sudo pip3 install ./kolla-ansible

必要なディレクトリを作成し、所有権の設定を行います。

$ sudo mkdir -p /etc/kolla
$ sudo chown $USER:$USER /etc/kolla

先程 github から落としたファイルのうち、必要なファイルを作成したディレクトリへコピーします。

$ cp -r kolla-ansible/etc/kolla/* /etc/kolla
$ cp kolla-ansible/ansible/inventory/* .

ここで、 /etc/ansible/ansible.cfg[defaults] に以下を追記して Ansible の設定を変更します。

host_key_checking=False
pipelining=True
forks=100

ここで、 Ansible の設定とインベントリの構成が正しいかチェックしておきます。

$ ansible -i all-in-one all -m ping

OpenStack の各サービスのパスワード類を生成します。

$ cd ~/kolla-ansible/tools
$ ./generate_passwords.py

/etc/kolla/globals.yml を編集して kolla の設定を行います。
設定はページKolla globals.yml を参考にしてください。
なお、cinder などの有効化設定もこちらで行います。
必要に応じて設定をしてください。

kolla_base_distro: "ubuntu" #ホストOSのディストリビューション
kolla_install_type: "binary" #パッケージの取得方法
kolla_internal_vip_address: "192.168.122.206" #管理IFのアドレス
network_interface: "enp1s0" #管理ネットワークのIF
neutron_external_interface: "enp6s0" #OpenStack Neutron ネットワークのIF

デプロイを行います。

$ cd ~/kolla-ansible/tools
$ ./kolla-ansible -i ../../all-in-one bootstrap-servers
$ ./kolla-ansible -i ../../all-in-one prechecks
$ ./kolla-ansible -i ../../all-in-one deploy

ここまで完了すると、 kolla_internal_vip_address で設定したIPアドレスにアクセスすると OpenStack のダッシュボードが表示されます。
しかし、外部へアクセスするためのネットワークなどが設定されていないため、それらの設定を行います。
kolla-ansible/tools/init-runonce をエディタで開き、下記を追記します。
CIDRRANGE , GATEWAY などを適時変更します。

ENABLE_EXT_NET=${ENABLE_EXT_NET:-1}
EXT_NET_CIDR=${EXT_NET_CIDR:-'192.168.122.0/24'}
EXT_NET_RANGE=${EXT_NET_RANGE:-'start=192.168.122.15,end=192.168.122.45'}
EXT_NET_GATEWAY=${EXT_NET_GATEWAY:-'192.168.122.1'}

cloud-init を利用してインスタンスのパスワードを設定する場合は以下の変更を行います。
~/kolla-ansible/ansible/roles/nova/templates/nova.conf.j2

[libvirt]
inject_password = True
inject_partition = -1

この変更は、 /etc/kolla/nova-compute/nova.conf に反映されますされると記述があるのですが、こちらの環境では反映を確認できませんでした。

~/kolla-ansible/ansible/roles/horizon/templates/local_settings.j2

OPENSTACK_HYPERVISOR_FEATURES = {
    'can_set_mount_point': False,
    'can_set_password': True,  //FalseをTrueに変更
    'requires_keypair': False,
    'enable_quotas': True
}

この変更は、 /etc/kolla/horizon/local_settings に反映されます。

最後に、変更した設定を OpenStack に適用します。
その前に、 python3-openstackclient をインストールしておきます。

$ sudo apt install python3-openstackclient

続いて、認証情報の入ったスクリプトファイルを生成します。

$ cd kolla-ansible/tools
$ ./kolla-ansible post-deploy
$ . /etc/kolla/admin-openrc.sh

変更した設定を適用します。

$ kolla-ansible/tools/init-runonce
$ cd kolla-ansible/tools
$ ./kolla-ansible -i ../../all-in-one reconfigure

以上が完了すると、変更した設定が適用され、ネットワークなどがいくつか作成されているはずです。
なお、 Horizon のパスワードは以下のようにして表示することができます。

$ grep keystone_admin_password /etc/kolla/passwords.yml

以上、簡単にではありますが、参考になりましたら幸いです。

お家で始める仮想化環境 Proxmox VE Cloud-init編

目次

環境

前提として、Proxmoxの基本的な構築が完了している必要があります。
Proxmox環境の構築方法はこちらをご覧ください。

また、Cloud-init Supportを参考にしています。

Cloud-initテンプレートの準備

本記事では、VMで使用するOSとしてUbuntuを使用します。
https://cloud-images.ubuntu.com/でOpenstack向けのCloud-initに対応したイメージが配布されていますので、こちらを利用します。

Proxmoxホストのシェルにログインして、上記イメージをダウンロードします。
今回はUbuntu 20.04 LTSを使用しますので、こちらをダウンロードしました。

# wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img

続いて、テンプレートで使用するためのVMを作成します。

# qm create 9000 --memory 2048 --net0 virtio,bridge=vmbr0

先ほどダウンロードしたイメージをインポートします。
以下の例では対象ディスクをlocal-lvmとしていますが、適時変更してください。(local-zfsなど)

# qm importdisk 9000 focal-server-cloudimg-amd64.img local-lvm

インポートしたディスクをscsi0としてVMにアタッチします。
先ほどと同様に、local-lvmvm-9000-disk-0は環境によって異なる場合がありますので、適時変更してください。

# qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9000-disk-0

続いて、Cloud-initが利用するCDROMドライブを設定します。

# qm set 9000 --ide2 local-lvm:cloudinit

先ほどアタッチしたディスクをブートディスクとして設定します。

# qm set 9000 --boot c --bootdisk scsi0

Cloud-initはシリアルコンソールを使用するため、その設定をします。

# qm set 9000 --serial0 socket --vga serial0

最後に、テンプレートに変換します。

# qm template 9000

Cloud-initテンプレートからのデプロイ

先ほど作成したテンプレートを使用して、VMのデプロイを行ってみます。
普段はWebGUIから操作することが多いので、WebGUIから操作することにします。
作成したテンプレートを右クリックするとCloneの項目がありますので選択します。
ダイアログが表示されますので、VM IDNameを入力し、ModeFull Cloneを選択します。

入力出来たら、右下のCloneを押して処理が完了するのを待ちます。

処理が完了したら、クローンしたVMより、Cloud-initメニューを開きます。

必要に応じて、各項目を設定します。

  • User
  • Password
  • DNS domain
  • DNS servers
  • SSH public key
  • IP Config

設定が完了したら、VMを起動します。
起動完了後、しばらく待っているとCloud-initの処理が行われます。
ログが表示されますので、処理が完了するのを待ってログインしてみてください。
設定した内容が反映されているはずです。

複数のVMをデプロイしたい場合も、作成したテンプレートからクローンすることで簡単にデプロイすることが出来ます。

RTX3080, RTX3090をGTX1080, RTX2060とベンチマーク結果を比較してみる。

4Kゲーミング

2020年9月17日に、NVIDIAのAmpereアーキテクチャを採用したGPU、RTX 3080が発売解禁されました。
筆者は、深夜販売に突撃して運よく入手出来たので、4Kゲーミング性能について軽くベンチマークを通して見ていきます。

RTX 3090 ?

RTX3080に続いて、RTX 3090が2020年9月24日に発売解禁となりました。
こちらも深夜販売での抽選に参加したところ運よく入手できましたので、こちらも見ていきます。

なお、「コスパ」とか言ってはいけません。
筆者が泣いてしまいます。

ベンチマーク環境

ベンチマークには、おなじみ3DMarkを使用します。
また、DLSSについてもどのような効果があるのか気になったので、こちらも試してみます。
手持ちのゲームでDLSSに対応したゲームが「DEATH STRANDING」ぐらいしか無かったので、参考程度にご覧ください。

ベンチマークPCとしては以下のものを使用しています。

詳細
CPU AMD Ryzen9 3950X 16-Core Processor
M/B ASUS Pro WS X570-ACE
Memory DDR4 Non-ECC UDIMM 16GB x4(64GB) 3200MHz
PSU 80PLUS GOLD 750W
Storage Western Digital SN550 500GB (M.2 NVMe)
Gprahics MSI GTX 1080 AERO
NVIDIA RTX 2060 FE
MSI RTX 3080 GAMING X TRIO
ZOTAC RTX 3090 Trinity

RTX 2000シリーズとの比較ベンチを多く見ますが、GTX世代との比較があまりなされていないように思ったのと、筆者がGTX 1080からの更新のため、GTX 1080との性能差に注目したいところです。
また、手持ちにあるGPUの中にRTX 2000シリーズがRTX 2060しか無かったので、参考程度です。

RTX 3080 and RTX 3090

RTX 3080 FE RTX 3090 FE
CUDAコア 8704基 10496基
RTコア 68基 82基
Tensorコア 272基 328基
ベースクロック 1.44GHz 1.4GHz
ブーストクロック 1.71GHz 1.7GHz
VRAM 10GB GDDR6X 24GB GDDR6X

外観

ZOTAC RTX 3090 Trinity

RTX 3090のカスタムカードとしては小さい部類だと思います。
他のカードにおいて、高さがPCIeスロットブラケットを大きく超えているのに対して、こちらのカードはさほど飛び出ていません。
補助電源は 8pin x2 となっています。

MSI RTX 3080 GAMING X TRIO

ブーストクロックが1815MHzにOCされたカードです。
RTX 3080のTBPが320Wになっているのに対して、このカードのTBPはOCされているために340Wとなっています。
それにより、補助電源が 8pin x3 となっています。
補助電源として 8pin x3 が必要なグラフィックカード、過去にあったんでしょうか…

NVIDIA RTX 2060 Founders Edition

何の変哲もない RTX 2060 Founders Edition です。
個人輸入で入手したものです。

MSI GTX 1080 AERO

どこぞで投げ売りされていた、MSI AEROシリーズのGTX 1080カードです。
外排気タイプになっています。

3DMark Time Spy (1920 x 1080)

Time Spy のデフォルト設定では2K解像度ですが、今回はFullHDにカスタム設定を行っています。

やはり、RTX 3000シリーズは、GTX 1080と比較してもスコアにおいて倍以上の差をつけています。
しかし、RTX 3090はRTX 3080と比較しても誤差程度の差しかないようです。

3DMark Time Spy Extreme (3840 x 2160)

続いて、4K相当のベンチマークである、Time Spy Extremeを実行しました。

こちらも、RTX 3000シリーズは共に、GTX 1080と比較すると倍以上のスコアとなっています。
また、先ほどに比べるとRTX3080と比較してRTX 3090のスコアが伸びているように感じます。
RTX 3090を活かすには4K以上の環境でないと意味がない といった考え方もできるのかもしれません。

3DMark Port Royal (1920 x 1080)

続いて、レイトレーシング性能を計測しました。
こちらもまずはFullHDから。

GTX 1080においてはRTコアを搭載していないため、比較対象として適切ではないですね。
RTX 2060と比較すると、その差は歴然です。
また、こちらもRTX 3090のスコアがRTX 3080と比較しても伸びていることが分かります。

3DMark Port Royal (3840 x 2160)

続いて、4Kレイトレーシング性能を計測しました。

GTX 1080については言うまでもないですね(RTコア無いし)。
ここで気になるのが、RTX 2060のスコアが思ったより出ていないことです。
Port Royalのデフォルト解像度は2Kであるので、試しにそちらを実行したところ4193というスコアが出ました。
4Kになった瞬間スコアががた落ちしたということになりますが、RTX 2060ではRTコアが足りていないのでしょうかね。
気になるところです。
本題に戻って、こちらもRTX 3000シリーズのスコアの伸びが目立っていますね。
4K解像度においても、レイトレーシングを利用しながらゲームを快適にプレイすることは夢ではない ということでしょう。

DEATH STRANDING (1920 x 1080)

続いて、DLSSの効果について適当に計測しました。
素人による計測なので、参考程度にご覧ください。
なお、以降、「DEATH STRANDING」上の画質設定はすべて一番高いものを設定しています。

筆者環境では、どのカードを使用してもプレイ中はFPSが120程度から変動しませんでした。
(もちろん、フレームレート制限が120FPSとなっているわけではない。)

DEATH STRANDING (3840 x 2160)

続いて、4K解像度でのプレイ。

こちらは、はっきりと差が現れました。
RTX 3000シリーズの性能向上がうかがえます。
(RTX 3000シリーズのスコアについては、環境によってはもっと高くなる可能性があると思います。)

DEATH STRANDING with DLSS (3840 x 2160)

続いて、4K解像度においてDLSSを利用してみます。
DLSSについては解説しません。
DLSS設定については「パフォーマンス」を選択しています。

先ほども述べたように、実質的なFPS上限が120程度になっていることでRTX 3000シリーズでの変化を確認することは出来ない状態です。
しかしながら、RTX 2060においてはFPS値が向上しており、DLSSの効果が確認できます。

GPU温度

続いて、多くの方が気になっているであろうGPU温度について。
こちらは、3DMark Time Spy Extreme 実行中の最大GPU温度です。

GTX1080については外排気タイプなので、冷却面での問題があるのは必然と言えます。
感心したのは、RTX 3000シリーズにおいてTBPが増加したにもかかわらず、想定されたよりもGPU温度が高くないということです。
RTX 3080,3090共に75,6度と、ハイエンドグラフィックカードとしてはかなり冷えているのではないでしょうか。

消費電力

続いて、消費電力です。
システム全体の消費電力である点に注意してください。(カード単体の消費電力ではありません)
また、「DEATH STRANDING」プレイ時の消費電力です。

こちらは概ね予想通りといったところでしょうか。
アイドル状態でも消費電力の差が見られます。
RTX 3090では200Wを超えて225W程度、RTX 3080では188Wでした。

4K解像度において「DEATH STRANDING」をプレイ中は、RTX 3090で550W程度、RTX 3080で540W程度でした。
先に述べたように、使用したグラフィックカードにおいて、RTX 3080はOCによってTBPが340Wとなっており、RTX 3090が350Wであるから、妥当な差であると言えそうです。

さて、面白いのはここです。
DLSSパフォーマンスを有効にした状態でプレイした時の消費電力について。
RTX 3000シリーズの両カードにおいて、DLSSを利用していない場合と比較すると、消費電力が低下しています。
4K解像度によってCUDAコアが使用する電力より、DLSS+(低解像度)CUDAが利用する電力の方が少ないという事でしょうか。
見た目で差を感じない人にとってDLSSを有効化した状態でゲームプレイをすることは、消費電力を下げる選択肢となるかもしれません。

電源ユニットの容量はどれぐらいが好ましい?

Ryzen9 3950X + RTX 3090の組み合わせで、ゲームプレイ中は550W程度の電力を消費するという事です。
今回、750W電源を利用してベンチマークを行いましたが、その最中に電源が落ちるといったことはありませんでした。
しかし、負荷率が50%程度で最も変換効率が高くなる電源ユニットが多いことを踏まえると、1000W以上の電源ユニットを用意したいところです。
また、Ryzen Threadripperなど、HEDT CPU環境で利用する場合は、もっと余裕が欲しいところです。

RTX 3070 ?

10月に発売予定のRTX 3070。
RTX 3080やRTX 3090がこれだけ性能向上しているとなると、こちらも期待できそうです。

About

インフラエンジニア
インフラ系の技術を中心に紹介・解説しています。

お問い合わせはTwitter DMまで

Privacy Policy

About Me

Recommends

Archives