CentOS7でBIG-IP VEのセットアップ
CentOS7でF5 BIG-IP VEのセットアップを実施したため、その手順を記載しておきます。
BIG-IP VEはqcow2ファイルからイメージを読み込むため、n9kvライクなインストール方法となります。
以下の公式Docに沿って記載したいと思います。
AskF5 | Manual: BIG-IP Virtual Edition 13.1.0 and Linux KVM: Setup
また、足回りとしては、virtioとSR-IOVの両方で構成可能です。
しかし、インストール後(正確にはトライアルライセンスのアクティベーション後)には変更できないため、最初に構成を決めてから足回り数を決定してください。
1.環境
筐体 : ProLiant DL360e Gen8 System ROM : P73 01/22/2018 NIC : Intel X540-AT2 OS : CentOS7.5(1804) Kernel : 3.10.0-862.el7.x86_64 Installed Environment Groups : Server with GUI Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools
2.BIG-IP VEのインストール
virt-managerによるGUIでのインストール方法をご紹介します。
IPMIなどが無ければ、tigervncなどを起動させておきましょう。*1
まずはqcow2ファイルを/var/lib/libvirt/images/直下にコピー
cp BIGIP-14.0.0.2-0.0.2.qcow2 /var/lib/libvirt/images/
2-1.virt-managerによるインストール
File>New Virtual Machineを選択
Import existing disk imageを選択して、Forwardをクリック
Browse...をクリック
前項でコピーしたBIGIP-14.0.0.2-0.0.2.qcow2を選択して、Choose Volumeをクリック*2
OS typteはLinux、VersionはRHEL6.9を選択して、Forwardをクリック
下図の通りであることを確認して、Forwardをクリック
メモリは最低2GBで起動します。
CPUsは最低1で起動します
Nameに任意の名前を入力
Customize configuration before installにチェック(必須)
Network selectionは任意のインターフェースを選択(mgt用なので後で変更可)
Device modelにvirtioを選択(必須)
Applyをクリック
HAを構成する場合、NICは最低でもあと3つ必要(できれば4つ必要)です。このため、AddHardwareをクリックして上記画面と同様にNICを追加していきましょう。
SR-IOVのVFを追加する場合
画面左下のAdd Hardwareをクリック
PCI Host Deviceを選択
任意のVirtualFunctionを選択*3
Finishをクリック
Begin Installationをクリックすると、自動的にインストールが進みます。
インストールが完了すると、ログイン画面となります。
login名:root
Passwd:default
ログインすると、パスワード変更を促されます。
(current)UNIX password:default
New BIG-IP password:任意のパスワード1
Retype new BIG-IP password:任意のパスワード1
すると、プロンプトが表示されます。
プロンプトが表示されたら、以下のコマンドによりBIG-IPのMgmtインターフェースのIPを確認します。このとき、同一LAN内でDHCPサーバを起動しておけば自動的にIPアドレスを取得してくれます。
tmsh show sys ip-address
以下出力のうち、cm deviceがIP(この例では、192.168.11.14)となります。
2-2.Web画面での初期アカウント設定
ホストOSまたは同一LAN内からブラウザを開き、BIG-IPにアクセスします。*4
https://BIG-IPのIPアドレス/
以下のログイン画面が表示されますので、ユーザ名とパスワードを入力。
Username:admin
Password:任意のパスワード1
パスワード変更を促されます。*5
Current Password:任意のパスワード1
New Password:任意のパスワード2
Confirm:任意のパスワード2
改めて、ログイン画面が表示されます。
Username:admin
Password:任意のパスワード2
ログイン後の画面は以下の通りです。
この画面より初期設定ウィザードに従い、トライアルライセンスのアクティベーションなどを行っていきます。
3.BIG-IP VEの足回りに関する留意事項
4.最後に
インストール自体は至ってシンプルなのですが、パスワード周りを整理しておかないと後々になってログインできなくなるため、任意のパスワード1&2という風に記載を分けました。また、今回はインストールのみでしたが、今度はHA構成の設定についても別途記事を書ければなと思っています。
*1:VNCサーバのインストール方法について、ここではあえて触れません、あしからず。
*2:ここではBIGIP-14.0.0.2-0.0.2.qcow2をさらにコピーして、bigip02.qcow2を選択しています。BIGIP-14.0.0.2-0.0.2.qcow2をマスターイメージとするためです。
*3:SR-IOVの設定は事前に行っておいてください。 metonymical.hatenablog.com
*4:httpsであることに注意してください。httpでアクセスしてもhttpsにリダイレクトとかしてくれません。
*5:任意のパスワード1よりも任意のパスワード2の方がパスワードの複雑性要件が厳しくなっているため、それなりの強度のパスワードを準備しておいてください。
PPPoE Client LAN型(固定Prefix)設定で全アドレス使用
PPPoEのLAN型固定Prefixで/29などをISPから払い出された際、ネットワークアドレスやブロードキャストアドレスも含む、全てのGlobalIPを使い切る方法となります。
1.構成
今回の例では、ISPから25.0.0.16/29のLAN型固定Prefixを払い出された想定でConfigを作成しています。
ルータを2台構成としています。
- PPPoE終端+StaticNATをするルータ=RT13
- 本来GlobalIPを割り当てたいルータ=RT03
回線はフレッツ光ネクストを使用しており、複数のISPとLAN型固定Prefixの契約して試行しましたが、いずれも成功しています。
四の五の説明するより、Configを見てもらった方が早いと思います。
2.RT13のConfig
! hostname RT13 ! interface GigabitEthernet0 switchport access vlan 10 no ip address ! interface GigabitEthernet8 no ip address duplex auto speed auto pppoe enable group global pppoe-client dial-pool-number 1 ! interface Vlan10 ip address 192.168.10.1 255.255.255.0 ip nat inside ip virtual-reassembly in ip tcp adjust-mss 1414 ! interface Dialer1 mtu 1492 ip unnumbered Vlan10 ip mtu 1454 ip nat outside ip virtual-reassembly in encapsulation ppp dialer pool 1 dialer-group 1 ppp authentication chap callin ppp chap hostname ユーザ名 ppp chap password パスワード ppp pap refuse ppp ipcp route default no cdp enable ! ip nat inside source static 192.168.10.16 25.0.0.16 ! dialer-list 1 protocol ip permit ! access-list 1 permit any ! end !
PPPoE終端の設定はおなじみですが、異なる点は1対1のStaticNATをしている点です。
3.RT03のConfig
! hostname RT03 ! interface GigabitEthernet0 switchport access vlan 20 no ip address ! interface GigabitEthernet8 ip address 192.168.10.16 255.255.255.0 ip nat outside ip virtual-reassembly duplex auto speed auto ! interface Vlan20 ip address 192.168.20.1 255.255.255.0 ip nat inside ip virtual-reassembly ! ! ip route 0.0.0.0 0.0.0.0 192.168.10.1 ! ip nat pool GIP 192.168.10.16 192.168.10.16 netmask 255.255.255.0 ip nat inside source list 1 pool GIP overload ! access-list 1 permit 192.168.20.0 0.0.0.255 ! end
RT03では、G8をWAN側インターフェースとしていますが、GlobalIPではなく、RT13のStaticNATで設定したPrivateIPをインターフェースに設定し、そのIP(=192.168.10.16)でoverloadさせてしまいます。
4.RT13のRoutingテーブルとNATテーブル
RT13#show ip a route Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP D - EIGRP, EX - EIGRP external, 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 i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2 ia - IS-IS inter area, * - candidate default, U - per-user static route o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP a - application route + - replicated route, % - next hop override, p - overrides from PfR Gateway of last resort is 1.1.1.1 to network 0.0.0.0 S* 0.0.0.0/0 [1/0] via 1.1.1.1 1.1.0.0/32 is subnetted, 1 subnets C 1.1.1.1 is directly connected, Dialer1 192.168.10.0/24 is variably subnetted, 2 subnets, 2 masks C 192.168.10.0/24 is directly connected, Vlan10 L 192.168.10.1/32 is directly connected, Vlan10 RT13#show ip nat translations Pro Inside global Inside local Outside local Outside global tcp 25.0.0.16:2598 192.168.10.16:2598 23.219.39.17:80 23.219.39.17:80 tcp 25.0.0.16:2599 192.168.10.16:2599 77.234.41.34:80 77.234.41.34:80 tcp 25.0.0.16:2600 192.168.10.16:2600 77.234.42.50:80 77.234.42.50:80
DefaultRouteのNexthopが1.1.1.1となっていますが、ppp ipcp route defaultの設定により、ISPとのPPPoEセッション時にネゴっているため、PPPoEを張るたびに変化します。
ちなみに、
ip route 0.0.0.0 0.0.0.0 Dialer1
とした場合、
CEFが使用されない(Fastスイッチングになってしまう)らしいので、ppp ipcp route defaultを使用しています。
5.RT03のRoutingテーブルとNATテーブル
RT03#show ip route Codes: C - connected, S - static, R - RIP, M - mobile, B - BGP D - EIGRP, EX - EIGRP external, 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 i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2 ia - IS-IS inter area, * - candidate default, U - per-user static route o - ODR, P - periodic downloaded static route Gateway of last resort is 192.168.10.1 to network 0.0.0.0 S* 0.0.0.0/0 [1/0] via 192.168.10.1 192.168.10.0/24 is subnetted, 1 subnets C 192.168.10.0 is directly connected, GigabitEthernet8 C 192.168.20.0/24 is directly connected, Vlan20 RT03#show ip nat translations Pro Inside global Inside local Outside local Outside global tcp 192.168.10.16:2598 192.168.20.10:2598 23.219.39.17:80 23.219.39.17:80 tcp 192.168.10.16:2599 192.168.20.10:2599 77.234.41.34:80 77.234.41.34:80 tcp 192.168.10.16:2600 192.168.20.10:2600 77.234.42.50:80 77.234.42.50:80
RT13がGlobalIPにNAT変換してくれるので、RT03は192.168.10.16をGlobalIPと見立ててPATしているだけです。
6.補足
Vlan10に複数のルータやサーバを追加していきたい場合、RT13で以下のように設定してください。
ip nat inside source static 192.168.10.17 25.0.0.17
ip nat inside source static 192.168.10.18 25.0.0.18
・・・
ip nat inside source static 192.168.10.23 25.0.0.23 ←ブロードキャストアドレスも可
ISP側ルータのRoutingテーブル上、25.0.0.16/29のNexthopがPPPoEクライアント側に向いているため、25.0.0.16(ネットワークアドレス)や25.0.0.23(ブロードキャストアドレス)を使用したとしても、25.0.0.16/29の範囲に入っていれば、当然RT13側に戻してくれます。
以上です。
7.最後に
以下のサイトを参考にさせて頂きました。
技術的な解説が詳細に記載されており、最初拝読させて頂いたときは完全に目から鱗でした。
milestone-of-se.nesuke.com
今までは、RT03に相当する機器でDefaultRouteのNexthopが必要という理由だけで、盲目的にRT13のVLAN10に相当するインターフェースでGlobalIPを付与しておりました。しかし、上記サイトを読んだ結果、GlobalIPを浪費してしまっていたんだな、と猛省しました。。。
ちなみに以前、本Blogで紹介した
metonymical.hatenablog.com
の構成で、
試しにIPSecやTunnnelインターフェース上でBGPピアを張ってみましたが、正常に疎通確認が取れました。
また、RT13がGlobalIPを持っていないため、ちょっとセキュア(?)になっている点がとても気に入っており、まずはラボで利用してみて商用稼働できるかを見極めていきたいなと考えています。
CentOS7 + SPDKでNVMe-oF (NVMe over Fabric) target構築
CentOS7上でSPDKをビルドして、NVMe-oF(NVMe over Fabric) targetを構築しました。
1.環境
1-1.筐体1 NVMe over Fabric Target
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 NIC : Mellanox ConnectX-3pro MCX311A-XCCT SSD : Samsung SSD 250GB 970 EVO M.2 Type2280 PCIe3.0×4 NVMe1.3 Adapter : GLOTRENDS M.2 PCIe NVMe or PCIe AHCI SSD to PCIe 3.0 x4 Adapter Card OS : CentOS7.5(1804) Kernel : 4.18.4-1.el7.elrepo.x86_64 Installed Environment Groups : Minimal Install SPDK : v18.10-pre DPDK : v18.05.0
1-2.筐体2 NVMe over Fabric Initiator
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 NIC : Mellanox ConnectX-3pro MCX311A-XCCT OS : CentOS7.5(1804) Kernel : 4.18.4-1.el7.elrepo.x86_64 Installed Environment Groups : Minimal Install
1-3.全体の構成
RoCEv2のフレームをPcapしたかったためTargetとInitiatorの間にスイッチを挟んでいますが、DAS(直結)構成でも大丈夫です。
1-4.全体の流れ
Kernelのアップグレード
事前準備
SPDKのビルド
SPDKのnvmf.conf設定
NVMe-oF Initiatorからのアクセス
2.Kernelのアップグレード
今回の構成ではRoCEv2を使用します。
RoCEv2を使用する場合、Kernel4.5以上でないとサポートされないため、ELRepoから最新のKernelにアップグレードします。
この作業はTargetおよびInitiatorの両方で行ってください。
2-1.リポジトリの登録
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
GPG-KeyとELRepoの登録を実施。
# yum list installed | grep kernel kernel.x86_64 3.10.0-862.el7 @anaconda kernel-tools.x86_64 3.10.0-862.el7 @anaconda kernel-tools-libs.x86_64 3.10.0-862.el7 @anaconda
現在インストールされているKernelのバージョンを確認
2-2.Kernelのアップグレード
yum --enablerepo=elrepo-kernel install kernel-ml
最新Kernelのインストール*1
# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg 0 : CentOS Linux (4.18.4-1.el7.elrepo.x86_64) 7 (Core) 1 : CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core) 2 : CentOS Linux (0-rescue-626b869879714a9cbe128e5b6f85dd89) 7 (Core) # grub2-set-default 0 # grub2-mkconfig -o /boot/grub2/grub.cfg Generating grub configuration file ... Found linux image: /boot/vmlinuz-4.18.4-1.el7.elrepo.x86_64 Found initrd image: /boot/initramfs-4.18.4-1.el7.elrepo.x86_64.img Found linux image: /boot/vmlinuz-3.10.0-862.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-862.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-626b869879714a9cbe128e5b6f85dd89 Found initrd image: /boot/initramfs-0-rescue-626b869879714a9cbe128e5b6f85dd89.img done # reboot
menuentryを確認
初期起動Kernelに4.18.4-1.el7.elrepo.x86_64を選択
grub.cfgへの反映
再起動
なお、Initiatorはここまでで完了です。
Targetはspdkのビルドを行うため、この後のkernel-ml-develやkernel-ml-headersのインストールも行ってください。
2-3.既存Kernel削除とその他のアップグレード
uname -r yum remove kernel yum list installed | grep kernel yum -y update kernel-tools-libs kernel-tools yum list installed | grep kernel
起動Kernelのバージョン確認
既存Kernelの削除
現在インストールされているKernel関連のパッケージの確認
tools類のアップデート*2
現在インストールされているKernel関連のパッケージの再確認
2-4.elrepo-kernelの常時有効化
vi /etc/yum.repos.d/elrepo.repo [elrepo-kernel] name=ELRepo.org Community Enterprise Linux Kernel Repository - el7 baseurl=http://elrepo.org/linux/kernel/el7/$basearch/ http://mirrors.coreix.net/elrepo/kernel/el7/$basearch/ http://mirror.rackspace.com/elrepo/kernel/el7/$basearch/ http://repos.lax-noc.com/elrepo/kernel/el7/$basearch/ http://mirror.ventraip.net.au/elrepo/kernel/el7/$basearch/ mirrorlist=http://mirrors.elrepo.org/mirrors-elrepo-kernel.el7 enabled=1 #0→1に修正 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org protect=0
2-5.tools類のアップグレードとdevel&headersのインストール
yum swap kernel-tools-libs kernel-tools -- kernel-ml-tools-libs kernel-ml-tools yum -y install kernel-ml-devel kernel-ml-headers yum list installed | grep kernel
kernel-*とkernel-ml-*のswap
kernel-ml-develとkernel-ml-headersのインストール
現在インストールされているKernel関連のパッケージの確認
# yum list installed | grep kernel kernel-ml.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel kernel-ml-devel.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel kernel-ml-headers.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel kernel-ml-tools.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel kernel-ml-tools-libs.x86_64 4.18.4-1.el7.elrepo @elrepo-kernel
上記のような出力になっていれば完了です。
3.事前準備
3-1.セキュリティ設定の無効化
firewalldとSELinuxを無効化します。
systemctl disable firewalld vi /etc/selinux/config で開いて SELINUX=disabled にして保存。
3-2.grubの設定
grubにHugePageの設定追加
vi /etc/default/grub GRUB_CMDLINE_LINUX=の行末に追加 default_hugepagesz=1G hugepagesz=1G hugepages=8 保存後、grubに反映 grub2-mkconfig -o /etc/grub2.cfg
3-3.NICのIPアドレス設定
nmcli devなどでMellanox製NICのデバイス名を確認の上、IPアドレスを設定してください。今回構築するNVMe-oF targetはRoCEv2で動作するため、NICにはIPアドレスが必要となります。
nmcli connection add type ethernet autoconnect yes con-name ens1 ifname ens1 nmcli connection modify ens1 ipv4.method manual ipv4.addresses 192.168.20.200/24 nmcli connection up ens1
4.SPDKのビルド
4-1.gitインストールからspdkのビルドまで
以下を流し込んでください。
yum -y install git && \ cd /usr/src && \ git clone https://github.com/spdk/spdk && \ cd spdk && \ git submodule update --init && \ scripts/pkgdep.sh && \ ./configure --with-rdma --enable-debug && \ make
gitインストール
/usr/srcにcd
spdkのソースをgitから取得
/usr/src/spdkにcd*3
アップデート
必要なパッケージのインストール
makeファイル生成
ビルド
iSCSI Targetと異なる点
--with-rdmaは必須となります。
また、nvmf_tgtを起動した際に「-L」オプションでDebugログが見れるようになるため、--enable-debugを追加しています。正常起動しているのか?固まっているのか?を見極めるためにも、あった方がいいかなと思います。
4-2.unittest.shの実行
ビルドが完了したら、最後に各モジュールのテストを実施してみてください。
./test/unit/unittest.sh 出力結果省略 ===================== All unit tests passed ===================== WARN: lcov not installed or SPDK built without coverage! WARN: neither valgrind nor ASAN is enabled!
多数の出力結果が表示されますが、最後に「All unit tests passed」と表示されればOKです。
Warringが2件表示されてますが、気にせず先に進んでください。
5.spdkのnvmf.confファイル設定
5-1.設定ファイルの作成
# cd /usr/src/spdk/app/nvmf_tgt # vi nvmf.conf [Global] ReactorMask 0x0F [Nvmf] MaxQueuesPerSession 4 MaxQueueDepth 1024 AcceptorPollRate 10000 [Nvme] TransportId "trtype:PCIe traddr:0000:04:00.0" Nvme0 RetryCount 4 TimeoutUsec 1 ActionOnTimeout None AdminPollRate 100000 HotplugEnable No [Subsystem1] NQN nqn.2016-06.io.spdk:cnode1 Listen RDMA 192.168.20.200:4791 AllowAnyHost Yes Host nqn.2016-06.io.spdk:init SN SPDK00000000000001 Namespace Nvme0n1 1
ReactorMaskの掛け方は最後に詳細を記載したいと思います。
わからなければ、コメントアウトしても問題ありません。
TransportIdの確認方法
私の場合、Samsung SSD 250GB 970を使用したため、lspciで以下のようにgrepしました。
# lspci |grep Samsung 04:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a808
SSDのbsf(bus slot function)番号が判明したら、頭にDomain番号「0000:」を付けてください。
サンプルconfがspdk/etc/spdk/nvmf.conf.inにあるので、これをコピーしてnvmf.confを作成してもよいと思います。
5-2.setup.shの起動
カーネル上での制御からSPDK(正確にはDPDK)上での制御に移行します。
ますはステータス確認から。
# cd /usr/src/spdk # scripts/setup.sh status Hugepages node hugesize free / total node0 1048576kB 8 / 8 node1 1048576kB 8 / 8 NVMe devices BDF Numa Node Driver name Device name 0000:03:00.0 0 nvme nvme0 I/OAT DMA BDF Numa Node Driver Name 0000:00:04.0 0 ioatdma 0000:20:04.0 1 ioatdma 0000:00:04.1 0 ioatdma 0000:20:04.1 1 ioatdma 0000:00:04.2 0 ioatdma 0000:20:04.2 1 ioatdma 0000:00:04.3 0 ioatdma 0000:20:04.3 1 ioatdma 0000:00:04.4 0 ioatdma 0000:20:04.4 1 ioatdma 0000:00:04.5 0 ioatdma 0000:20:04.5 1 ioatdma 0000:00:04.6 0 ioatdma 0000:20:04.6 1 ioatdma 0000:00:04.7 0 ioatdma 0000:20:04.7 1 ioatdma virtio BDF Numa Node Driver Name Device Name
現在はカーネル上のnvmeやioatdmaドライバで制御していることがわかります。
オプション無しでsetup.shを実行すると、uio_pci_genericに移行します。*4
# scripts/setup.sh 0000:03:00.0 (144d a808): nvme -> uio_pci_generic 0000:00:04.0 (8086 3c20): ioatdma -> uio_pci_generic 0000:20:04.0 (8086 3c20): ioatdma -> uio_pci_generic 0000:00:04.1 (8086 3c21): ioatdma -> uio_pci_generic 0000:20:04.1 (8086 3c21): ioatdma -> uio_pci_generic 0000:00:04.2 (8086 3c22): ioatdma -> uio_pci_generic 0000:20:04.2 (8086 3c22): ioatdma -> uio_pci_generic 0000:00:04.3 (8086 3c23): ioatdma -> uio_pci_generic 0000:20:04.3 (8086 3c23): ioatdma -> uio_pci_generic 0000:00:04.4 (8086 3c24): ioatdma -> uio_pci_generic 0000:20:04.4 (8086 3c24): ioatdma -> uio_pci_generic 0000:00:04.5 (8086 3c25): ioatdma -> uio_pci_generic 0000:20:04.5 (8086 3c25): ioatdma -> uio_pci_generic 0000:00:04.6 (8086 3c26): ioatdma -> uio_pci_generic 0000:20:04.6 (8086 3c26): ioatdma -> uio_pci_generic 0000:00:04.7 (8086 3c27): ioatdma -> uio_pci_generic 0000:20:04.7 (8086 3c27): ioatdma -> uio_pci_generic
以下のようになっていれば、OKです。
# scripts/setup.sh status Hugepages node hugesize free / total node0 1048576kB 0 / 1 node1 1048576kB 0 / 1 NVMe devices BDF Numa Node Driver name Device name 0000:03:00.0 0 uio_pci_generic - I/OAT DMA BDF Numa Node Driver Name 0000:00:04.0 0 uio_pci_generic 0000:20:04.0 1 uio_pci_generic 0000:00:04.1 0 uio_pci_generic 0000:20:04.1 1 uio_pci_generic 0000:00:04.2 0 uio_pci_generic 0000:20:04.2 1 uio_pci_generic 0000:00:04.3 0 uio_pci_generic 0000:20:04.3 1 uio_pci_generic 0000:00:04.4 0 uio_pci_generic 0000:20:04.4 1 uio_pci_generic 0000:00:04.5 0 uio_pci_generic 0000:20:04.5 1 uio_pci_generic 0000:00:04.6 0 uio_pci_generic 0000:20:04.6 1 uio_pci_generic 0000:00:04.7 0 uio_pci_generic 0000:20:04.7 1 uio_pci_generic virtio BDF Numa Node Driver Name Device Name
5-3.Targetプログラムの実行
/usr/src/spdkのパス上で以下を実行。
app/nvmf_tgt/nvmf_tgt -c app/nvmf_tgt/nvmf.conf 以下、出力結果。 # app/nvmf_tgt/nvmf_tgt -c app/nvmf_tgt/nvmf.conf Starting SPDK v18.07-pre / DPDK 18.02.0 initialization... [ DPDK EAL parameters: nvmf -c 0x0F --file-prefix=spdk_pid23820 ] EAL: Detected 8 lcore(s) EAL: Multi-process socket /var/run/.spdk_pid23820_unix EAL: Probing VFIO support... app.c: 530:spdk_app_start: *NOTICE*: Total cores available: 4 reactor.c: 718:spdk_reactors_init: *NOTICE*: Occupied cpu socket mask is 0x1 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 1 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 2 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 3 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 0 on socket 0 EAL: PCI device 0000:03:00.0 on NUMA socket 0 EAL: probe driver: 144d:a808 spdk_nvme rdma.c:1454:spdk_nvmf_rdma_create: *ERROR*: rdma_create_event_channel() failed, No such device Segmentation fault (core dumped)
初回起動時に赤文字のエラーを吐く場合は、一度サーバを再起動してみてください。
nvmf_tgtはフォアグラウンドで稼働してしまうため、上記出力(赤文字以外の出力)でプロンプトが停止したように見えますが、nvmf targetは正常に起動できています。
iscsi targetとは異なり、-b(バックグラウンド)オプションはないようです。
また、Debugオプションを使用したい場合、まずは-Lに指定可能な引数を確認するため、-hオプションでnvmf_tgtを起動してあげてください。
# app/nvmf_tgt/nvmf_tgt -h app/nvmf_tgt/nvmf_tgt [options] options: -c config config file (default /usr/local/etc/nvmf/nvmf.conf) -d disable coredump file enabling -e mask tracepoint group mask for spdk trace buffers (default 0x0) -g force creating just one hugetlbfs file -h show this usage -i shared memory ID (optional) -m mask core mask for DPDK -n channel number of memory channels used for DPDK -p core master (primary) core for DPDK -q disable notice level logging to stderr -r RPC listen address (default /var/tmp/spdk.sock) -s size memory size in MB for DPDK (default: all hugepage memory) -u disable PCI access. -w wait for RPCs to initialize subsystems -B addr pci addr to blacklist -R unlink huge files after initialization -W addr pci addr to whitelist (-B and -W cannot be used at the same time) -L flag enable debug log flag (all, aio, bdev, bdev_malloc, bdev_null, bdev_nvme, blob, blob_rw, copy_ioat, gpt_parse, ioat, log, lvol, lvolrpc, nbd, nvme, nvmf, rdma, reactor, rpc, vbdev_gpt, vbdev_lvol, vbdev_passthru, vbdev_split, virtio, virtio_blk, virtio_dev, virtio_pci, virtio_user)
実際にDebugオプションを付けて起動した場合は、こんな感じです。
このように起動した後、Initiatorからアクセスすると、Targetの動きがわかります。
# app/nvmf_tgt/nvmf_tgt -L nvme -L nvmf -L rdma -c app/nvmf_tgt/nvmf.conf
6.NVMe-oF Initiatorからのアクセス
6-1.Initiator側の事前準備
Initiatorのインストール
yum -y install nvme-cli
modprobe実施
modprobe ib_core modprobe ib_umad modprobe ib_uverbs modprobe iw_cm modprobe rdma_cm modprobe rdma_ucm modprobe mlx4_core modprobe mlx4_ib modprobe nvme_rdma
上記のmodprobeが正常終了していれば、以下のように/dev/nvme-fabricsが追加されているハズです。
# ls /dev/ autofs fuse net rtc tty13 tty30 tty48 tty8 vcs6 block hpet network_latency rtc0 tty14 tty31 tty49 tty9 vcsa bsg hpilo network_throughput sda tty15 tty32 tty5 ttyS0 vcsa1 btrfs-control hugepages null sda1 tty16 tty33 tty50 ttyS1 vcsa2 bus hwrng nvme-fabrics sda2 tty17 tty34 tty51 ttyS2 vcsa3 centos infiniband nvram sg0 tty18 tty35 tty52 ttyS3 vcsa4 char initctl port sg1 tty19 tty36 tty53 uhid vcsa5 console input ppp shm tty2 tty37 tty54 uinput vcsa6 core ipmi0 ptmx snapshot tty20 tty38 tty55 urandom vfio cpu kmsg ptp0 snd tty21 tty39 tty56 usbmon0 vga_arbiter cpu_dma_latency kvm ptp1 stderr tty22 tty4 tty57 usbmon1 vhci cuse lightnvm ptp2 stdin tty23 tty40 tty58 usbmon2 vhost-net disk log ptp3 stdout tty24 tty41 tty59 usbmon3 vhost-vsock dm-0 loop-control ptp4 tty tty25 tty42 tty6 vcs watchdog dm-1 mapper ptp5 tty0 tty26 tty43 tty60 vcs1 watchdog0 dri mcelog ptp6 tty1 tty27 tty44 tty61 vcs2 zero fb0 mem pts tty10 tty28 tty45 tty62 vcs3 fd memory_bandwidth random tty11 tty29 tty46 tty63 vcs4 full mqueue raw tty12 tty3 tty47 tty7 vcs5
Discover実施Initiator側
# nvme discover -t rdma -a 192.168.20.200 -s 4791 Discovery Log Number of Records 1, Generation counter 4 =====Discovery Log Entry 0====== trtype: rdma adrfam: ipv4 subtype: nvme subsystem treq: not specified portid: 0 trsvcid: 4791 subnqn: nqn.2016-06.io.spdk:cnode1 traddr: 192.168.20.200 rdma_prtype: not specified rdma_qptype: connected rdma_cms: rdma-cm rdma_pkey: 0x0000
Discover実施Target側
# app/nvmf_tgt/nvmf_tgt -L nvmf -c app/nvmf_tgt/nvmf.conf request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x01 cid 1 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbeee9c800 key 0x10110 len 0x400 ctrlr.c: 321:spdk_nvmf_ctrlr_connect: *INFO*: recfmt 0x0 qid 0 sqsize 31 ctrlr.c: 323:spdk_nvmf_ctrlr_connect: *INFO*: Connect data: ctrlr.c: 324:spdk_nvmf_ctrlr_connect: *INFO*: cntlid: 0xffff ctrlr.c: 332:spdk_nvmf_ctrlr_connect: *INFO*: hostid: 0259e14b-3479-4850-be97-f6006ffa084c *** ctrlr.c: 349:spdk_nvmf_ctrlr_connect: *INFO*: subnqn: "nqn.2014-08.org.nvmexpress.discovery" ctrlr.c: 366:spdk_nvmf_ctrlr_connect: *INFO*: hostnqn: "nqn.2014-08.org.nvmexpress:uuid:eb63ddbc-c01f-4435-8e0b-bbbaf22639f2" ctrlr.c: 389:spdk_nvmf_ctrlr_connect: *INFO*: Connect Admin Queue for controller ID 0xffff ctrlr.c: 207:spdk_nvmf_ctrlr_create: *INFO*: cap 0x20010103ff ctrlr.c: 208:spdk_nvmf_ctrlr_create: *INFO*: vs 0x10300 ctrlr.c: 209:spdk_nvmf_ctrlr_create: *INFO*: cc 0x0 ctrlr.c: 210:spdk_nvmf_ctrlr_create: *INFO*: csts 0x0 ctrlr.c: 104:ctrlr_add_qpair_and_update_rsp: *INFO*: connect capsule response: cntlid = 0x0001 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=1 cdw0=0x00000001 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 1, offset 0x0 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: cap ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x20010103ff request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x010103ff rsvd1=32 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x00 cid 26 ctrlr.c: 598:spdk_nvmf_property_set: *INFO*: size 0, offset 0x14, value 0x460001 ctrlr.c: 608:spdk_nvmf_property_set: *INFO*: name: cc ctrlr.c: 438:nvmf_prop_set_cc: *INFO*: cur CC: 0x00000000 ctrlr.c: 439:nvmf_prop_set_cc: *INFO*: new CC: 0x00460001 ctrlr.c: 449:nvmf_prop_set_cc: *INFO*: Property Set CC Enable! ctrlr.c: 480:nvmf_prop_set_cc: *INFO*: Prop Set IOSQES = 6 (64 bytes) ctrlr.c: 487:nvmf_prop_set_cc: *INFO*: Prop Set IOCQES = 4 (16 bytes) request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x1c ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: csts ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x1 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000001 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x8 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: vs ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x10300 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00010300 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 1, offset 0x0 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: cap ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x20010103ff request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x010103ff rsvd1=32 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x06 fuse 0 cid 26 nsid 0 cdw10 0x00000001 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xc026a1000 key 0x10111 len 0x1000 ctrlr.c:1172:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ctrlr data: maxcmd 0x400 ctrlr.c:1173:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: sgls data: 0x100005 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x02 fuse 0 cid 26 nsid 0 cdw10 0x00030070 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xc09c46000 key 0x10112 len 0x10 ctrlr.c:1082:spdk_nvmf_ctrlr_get_log_page: *INFO*: Get log page: LID=0x70 offset=0x0 len=0x10 ctrlr_discovery.c: 63:nvmf_update_discovery_log: *INFO*: Generating log page for genctr 4 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x02 fuse 0 cid 26 nsid 0 cdw10 0x01ff0070 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbdc640000 key 0x10113 len 0x800 ctrlr.c:1082:spdk_nvmf_ctrlr_get_log_page: *INFO*: Get log page: LID=0x70 offset=0x0 len=0x800 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x00 cid 8 ctrlr.c: 598:spdk_nvmf_property_set: *INFO*: size 0, offset 0x14, value 0x464001 ctrlr.c: 608:spdk_nvmf_property_set: *INFO*: name: cc ctrlr.c: 438:nvmf_prop_set_cc: *INFO*: cur CC: 0x00460001 ctrlr.c: 439:nvmf_prop_set_cc: *INFO*: new CC: 0x00464001 ctrlr.c: 463:nvmf_prop_set_cc: *INFO*: Property Set CC Shutdown 01b! request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=8 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 8 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x1c ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: csts ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x8 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=8 cdw0=0x00000008 rsvd1=0 status=0x0000
Connect実施Initiator側
iSCSIのときとは違い、Successなどは出力されません。
# nvme connect -t rdma -n nqn.2016-06.io.spdk:cnode1 -a 192.168.20.200 -s 4791
Connect実施Target側
Connectが完了すると、定期的にKeepaliveメッセージが流れます。
# nvme connect -t rdma -n nqn.2016-06.io.spdk:cnode1 -a 192.168.20.200 -s 4791 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x01 cid 0 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbeee99000 key 0x10111 len 0x400 ctrlr.c: 321:spdk_nvmf_ctrlr_connect: *INFO*: recfmt 0x0 qid 0 sqsize 31 ctrlr.c: 323:spdk_nvmf_ctrlr_connect: *INFO*: Connect data: ctrlr.c: 324:spdk_nvmf_ctrlr_connect: *INFO*: cntlid: 0xffff ctrlr.c: 332:spdk_nvmf_ctrlr_connect: *INFO*: hostid: 07ca1c45-8f62-493f-a732-7fd3c721f6f9 *** ctrlr.c: 349:spdk_nvmf_ctrlr_connect: *INFO*: subnqn: "nqn.2016-06.io.spdk:cnode1" ctrlr.c: 366:spdk_nvmf_ctrlr_connect: *INFO*: hostnqn: "nqn.2014-08.org.nvmexpress:uuid:eb63ddbc-c01f-4435-8e0b-bbbaf22639f2" ctrlr.c: 389:spdk_nvmf_ctrlr_connect: *INFO*: Connect Admin Queue for controller ID 0xffff ctrlr.c: 207:spdk_nvmf_ctrlr_create: *INFO*: cap 0x20010103ff ctrlr.c: 208:spdk_nvmf_ctrlr_create: *INFO*: vs 0x10300 ctrlr.c: 209:spdk_nvmf_ctrlr_create: *INFO*: cc 0x0 ctrlr.c: 210:spdk_nvmf_ctrlr_create: *INFO*: csts 0x0 ctrlr.c: 104:ctrlr_add_qpair_and_update_rsp: *INFO*: connect capsule response: cntlid = 0x0001 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=0 cdw0=0x00000001 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 1, offset 0x0 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: cap ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x20010103ff request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x010103ff rsvd1=32 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x00 cid 26 ctrlr.c: 598:spdk_nvmf_property_set: *INFO*: size 0, offset 0x14, value 0x460001 ctrlr.c: 608:spdk_nvmf_property_set: *INFO*: name: cc ctrlr.c: 438:nvmf_prop_set_cc: *INFO*: cur CC: 0x00000000 ctrlr.c: 439:nvmf_prop_set_cc: *INFO*: new CC: 0x00460001 ctrlr.c: 449:nvmf_prop_set_cc: *INFO*: Property Set CC Enable! ctrlr.c: 480:nvmf_prop_set_cc: *INFO*: Prop Set IOSQES = 6 (64 bytes) ctrlr.c: 487:nvmf_prop_set_cc: *INFO*: Prop Set IOCQES = 4 (16 bytes) request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x1c ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: csts ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x1 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000001 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x8 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: vs ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x10300 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00010300 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 26 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 1, offset 0x0 ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: cap ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x20010103ff request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x010103ff rsvd1=32 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x06 fuse 0 cid 26 nsid 0 cdw10 0x00000001 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xc026a2000 key 0x10112 len 0x1000 ctrlr.c:1172:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ctrlr data: maxcmd 0x400 ctrlr.c:1173:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: sgls data: 0x100005 ctrlr_bdev.c: 73:spdk_nvmf_subsystem_bdev_io_type_supported: *INFO*: All devices in Subsystem nqn.2016-06.io.spdk:cnode1 support io_type 3 ctrlr_bdev.c: 73:spdk_nvmf_subsystem_bdev_io_type_supported: *INFO*: All devices in Subsystem nqn.2016-06.io.spdk:cnode1 support io_type 9 ctrlr.c:1215:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: ioccsz 0x104 ctrlr.c:1217:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: iorcsz 0x1 ctrlr.c:1219:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: icdoff 0x0 ctrlr.c:1221:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: ctrattr 0x0 ctrlr.c:1223:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: msdbd 0x1 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x02 fuse 0 cid 26 nsid 4294967295 cdw10 0x03ff0005 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xc026a3000 key 0x10113 len 0x1000 ctrlr.c:1082:spdk_nvmf_ctrlr_get_log_page: *INFO*: Get log page: LID=0x05 offset=0x0 len=0x1000 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=26 cdw0=0x00000000 rsvd1=0 status=0x0000 ~・~一部省略~・~ ctrlr.c:1548:spdk_nvmf_ctrlr_keep_alive: *INFO*: Keep Alive request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=0 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x18 fuse 0 cid 0 nsid 0 cdw10 0x00000000 ctrlr.c:1548:spdk_nvmf_ctrlr_keep_alive: *INFO*: Keep Alive request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=0 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: o
List確認Initiator側
# nvme list
Node SN Model Namespace Usage Format FW Rev
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1 SPDK00000000000001 SPDK bdev Controller 1 250.06 GB / 250.06 GB 512 B + 0 B 18.10
List確認Target側
request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x06 fuse 0 cid 18 nsid 0 cdw10 0x00000001 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbe37f8000 key 0x10120 len 0x1000 ctrlr.c:1172:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ctrlr data: maxcmd 0x400 ctrlr.c:1173:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: sgls data: 0x100005 ctrlr_bdev.c: 73:spdk_nvmf_subsystem_bdev_io_type_supported: *INFO*: All devices in Subsystem nqn.2016-06.io.spdk:cnode1 support io_type 3 ctrlr_bdev.c: 73:spdk_nvmf_subsystem_bdev_io_type_supported: *INFO*: All devices in Subsystem nqn.2016-06.io.spdk:cnode1 support io_type 9 ctrlr.c:1215:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: ioccsz 0x104 ctrlr.c:1217:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: iorcsz 0x1 ctrlr.c:1219:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: icdoff 0x0 ctrlr.c:1221:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: ctrattr 0x0 ctrlr.c:1223:spdk_nvmf_ctrlr_identify_ctrlr: *INFO*: ext ctrlr data: msdbd 0x1 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=18 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 121:nvmf_trace_command: *INFO*: Admin cmd: opc 0x06 fuse 0 cid 18 nsid 1 cdw10 0x00000000 request.c: 136:nvmf_trace_command: *INFO*: SGL: Keyed (Inv): addr 0xbe37f8000 key 0x10121 len 0x1000 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=18 cdw0=0x00000000 rsvd1=0 status=0x0000
bdevとして認識されていることを確認*5
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 136.8G 0 disk
tqsda1 8:1 0 1G 0 part /boot
mqsda2 8:2 0 135.7G 0 part
tqcentos-root 253:0 0 131.7G 0 lvm /
mqcentos-swap 253:1 0 4G 0 lvm [SWAP]
sr0 11:0 1 1024M 0 rom
nvme0n1 259:0 0 232.9G 0 disk
Disconnect実施Initiator側
# nvme disconnect -n "nqn.2016-06.io.spdk:cnode1" NQN:nqn.2016-06.io.spdk:cnode1 disconnected 1 controller(s)
Disconnect実施Target側
request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x00 cid 18 ctrlr.c: 598:spdk_nvmf_property_set: *INFO*: size 0, offset 0x14, value 0x464001 ctrlr.c: 608:spdk_nvmf_property_set: *INFO*: name: cc ctrlr.c: 438:nvmf_prop_set_cc: *INFO*: cur CC: 0x00460001 ctrlr.c: 439:nvmf_prop_set_cc: *INFO*: new CC: 0x00464001 ctrlr.c: 463:nvmf_prop_set_cc: *INFO*: Property Set CC Shutdown 01b! request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=18 cdw0=0x00000000 rsvd1=0 status=0x0000 request.c: 116:nvmf_trace_command: *INFO*: Admin Fabrics cmd: fctype 0x04 cid 18 ctrlr.c: 557:spdk_nvmf_property_get: *INFO*: size 0, offset 0x1c ctrlr.c: 573:spdk_nvmf_property_get: *INFO*: name: csts ctrlr.c: 583:spdk_nvmf_property_get: *INFO*: response value: 0x8 request.c: 92:spdk_nvmf_request_complete: *INFO*: cpl: cid=18 cdw0=0x00000008 rsvd1=0 status=0x0000
上記InitiatorとTargetのやり取りをPcapしたファイルを以下にアップしておきます。
roce02.pcapng
あとは、iSCSI Targetと同様に動作しますので、Initiator側でmkfsするなり、fioで速度測定するなりご自由にどうぞ。
以上です。
7.補足その1:ReactorMaskについて
ReactorMaskとは、PMD(Poll Mode Driver)で専有させるCPUコアを明示的に指定するためのものです。NVMe-oF targetの場合、SSDが管理されているNUMA socket*6と同じNUMA socket上のCPUコアを明示的に指定することでパフォーマンスが向上します。このため、ReactorMaskでPMDが専有するCPUコアを明示的に指定することが重要となってきます。
それでは、CPUコアを明示的に指定する方法を具体例を交えて解説します。
lscpuの結果
# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 8 On-line CPU(s) list: 0-7 Thread(s) per core: 1 Core(s) per socket: 4 Socket(s): 2 NUMA node(s): 2 Vendor ID: GenuineIntel CPU family: 6 Model: 45 Model name: Intel(R) Xeon(R) CPU E5-2407 0 @ 2.20GHz Stepping: 7 CPU MHz: 1200.000 CPU max MHz: 2200.0000 CPU min MHz: 1200.0000 BogoMIPS: 4389.14 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 10240K NUMA node0 CPU(s): 0-3 NUMA node1 CPU(s): 4-7 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm epb tpr_shadow vnmi flexpriority ept vpid xsaveopt ibpb ibrs stibp dtherm arat pln pts spec_ctrl intel_stibp
今回使用したサーバ(DL360e)の場合、2ソケット、Hyperスレッド無し、4コアなので、トータル8コアあります。
さらに、NUMA socketの割り当ては以下のようになっています。
NUMA socket(node)0:0-3コア
NUMA socket(node)1:4-7コア
また、nvmf_tgtの実行結果から、SSDがNUMA socket(node)0で動作していることがわかります。
# app/nvmf_tgt/nvmf_tgt -c app/nvmf_tgt/nvmf.conf Starting SPDK v18.07-pre / DPDK 18.02.0 initialization... [ DPDK EAL parameters: nvmf -c 0x0E --file-prefix=spdk_pid17014 ] EAL: Detected 8 lcore(s) EAL: Multi-process socket /var/run/.spdk_pid17014_unix EAL: Probing VFIO support... app.c: 530:spdk_app_start: *NOTICE*: Total cores available: 3 reactor.c: 718:spdk_reactors_init: *NOTICE*: Occupied cpu socket mask is 0x1 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 2 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 3 on socket 0 reactor.c: 492:_spdk_reactor_run: *NOTICE*: Reactor started on core 1 on socket 0 EAL: PCI device 0000:03:00.0 on NUMA socket 0 EAL: probe driver: 144d:a808 spdk_nvme
上記結果より、PMDに専有させたいコアは「NUMA socket(node)0:0-3」となります。
このときのReactorMaskの指定方法は、
[Global] ReactorMask 0x0F
となります。
CPUコアの並び順は以下のようになっています。
7654 3210
lscpuの結果より、
7654がNUMA socket(node)1
3210がNUMA socket(node)0
となります。
ReactorMaskのうち、0x0Fを2進数に変換すると、以下のようになります。
16進数 0x0F 2進数 0000 1111
CPUコアの並びと2進数に変換したReactorMaskを合わせると
7654 3210 0000 1111
となり、ReactorMaskのうち「1」が立っているCPUがPMDに専有されます。
考え方としては、SubnetMaskと同様ですね。
今回の場合、あまり意味はないですが、例えば、奇数番号のコアだけを使用したい場合は、
CPUコア 7654 3210 2進数 1010 1010 16進数 0xAA
となります。
8.補足その2:fioの実施結果
fioを実施してみました。
結果、10Gbpsをフルに使用したパフォーマンスを出してくれました。
但し、Samsung SSD 250GB 970 EVOのシーケンシャルリードの公称値が3400MBps(27.2Gbps)なので、Mellanox製NICがボトルネックとなっています。
これについては、40GNIC or 100GNICで試せたらいいなと考えています。
fio設定ファイル
# cat seqread4.fio [global] filename=/dev/nvme0n1 group_reporting=1 direct=1 ioengine=libaio [seqread4] readwrite=read blocksize=32m size=10g numjobs=2 loops=2
fio実行結果
# fio seqread4.fio seqread4: (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.1 Starting 2 processes Jobs: 2 (f=2): [R(2)][100.0%][r=1185MiB/s,w=0KiB/s][r=37,w=0 IOPS][eta 00m:00s] seqread4: (groupid=0, jobs=2): err= 0: pid=13105: Thu Aug 23 15:26:47 2018 read: IOPS=36, BW=1167MiB/s (1224MB/s)(40.0GiB/35097msec) slat (usec): min=26489, max=30909, avg=28159.67, stdev=289.25 clat (usec): min=13362, max=27098, avg=26659.48, stdev=449.47 lat (usec): min=40354, max=56431, avg=54820.49, stdev=422.94 clat percentiles (usec): | 1.00th=[25560], 5.00th=[26346], 10.00th=[26346], 20.00th=[26608], | 30.00th=[26608], 40.00th=[26608], 50.00th=[26608], 60.00th=[26608], | 70.00th=[26870], 80.00th=[26870], 90.00th=[26870], 95.00th=[26870], | 99.00th=[26870], 99.50th=[26870], 99.90th=[27132], 99.95th=[27132], | 99.99th=[27132] bw ( KiB/s): min=588646, max=656673, per=49.95%, avg=596887.99, stdev=20330.41, samples=140 iops : min= 17, max= 20, avg=18.20, stdev= 0.61, samples=140 lat (msec) : 20=0.08%, 50=99.92% cpu : usr=0.02%, sys=3.94%, ctx=21806, majf=0, minf=1107 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 rwt: total=1280,0,0, short=0,0,0, dropped=0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): READ: bw=1167MiB/s (1224MB/s), 1167MiB/s-1167MiB/s (1224MB/s-1224MB/s), io=40.0GiB (42.9GB), run=35097-35097msec Disk stats (read/write): nvme0n1: ios=325850/0, merge=0/0, ticks=6298513/0, in_queue=6471868, util=99.76%
1224MBps=9792Mbps
9.最後に
以下のサイトを参考にさせて頂きました。
SPDK: NVMe over Fabrics Target
Intel SPDK NVMe-oF Target Performance Tuning. Part 2: Preparing testing environment | StarWind Blog
CentOS7でelrepoリポジトリを有効化してkernel-mlを入れる - Qiita
kernelのBugにヒットした際、仕方なく4.17系でリビルドして何とかPcapに成功したのですが、リビルドの手順も合せてこのBlogに記載するのは本編からブレるため、4.18.4がリリースされるまで待ちました。ただ予想以上に早くリリースして頂いたので、コミッターの方にはとても感謝しています。
この記事によるとNVMe市場は2020年までに570億ドル(日本円で6兆円超)規模の市場になるらしいです。
blog.calsoftinc.com
なので、早めにキャッチアップ&修得しておいて損はない技術かなと思っています。
また、以前FCoEの勉強をしていたため、RoCEは前々から気になっていました。
metonymical.hatenablog.com
FCoEはあっという間に消えてしまいましたが、RoCEはNVMe-oFのうちover Fabricの部分で残りそうな予感がしています。
oEやoCEの部分では既に規格があります*7が、RoCEv2がいいかも?と思った点は、それに加えて、IP&UDPを乗せたところだと思っています。
EthernetやIPの世界では既に400Gbpsのスイッチも市場に出始めていますし、100G×32ポート程度のスイッチであれば100万円ちょい&100GBase-SR4のQSFP28でも1万円ちょいで購入できます。
このような状況を踏まえれば、EthernetやIPをFabricとして使用したとしても、高性能なNVMe対応ストレージに対して、充分な性能を担保できるのでは?と考えています。また、導入コストやスケーラビリティの点を含めて考えても、IBやFCと対等に渡り合えるのではないかと考えています。
なので、例えば、IP CLOSネットワーク上でRoCEv2を動作させて、障害時の切替検証や複数InitiatorからTargetへのアクセス時における負荷分散など、といったシチュエーションにおける最適なネットワーク設計を検討していきたいと考えています。
*1:あえて、-yオプションを付けていません。万が一、4.18系Kernelで、4.18.4-1以前のバージョンだった場合、リポジトリからミラーサイトのURLを全て削除してください。4.18.1-1や4.18.3-1などの場合、uio_pci_genericのBugを踏むことになりTargetを起動できません。
*2:この後、yum swapしますので、最新までアップデートしてください。
*3:ここのパスが基点となります。
*4:GRUB_CMDLINE_LINUX=の行末に、intel_iommu=on iommu=pt pci=realloc も追記すると、uioの代わりにvfio-pciで稼働するようになりますが、HPのアドバイザリにヒットしたため、今回はuio_pci_genericで行っています。また、Kernel4.18系のうち、4.18.3-1以前のバージョンの場合、uio_pci_genericに移行できず、空欄となるBugを踏むことになります。
*5:setup.shの実行直後にlsblkを実行すると、nvmeはカーネルの制御から解放されているためlsblkでは見えなくなります。その後、Initiator側からConnectして、lsblkを実行すると、nvme0n1が見えるようになります。
*6:NUMA socketとかNUMA nodeと言ったりします。厳密には異なりますが、今回は同じ用語だと考えてください。
*7:DCBXとして、802.1Qau(Congestion Notification)、802.1Qaz(Enhanced Transmission Selection)、802.1Qbb(Priority-based Flow Control)に加えて、SPB、TRILLなどがあります。
MPLS over GRE over IPSec with IKEv2
Cisco891FJ×2台構成でMPLS over GRE over IPSec with IKEv2を実装してみました。
IPSec with IKEv2の部分について
トンネルの暗号化はcrypto mapを使うとACLを書くのが大変なので、AWSのVGWでもサンプルConfigが公開されているipsec profileにしています。
また、isakmpはちょっぴり不安なのでIKEv2に変更しています。
MPLS over GREの部分について
MP-BGPにてMPLSを使うため、tunnel mode ipsec ipv4ではなく、多少のオーバーヘッドは掛かりますが、デフォルトのtunnel mode gre ip(DefaultなのでConfig上は表示されません)にしました。
1.構成
RTAとRTBがCisco891FJとなっています。
Versionは15.7(3)M2ですが、多少古くても大丈夫だと思います。
Internetを模倣するために、RTAとRTBの間にCat3560Eを挟んでConnected同士でRoutingしています。
四の五の説明するより、Configを見てもらった方が早いと思います。
2.RTAのConfig
! hostname RTA ! ip cef ! ip vrf r1 rd 10.0.0.1:1 route-target export 65000:1 route-target import 65000:1 ! ip vrf r2 rd 10.0.0.1:2 route-target export 65000:2 route-target import 65000:2 ! ! crypto ikev2 proposal ikev2prop encryption aes-cbc-256 integrity sha256 group 14 ! crypto ikev2 policy ikev2poli proposal ikev2prop ! crypto ikev2 keyring ikev2key peer RTB address 2.2.2.2 pre-shared-key PASSWORD ! crypto ikev2 profile ikev2prof match identity remote address 2.2.2.2 255.255.255.255 identity local address 1.1.1.1 authentication remote pre-share authentication local pre-share keyring local ikev2key lifetime 3600 ! ! crypto ipsec transform-set LAB-TS esp-aes 256 esp-sha256-hmac mode tunnel ! crypto ipsec profile LAB-ipsec-profile set transform-set LAB-TS set ikev2-profile ikev2prof ! ! interface Tunnel100 ip address 10.0.0.1 255.255.255.0 mpls bgp forwarding mpls ip tunnel source 1.1.1.1 tunnel destination 2.2.2.2 tunnel path-mtu-discovery tunnel protection ipsec profile LAB-ipsec-profile ! interface GigabitEthernet8 ip address 1.1.1.1 255.255.255.0 duplex auto speed auto ! interface Vlan11 ip vrf forwarding r1 ip address 192.168.11.1 255.255.255.0 ! interface Vlan12 ip vrf forwarding r2 ip address 192.168.12.1 255.255.255.0 ! ! router bgp 65000 bgp router-id 10.0.0.1 bgp log-neighbor-changes neighbor 10.0.0.2 remote-as 65001 neighbor 10.0.0.2 update-source Tunnel100 ! address-family ipv4 neighbor 10.0.0.2 activate neighbor 10.0.0.2 soft-reconfiguration inbound exit-address-family ! address-family vpnv4 neighbor 10.0.0.2 activate neighbor 10.0.0.2 send-community both exit-address-family ! address-family ipv4 vrf r1 network 192.168.11.0 exit-address-family ! address-family ipv4 vrf r2 network 192.168.12.0 exit-address-family ! ! mpls ldp router-id Tunnel100 ! ip route 0.0.0.0 0.0.0.0 1.1.1.2 !
3.RTBのConfig
! hostname RTB ! ip cef ! ip vrf r1 rd 10.0.0.2:1 route-target export 65000:1 route-target import 65000:1 ! ip vrf r2 rd 10.0.0.2:2 route-target export 65000:2 route-target import 65000:2 ! ! crypto ikev2 proposal ikev2prop encryption aes-cbc-256 integrity sha256 group 14 ! crypto ikev2 policy ikev2poli proposal ikev2prop ! crypto ikev2 keyring ikev2key peer RTA address 1.1.1.1 pre-shared-key PASSWORD ! crypto ikev2 profile ikev2prof match identity remote address 1.1.1.1 255.255.255.255 identity local address 2.2.2.2 authentication remote pre-share authentication local pre-share keyring local ikev2key lifetime 3600 ! ! crypto ipsec transform-set LAB-TS esp-aes 256 esp-sha256-hmac mode tunnel ! crypto ipsec profile LAB-ipsec-profile set transform-set LAB-TS set ikev2-profile ikev2prof ! ! interface Tunnel100 ip address 10.0.0.2 255.255.255.0 mpls bgp forwarding mpls ip tunnel source 2.2.2.2 tunnel destination 1.1.1.1 tunnel path-mtu-discovery tunnel protection ipsec profile LAB-ipsec-profile ! interface GigabitEthernet8 ip address 2.2.2.2 255.255.255.0 duplex auto speed auto ! interface Vlan13 ip vrf forwarding r1 ip address 192.168.13.1 255.255.255.0 ! interface Vlan14 ip vrf forwarding r2 ip address 192.168.14.1 255.255.255.0 ! ! router bgp 65001 bgp router-id 10.0.0.2 bgp log-neighbor-changes neighbor 10.0.0.1 remote-as 65000 neighbor 10.0.0.1 update-source Tunnel100 ! address-family ipv4 neighbor 10.0.0.1 activate neighbor 10.0.0.1 soft-reconfiguration inbound exit-address-family ! address-family vpnv4 neighbor 10.0.0.1 activate neighbor 10.0.0.1 send-community both exit-address-family ! address-family ipv4 vrf r1 network 192.168.13.0 exit-address-family ! address-family ipv4 vrf r2 network 192.168.14.0 exit-address-family ! ! mpls ldp router-id Tunnel100 ! ip route 0.0.0.0 0.0.0.0 2.2.2.1 !
以上です。
4.最後に
以下のサイトを参考にさせて頂きました。
http://www.networking-forum.com/viewtopic.php?t=28459#
今回は検証できていませんが、複数拠点で構成する場合、tunnel mode gre multipointでもイケる気がしています。そうすることで(Ciscoの)FlexVPNとしての実装もできそうな感じがします。
先にも書きましたが、tunnel mode ipsec ipv4について少々補足します。ipsec ipv4にした場合、VTI(VirtualTunnelInterface)を使用することになるため、オーバーヘッドが減少するそうです。しかし、今回の場合は、ipsec ipv4を入れると、MPLSヘッダのついたパケットがIPパケットとして(当然のことながら)認識されないためトンネルを越えられなくなります。このため、Defaultのgre ipとしています。
もう一点、rdとroute-targetについて補足します。
ip vrf r1 rd 10.0.0.1:1 route-target export 65000:1 route-target import 65000:1
rdは一般的に双方のRTで合わせますが、異なっていても問題ありません。
しかし、route-targetは双方のRTで一致していないといけないため、65000:1としていますが、(router bgpに記載のASNと一致させなくてもよいという意味で)10:1とかでも問題ありません。
CentOS7でCephブロックデバイスの構築
CentOS7上でCephブロックデバイスを構築しました。
Cephは、オブジェクト、ブロック、ファイルストレージを1つの統一されたシステムで独自に提供してくれます。今回はこのうちブロックデバイスの構築を実施します。
Windows版VMWareWorkstation12上でCentOS7.5を3台稼働させて構築しましたが、同様の手順でベアメタルサーバ上にも構築できます。
1.環境
1-1.VMWare
筐体 : 自作PC CPU : Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz VMWare : VMware(R) Workstation 12 Pro 12.5.9 build-7535481 OS : CentOS7.5(1804) Kernel : 3.10.0-862.el7.x86_64 Installed Environment Groups : Server with GUI
WinおよびVMWare環境は以下の画像で確認してもらった方が良いかもしれません。
Win環境
VMWare環境
50GBのOS用とは別に100GB×2のHDDを追加しています。
これをマスター(ceph00)として、クローンを3台分(ceph01,ceph02,ceph03)作成しておきます。
1-3.全体の流れ
各ノード共通設定
cephのインストール
cephブロックデバイス設定
2.各ノード共通設定
3台のノード全てに同一の設定を行っていきます。
2-1.セキュリティ設定の無効化
firewalldとSELinuxを無効化します。
systemctl disable firewalld vi /etc/selinux/config で開いて SELINUX=disabled にして保存。
また、ここでは触れませんが、chronyなどで時刻同期を行ってください。
2-2.パスワード無しsshログイン設定
#ssh-keygen -N "" -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): #そのままEnter Created directory '/root/.ssh'. Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:oaQzt0YznhT9W2ZjSQtqSNgT8+OE2y5zUp7J9++aCeM root@ceph01.md.jp The key's randomart image is: +---[RSA 2048]----+ | o | | o * | | . B * . . | | + X = o o | | + X S . O | | B @ o * . | | O B = | | . = o + o | | E =+o | +----[SHA256]-----+
次に3台のノードにそれぞれ鍵をコピーしていきます。
このとき、ホスト名もしくはFQDNで各ノードにアクセスできるようにhostsファイルもしくはDNSサーバの設定を実施しておいてください。
#ssh-copy-id root@ceph01.md.jp /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" The authenticity of host 'ceph01.md.jp (192.168.11.121)' can't be established. ECDSA key fingerprint is SHA256:nC6u8EYKElp2okhoYNCqJatrYlCzWi8ZtRudjt9VHQA. ECDSA key fingerprint is MD5:6e:45:af:09:1a:be:10:af:8f:31:b9:f1:81:2a:2a:58. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@ceph01.md.jp's password: #パスワードを入力 Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'root@ceph01.md.jp'" and check to make sure that only the key(s) you wanted were added. 上記と同様に他2台分のカギもコピー #ssh-copy-id root@ceph02.md.jp #ssh-copy-id root@ceph03.md.jp
3.cephのインストール
ここからはadminノード(ceph01)のみで操作を行います。
3-2.ceph.confの設定
各ノード間通信を行うNWアドレスを追加
# vi ceph.conf
[global]
fsid = fad4e572-b6cb-47e7-b38e-ed41fa1545c0
mon_initial_members = ceph01, ceph02, ceph03
mon_host = 192.168.11.121,192.168.11.122,192.168.11.123
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
public network = 192.168.11.0/24
3-3.cephのインストール
何も問題がなければ、以下のコマンド一発でインストール可能なのですが、途中で止まる時がちょいちょいありました。なので、エラー吐いて止まった場合は、「5.トラブルシュート」を参照してください。
# ceph-deploy install --release mimic ceph01.md.jp ceph02.md.jp ceph03.md.jp
3-4.インストール後の設定
監視ノードの初期化
設定とadminキーを各ノードに展開
各ノードのディスクをOSDとして登録
# ceph-deploy mon create-initial # ceph-deploy admin ceph01.md.jp ceph02.md.jp ceph03.md.jp # ceph-deploy osd create ceph01.md.jp --data /dev/sdb && \ ceph-deploy osd create ceph01.md.jp --data /dev/sdc && \ ceph-deploy osd create ceph02.md.jp --data /dev/sdb && \ ceph-deploy osd create ceph02.md.jp --data /dev/sdc && \ ceph-deploy osd create ceph03.md.jp --data /dev/sdb && \ ceph-deploy osd create ceph03.md.jp --data /dev/sdc
3-5.管理マネージャの起動
ディレクトリと空ファイル作成
mgr.adminのキー生成
空ファイルにキーを追記
管理マネージャ起動
# mkdir /var/lib/ceph/mgr/ceph-admin # touch /var/lib/ceph/mgr/ceph-admin/keyring # ceph --cluster ceph auth get-or-create mgr.admin mon 'allow profile mgr' osd 'allow *' mds 'allow *' [mgr.admin] key = AQAXT0BbUiPaCRAAwqwc/7UEzfzB8Ts9qDNf2g== #上記の鍵を空ファイルに追記して保存 # vi /var/lib/ceph/mgr/ceph-admin/keyring [mgr.admin] key = AQAXT0BbUiPaCRAAwqwc/7UEzfzB8Ts9qDNf2g== # ceph-mgr -i admin
3-6.起動確認
#ps -C ceph-mgr PID TTY TIME CMD 58425 ? 00:00:00 ceph-mgr # ceph -s cluster: id: fad4e572-b6cb-47e7-b38e-ed41fa1545c0 health: HEALTH_OK services: mon: 3 daemons, quorum ceph01,ceph02,ceph03 mgr: admin(active) osd: 6 osds: 6 up, 6 in data: pools: 0 pools, 0 pgs objects: 0 objects, 0 bytes usage: 6163 MB used, 593 GB / 599 GB avail pgs:
4.cephブロックデバイス設定
4-1.プール作成およびイメージ作成
poolの作成
poolの初期化
イメージの作成
イメージとブロックデバイスのマッピング
# ceph osd pool create pool01 128 pool 'pool01' created # rbd pool init pool01 # rbd create vol01 -p pool01 --size 10G --image-feature layering # rbd map vol01 -p pool01 /dev/rbd0
pool01という名前のプール作成
pool01を初期化
pool01上にvol01という名前の10GB空イメージを作成
pool01上のvol01をブロックデバイスとしてマッピングすることで、/dev/rbd0というデバイスが追加される。
あとは、通常のディスク(ブロックデバイス)と同様にfdiskやmkfsを構成することが可能です。
4-2.各種情報の確認
プールの確認
プール内イメージの確認
イメージの情報(容量など)確認
ブロックデバイスの確認
# rados lspools pool01 # rbd ls pool01 vol01 # rbd info pool01/vol01 rbd image 'vol01': size 10240 MB in 2560 objects order 22 (4096 kB objects) block_name_prefix: rbd_data.103f74b0dc51 format: 2 features: layering flags: create_timestamp: Sat Jul 7 13:35:56 2018 # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 50G 0 disk tqsda1 8:1 0 1G 0 part /boot mqsda2 8:2 0 49G 0 part tqcentos-root 253:0 0 47G 0 lvm / mqcentos-swap 253:1 0 2G 0 lvm [SWAP] sdb 8:16 0 100G 0 disk mqceph--fab7c5a8--f170--4a59--93b4--68948d9c91a1-osd--block--9024dc2b--ef0e--403b--bbd1--eec740127c24 253:2 0 100G 0 lvm sdc 8:32 0 100G 0 disk mqceph--4fc60b45--ac73--470f--beac--ea58fcb809ee-osd--block--ecff0a57--aee5--4119--9769--0156b634ad34 253:3 0 100G 0 lvm sr0 11:0 1 1024M 0 rom rbd0 252:0 0 10G 0 disk
4-3.プールやイメージの削除方法
Default設定ではプール削除などができないようになっているため少々厄介です。
イメージのアンマップ
イメージの削除(1つのプールに複数のイメージがある場合は全イメージを削除)
pool削除の許可設定を追加
ceph-monのリスタート
poolの削除禁止設定を無効化
プールの削除
# rbd unmap -p pool01 --image vol01 # rbd remove -p pool01 --image vol01 Removing image: 100% complete...done. #vi /etc/ceph/ceph.conf 最終行に以下を追記 [mon] mon allow pool delete = true # systemctl restart ceph-mon.target # for pool in $(rados lspools); do ceph osd pool set $pool nodelete false; done set pool 1 nodelete to false # ceph osd pool delete pool01 pool01 --yes-i-really-really-mean-it
5.トラブルシュート
私の場合、なぜか?土日にインストールコマンドを実行すると、YumのDL時に途中で止まる事象を確認しました。
途中で止まってしまう箇所は以下の通り。
以下、抜粋 [ceph01.md.jp][DEBUG ] Dependencies Resolved [ceph01.md.jp][DEBUG ] [ceph01.md.jp][DEBUG ] ================================================================================ [ceph01.md.jp][DEBUG ] Package Arch Version Repository [ceph01.md.jp][DEBUG ] Size [ceph01.md.jp][DEBUG ] ================================================================================ [ceph01.md.jp][DEBUG ] Installing: [ceph01.md.jp][DEBUG ] ceph x86_64 2:12.2.5-0.el7 Ceph 3.0 k [ceph01.md.jp][DEBUG ] ceph-radosgw x86_64 2:12.2.5-0.el7 Ceph 3.8 M [ceph01.md.jp][DEBUG ] Installing for dependencies: [ceph01.md.jp][DEBUG ] ceph-base x86_64 2:12.2.5-0.el7 Ceph 3.9 M [ceph01.md.jp][DEBUG ] ceph-common x86_64 2:12.2.5-0.el7 Ceph 15 M [ceph01.md.jp][DEBUG ] ceph-mds x86_64 2:12.2.5-0.el7 Ceph 3.6 M [ceph01.md.jp][DEBUG ] ceph-mgr x86_64 2:12.2.5-0.el7 Ceph 3.6 M [ceph01.md.jp][DEBUG ] ceph-mon x86_64 2:12.2.5-0.el7 Ceph 5.0 M [ceph01.md.jp][DEBUG ] ceph-osd x86_64 2:12.2.5-0.el7 Ceph 13 M [ceph01.md.jp][DEBUG ] ceph-selinux x86_64 2:12.2.5-0.el7 Ceph 20 k [ceph01.md.jp][DEBUG ] leveldb x86_64 1.12.0-11.el7 epel 161 k [ceph01.md.jp][DEBUG ] libbabeltrace x86_64 1.2.4-3.el7 epel 147 k [ceph01.md.jp][DEBUG ] libcephfs2 x86_64 2:12.2.5-0.el7 Ceph 432 k [ceph01.md.jp][DEBUG ] libradosstriper1 x86_64 2:12.2.5-0.el7 Ceph 330 k [ceph01.md.jp][DEBUG ] librgw2 x86_64 2:12.2.5-0.el7 Ceph 1.7 M [ceph01.md.jp][DEBUG ] lttng-ust x86_64 2.4.1-4.el7 epel 176 k [ceph01.md.jp][DEBUG ] mailcap noarch 2.1.41-2.el7 base 31 k [ceph01.md.jp][DEBUG ] pyOpenSSL x86_64 0.13.1-3.el7 base 133 k [ceph01.md.jp][DEBUG ] python-babel noarch 0.9.6-8.el7 base 1.4 M [ceph01.md.jp][DEBUG ] python-beaker noarch 1.5.4-10.el7 base 80 k [ceph01.md.jp][DEBUG ] python-cephfs x86_64 2:12.2.5-0.el7 Ceph 82 k [ceph01.md.jp][DEBUG ] python-cherrypy noarch 3.2.2-4.el7 base 422 k [ceph01.md.jp][DEBUG ] python-flask noarch 1:0.10.1-4.el7 extras 204 k [ceph01.md.jp][DEBUG ] python-itsdangerous noarch 0.23-2.el7 extras 24 k [ceph01.md.jp][DEBUG ] python-jinja2 noarch 2.7.2-2.el7 base 515 k [ceph01.md.jp][DEBUG ] python-mako noarch 0.8.1-2.el7 base 307 k [ceph01.md.jp][DEBUG ] python-markupsafe x86_64 0.11-10.el7 base 25 k [ceph01.md.jp][DEBUG ] python-paste noarch 1.7.5.1-9.20111221hg1498.el7 base 866 k [ceph01.md.jp][DEBUG ] python-pecan noarch 0.4.5-2.el7 epel 255 k [ceph01.md.jp][DEBUG ] python-prettytable noarch 0.7.2-3.el7 base 37 k [ceph01.md.jp][DEBUG ] python-rados x86_64 2:12.2.5-0.el7 Ceph 172 k [ceph01.md.jp][DEBUG ] python-rbd x86_64 2:12.2.5-0.el7 Ceph 105 k [ceph01.md.jp][DEBUG ] python-requests noarch 2.6.0-1.el7_1 base 94 k [ceph01.md.jp][DEBUG ] python-rgw x86_64 2:12.2.5-0.el7 Ceph 73 k [ceph01.md.jp][DEBUG ] python-simplegeneric noarch 0.8-7.el7 epel 12 k [ceph01.md.jp][DEBUG ] python-singledispatch noarch 3.4.0.2-2.el7 epel 18 k [ceph01.md.jp][DEBUG ] python-tempita noarch 0.5.1-6.el7 base 33 k [ceph01.md.jp][DEBUG ] python-urllib3 noarch 1.10.2-5.el7 base 102 k [ceph01.md.jp][DEBUG ] python-webob noarch 1.2.3-7.el7 base 202 k [ceph01.md.jp][DEBUG ] python-webtest noarch 1.3.4-6.el7 base 102 k [ceph01.md.jp][DEBUG ] python-werkzeug noarch 0.9.1-2.el7 extras 562 k [ceph01.md.jp][DEBUG ] userspace-rcu x86_64 0.7.16-1.el7 epel 73 k [ceph01.md.jp][DEBUG ] Updating for dependencies: [ceph01.md.jp][DEBUG ] librados2 x86_64 2:12.2.5-0.el7 Ceph 2.9 M [ceph01.md.jp][DEBUG ] librbd1 x86_64 2:12.2.5-0.el7 Ceph 1.1 M [ceph01.md.jp][DEBUG ] [ceph01.md.jp][DEBUG ] Transaction Summary [ceph01.md.jp][DEBUG ] ================================================================================ [ceph01.md.jp][DEBUG ] Install 2 Packages (+39 Dependent packages) [ceph01.md.jp][DEBUG ] Upgrade ( 2 Dependent packages) [ceph01.md.jp][DEBUG ] [ceph01.md.jp][DEBUG ] Total download size: 60 M [ceph01.md.jp][DEBUG ] Downloading packages: [ceph01.md.jp][DEBUG ] No Presto metadata available for Ceph ここで5分待たされて、以下の表示で止まる。 [ceph01.md.jp][WARNIN] No data was received after 300 seconds, disconnecting... [ceph01.md.jp][INFO ] Running command: ceph --version [ceph01.md.jp][ERROR ] Traceback (most recent call last): [ceph01.md.jp][ERROR ] File "/usr/lib/python2.7/site-packages/ceph_deploy/lib/vendor/remoto/process.py", line 119, in run [ceph01.md.jp][ERROR ] reporting(conn, result, timeout) [ceph01.md.jp][ERROR ] File "/usr/lib/python2.7/site-packages/ceph_deploy/lib/vendor/remoto/log.py", line 13, in reporting [ceph01.md.jp][ERROR ] received = result.receive(timeout) [ceph01.md.jp][ERROR ] File "/usr/lib/python2.7/site-packages/ceph_deploy/lib/vendor/remoto/lib/vendor/execnet/gateway_base.py", line 704, in receive [ceph01.md.jp][ERROR ] raise self._getremoteerror() or EOFError() [ceph01.md.jp][ERROR ] RemoteError: Traceback (most recent call last): [ceph01.md.jp][ERROR ] File "/usr/lib/python2.7/site-packages/ceph_deploy/lib/vendor/remoto/lib/vendor/execnet/gateway_base.py", line 1036, in executetask [ceph01.md.jp][ERROR ] function(channel, **kwargs) [ceph01.md.jp][ERROR ] File "", line 12, in _remote_run [ceph01.md.jp][ERROR ] File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__ [ceph01.md.jp][ERROR ] errread, errwrite) [ceph01.md.jp][ERROR ] File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child [ceph01.md.jp][ERROR ] raise child_exception [ceph01.md.jp][ERROR ] OSError: [Errno 2] No such file or directory [ceph01.md.jp][ERROR ] [ceph01.md.jp][ERROR ] [ceph_deploy][ERROR ] RuntimeError: Failed to execute command: ceph --version
よくよく動きを観察していると、ceph-radosgwやceph-osdのDLが遅すぎてタイムアウトするような状態となっている事象でした。一台目のノードで引っ掛かると、他のノードにおいても同様に上記の箇所で都度停止してしまいます。
このため、少々ダサい方法ですが各ノードに対して手動でインストールします。
5-1.各ノードでインストールの実行
各ノード(ceph01,ceph02,ceph03)にsshでログインしてください。
ceph01
yumが動作したままになっている可能性が高いのでKillしてください。 # ps -aux | grep yum root 2038 0.7 7.2 1020036 135832 pts/0 S 12:51 0:02 /usr/bin/python /usr/bin/yum -y install ceph ceph-radosgw root 2109 0.0 0.0 112704 972 pts/0 R+ 12:57 0:00 grep --color=auto yum # kill -9 2038 再度、Yum実行 # yum -y install ceph ceph-radosgw さらに、以下のように停止する場合があるため、再々度、Yum実行 Trying other mirror. Error downloading packages: 2:ceph-osd-12.2.5-0.el7.x86_64: [Errno 256] No more mirrors to try. # yum -y install ceph-osd
最初に抜粋した箇所で止まった場合、ceph02やceph03は、まだceph-deploy installが行われていません。このため、一度個別にceph-deploy installを実行し、エラーは吐かせた後で、ceph01と同様の対処を行います。この作業はceph02とceph03で並行して行っても構いません。
ceph02
# ceph-deploy install --release mimic ceph02.md.jp # ps -aux | grep yum # kill -9 {PID} # yum -y install ceph ceph-radosgw
ceph03
# ceph-deploy install --release mimic ceph03.md.jp # ps -aux | grep yum # kill -9 {PID} # yum -y install ceph ceph-radosgw
ceph01
# ceph-deploy install --release mimic ceph01.md.jp ceph02.md.jp ceph03.md.jp ~略~ [ceph01.md.jp][DEBUG ] Complete! [ceph01.md.jp][INFO ] Running command: ceph --version [ceph01.md.jp][DEBUG ] ceph version 13.2.0 (79a10589f1f80dfe21e8f9794365ed98143071c4) mimic (stable) ~略~ [ceph02.md.jp][DEBUG ] Complete! [ceph02.md.jp][INFO ] Running command: ceph --version [ceph02.md.jp][DEBUG ] ceph version 13.2.0 (79a10589f1f80dfe21e8f9794365ed98143071c4) mimic (stable) ~略~ [ceph03.md.jp][DEBUG ] Complete! [ceph03.md.jp][INFO ] Running command: ceph --version [ceph03.md.jp][DEBUG ] ceph version 13.2.0 (79a10589f1f80dfe21e8f9794365ed98143071c4) mimic (stable)
最後にceph01にて再度同じコマンドを実行します。
正常に完了すると、上記の通り各ノードごとにComplete!のメッセージが表示されます。
以上です。
6.最後に
以下のサイトを参考にさせて頂きました。
Ceph(luminous)のインストール方法
删除pool error的解决方法 - sisimi_2017 - 博客园
Protecting your Ceph pools against removal or property changes – Widodh
今回はCephをブロックデバイスとして使う場合の構築方法でしたが、これ以外にもオブジェクトストレージやファイルシステムとして使う場合の構築方法もあるため、一つのストレージシステムで全てをまかなえるのが良いなと思っています。
というのもありますが、一番の理由としてCephはspdkのTargetとして使えるためです。
CentOS7 + SPDKでiSCSI target構築
CentOS7上でSPDKをビルドして、iSCSI targetを構築しました。
なお、CentOS7はDL360上で稼働させた場合と、Windows版VMWareWorkstation12上で稼働させた場合の両方で構築することができました。
1.環境
1-1.DL360
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 CPU : Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz OS : CentOS7.5(1804) Kernel : 3.10.0-862.el7.x86_64 Installed Environment Groups : Minimal Install SPDK : v18.07-pre DPDK : v18.02.0
1-2.VMWare
筐体 : 自作PC CPU : Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz VMWare : VMware(R) Workstation 12 Pro 12.5.9 build-7535481 OS : CentOS7.5(1804) Kernel : 3.10.0-862.el7.x86_64 Installed Environment Groups : Minimal Install SPDK : v18.07-pre DPDK : v18.02.0
WinおよびVMWare環境は以下の画像で確認してもらった方が良いかもしれません。
Win環境
VMWare環境
HugePageを使うためメモリは多めで。
SPDKはDPDKのPMDを使うためCPUのコア数も多めで。
さらに、
Intel VT-x/EPT またはAMD-V-RVIを仮想化
CPUパフォーマンスカウンタを仮想化
にもチェックを入れました。
50GBのOS用とは別に200GBのiSCSI Target用のHDDを追加しています。
1-3.全体の流れ
事前準備
SPDKのビルド
SPDKのiscsi.conf設定
2.事前準備
2-1.セキュリティ設定の無効化
firewalldとSELinuxを無効化します。
systemctl disable firewalld vi /etc/selinux/config で開いて SELINUX=disabled にして保存。
3.SPDKのビルド
spdkはdpdkと違い至れり尽くせりでpkgdep.shを実行することにより、spdkのビルドに必要なパッケージなどを自動でインストールし依存関係を解消してくれます。
3-1.gitインストールからspdkのビルドまで
少々乱暴ですが、以下を流し込んでしまって問題ありません。
yum -y install git && \ cd /usr/src && \ git clone https://github.com/spdk/spdk && \ cd spdk && \ git submodule update --init && \ scripts/pkgdep.sh && \ ./configure && \ make
gitインストール
/usr/srcにcd
spdkのソースをgitから取得
/usr/src/spdkにcd*2
アップデート
必要なパッケージのインストール
makeファイル生成
ビルド
ちなみに、make前に
./configure --help
とすると、追加オプションを表示できます。
例えば、
./configure --with-rdma
とすることで、RDMAにも対応してくれるようです。
3-2.unittest.shの実行
ビルドが完了したら、最後に各モジュールのテストを実施してみてください。
./test/unit/unittest.sh 出力結果省略 ===================== All unit tests passed ===================== WARN: lcov not installed or SPDK built without coverage! WARN: neither valgrind nor ASAN is enabled!
多数の出力結果が表示されますが、最後に「All unit tests passed」と表示されればOKです。
Warringが2件表示されてますが、気にせず先に進んでください。
4.spdkのiscsi.confファイル設定
4-1.設定ファイルの作成
# cd /usr/src/spdk/app/iscsi_tgt # vi iscsi.conf [global] ReactorMask 0x1 LogFacility "local7" [iSCSI] NodeBase "iqn.2016-06.io.spdk" AuthFile /usr/local/etc/spdk/auth.conf MinConnectionsPerCore 1 MinConnectionIdleInterval 5000 Timeout 30 DiscoveryAuthMethod Auto DefaultTime2Wait 2 DefaultTime2Retain 60 ImmediateData Yes ErrorRecoveryLevel 0 [Rpc] #AIO(Asynchronous I/O)が生成されなかったためRPCを有効化しています。 Enable Yes Listen 127.0.0.1 [AIO] AIO /dev/sdb AIO0 512 #追加した200GBのHDDを指定しています。 [PortalGroup1] Portal DA1 192.168.11.208:3260 #自身のIPアドレス or 0.0.0.0:3260でも大丈夫です。 [InitiatorGroup1] InitiatorName ANY Netmask 192.168.11.0/24 #アクセス許可するNWアドレスを指定します。 [TargetNode1] TargetName disk1 TargetAlias "Data Disk1" Mapping PortalGroup1 InitiatorGroup1 AuthMethod Auto AuthGroup AuthGroup1 UseDigest Auto LUN0 AIO0 #AIO0をLUN0としてTargetNodeを起動します。 QueueDepth 128
4-2.Targetプログラムの実行
ファイルの保存が完了したら、先ほどcdした /usr/src/spdk/app/iscsi_tgt のパス上で以下を実行。
./iscsi_tgt -c iscsi.conf 以下、出力結果。 # ./iscsi_tgt -c iscsi.conf Starting SPDK v18.07-pre / DPDK 18.02.0 initialization... [ DPDK EAL parameters: iscsi -c 0x1 --file-prefix=spdk_pid22562 ] EAL: Detected 4 lcore(s) EAL: Multi-process socket /var/run/.spdk_pid22562_unix EAL: Probing VFIO support... app.c: 521:spdk_app_start: *NOTICE*: Total cores available: 1 reactor.c: 669:spdk_reactors_init: *NOTICE*: Occupied cpu socket mask is 0x1 reactor.c: 453:_spdk_reactor_run: *NOTICE*: Reactor started on core 0 on socket 0
iscsi_tgtのデフォルト動作ではフォアグラウンドで稼働してしまうため、上記出力でプロンプトが停止したように見えますが、iSCSI targetは正常に起動できています。
ちなみに、上記はVMWareの場合で、DL360の場合は EAL: NUMA socket 0~ といった表示が複数行出力されますが、iSCSI targetは正常に起動できています。*3
バックグラウンドで動作させたい場合には、-bを付けてください。
./iscsi_tgt -b -c iscsi.conf
4-3.Initiatorからのアクセス
Initiatorのインストール
yum -y install iscsi-initiator-utils
Discovery実施
# iscsiadm -m discovery -t sendtargets -p 192.168.11.208 192.168.11.208:3260,1 iqn.2016-06.io.spdk:disk1
Discovery時のTarget側出力*4
conn.c: 324:spdk_iscsi_conn_construct: *NOTICE*: Launching connection on acceptor thread iscsi.c:2090:spdk_iscsi_op_login_notify_session_info: *NOTICE*: Login(discovery) from iqn.1994-05.com.redhat:a2f790913987 (192.168.11.209) on (192.168.11.208:3260,1), ISID=23d000000, TSIH=1, CID=0, HeaderDigest=off, DataDigest=off conn.c: 741:spdk_iscsi_conn_read_data: *ERROR*: spdk_sock_recv() failed, errno 104: Connection reset by peer conn.c: 456:spdk_iscsi_remove_conn: *NOTICE*: Terminating connections(tsih 1): 0
ログイン実施
# iscsiadm -m node --login Logging in to [iface: default, target: iqn.2016-06.io.spdk:disk1, portal: 192.168.11.208,3260] (multiple) Login to [iface: default, target: iqn.2016-06.io.spdk:disk1, portal: 192.168.11.208,3260] successful.
ログイン時のTarget側出力
conn.c: 324:spdk_iscsi_conn_construct: *NOTICE*: Launching connection on acceptor thread iscsi.c:2078:spdk_iscsi_op_login_notify_session_info: *NOTICE*: Login from iqn.1994-05.com.redhat:a2f790913987 (192.168.11.209) on iqn.2016-06.io.spdk:disk1 tgt_node1 (192.168.11.208:3260,1), ISID=23d000003, TSIH=2, CID=0, HeaderDigest=off, DataDigest=off
Session確認
# iscsiadm -m session tcp: [1] 192.168.11.208:3260,1 iqn.2016-06.io.spdk:disk1 (non-flash)
bdevとして認識されていることを確認
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 50G 0 disk
tqsda1 8:1 0 1G 0 part /boot
mqsda2 8:2 0 49G 0 part
tqcentos-root 253:0 0 47G 0 lvm /
mqcentos-swap 253:1 0 2G 0 lvm [SWAP]
sdb 8:16 0 200G 0 disk
sr0 11:0 1 1024M 0 rom
ログアウト
# iscsiadm -m node --logout Logging out of session [sid: 1, target: iqn.2016-06.io.spdk:disk1, portal: 192.168.11.208,3260] Logout of [sid: 1, target: iqn.2016-06.io.spdk:disk1, portal: 192.168.11.208,3260] successful.
ログアウト時のTarget側出力
iscsi.c:2601:spdk_iscsi_op_logout: *NOTICE*: Logout from iqn.1994-05.com.redhat:a2f790913987 (192.168.11.209) on iqn.2016-06.io.spdk:disk1 tgt_node1 (192.168.11.208:3260,1), ISID=23d000003, TSIH=2, CID=0, HeaderDigest=off, DataDigest=off conn.c: 456:spdk_iscsi_remove_conn: *NOTICE*: Terminating connections(tsih 2): 0
あとは、通常のiSCSI Targetと同様に動作しますので、Initiator側でmkfsするなり、fioで速度測定するなりご自由にどうぞ。
以上です。
5.最後に
以下のサイトを参考にさせて頂きました。
SPDK: Getting Started
https://www.starwindsoftware.com/blog/intel-spdk-nvme-of-target-performance-tuning-part-2-preparing-testing-environment
CentOS7下编译安装SPDK iSCSI Target - 程序园
SPDKに関する日本語サイトが皆無に等しいのは覚悟の上だったのですが、英語サイトでも出力結果などの詳細解説を記載したサイトが無かったため、ちょっとしんどかったです。3番目の中国サイトがとても助かりました。ありがとうございます。
DPDKに引き続き、取り急ぎSPDKを動作させるところまでは何とかできました。これをベースにNVMe-oFなどにも挑戦したいなと思っています。RoCEv2などにも興味があるのですが、こちらは現在情報収集中です。私は元々ネットワークエンジニアなので、近い将来、主記憶装置も補助記憶装置もすべてがネットワーク上で抽象化orプール化されていくことをイメージしながら、その(大容量)トラフィックをどのように捌いて制御しようか?なんてことを考えつつ、最適なネットワーク設計を模索し続けています。
*1:この後にmakeした際、以下のエラーでコンパイルが停止するため追記しました。/usr/src/spdk/lib/iscsi/md5.h:40:25: fatal error: openssl/md5.h: No such file or directory
*2:このパスがspdkの基点になります。今回紹介した内容以外にも開発用の色々なツールが含まれていますので、興味があればディレクトリを漁ってみるのもいいかもしれません。
*3:このとき、Minimal Installだと、netstatが叩けなかったため、ss -naptで確認したところ、TCP3260のポートが開いていないように見える事象を確認しました。しかし、正常起動している可能性が高いので、試しにinitiator側からDiscoveryしてみてください。私はこの事象で1週間悩み続けました、幻を見ていたのかもしれませんが。。。
*4:エラーが出ていますが気にせず先に進めてください
CentOS7 + pktgen with DPDKでパケットジェネレータ作成
CentOS7上に3台の仮想マシン(CentOS)を稼働させつつDPDKとpktgenをインストールして10Gワイヤーレートが出るパケットジェネレータを作成しました。
1.環境
1-1.母体(ホストOS)
筐体 : ProLiant DL360p Gen8 System ROM : P71 01/22/2018 CPU : Intel(R) Xeon(R) CPU E5-2660 0 @ 2.20GHz NIC : Intel X520-SR2(82599ES) OS : CentOS7.4(1708) Kernel : kernel-3.10.0-693.el7.x86_64 Installed Environment Groups : Server with GUI Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools
1-2.仮想マシン(ゲストOS)
筐体 : 下記参照 System ROM : 下記参照 CPU : 下記参照 NIC : Intel X520-SR2(82599ES) OS : CentOS7.4(1708) Kernel : kernel-3.10.0-693.el7.x86_64 Installed Environment Groups : Server with GUI Add-Ons for Selected Environment : Virtualization Client, Virtualization Hypervisor, Virtualization Tools , Development Tools
筐体、System ROMはホストOSにインストールされているqemu-kvmをそのまま使用。
yum updateやupgradeは未実施。
CPUはNestedKVMを有効化しているため、ホストOSと同一 。
ゲストOSはDPDKやpktgenのビルドが必須なため、Development Toolsを加えています。
1-3.全体の流れ
ホストOSでNestedKVM, SR-IOV, VFIOの設定
ゲストOSでHugePage & IOMMU, VFIOの設定
ゲストOSでDPDKのインストール, igb_uioの設定
ゲストOSでpktgenのインストール
ゲストOS×3台使った負荷試験
2.ホストOSの設定
2-1.NestedKVMの設定
ゲストOS3台の名前はc741, c742, c743とします。
ファイルを新規作成 vi /etc/modprobe.d/kvm-nested.conf 以下を追記して保存。 options kvm_intel nested=1 再読み込み modprobe -r kvm_intel modprobe kvm_intel ゲストOS作成後、以下のようにvirshにて設定 virsh edit c741 <cpu mode='custom' match='exact'> の行を <cpu mode='host-passthrough'> に変更して保存。
2-2.SR-IOVの設定*1
grubにiommuの設定追加
vi /etc/default/grub GRUB_CMDLINE_LINUX=の行末に追加 intel_iommu=on iommu=pt pci=realloc 保存後、grubに反映 grub2-mkconfig -o /etc/grub2.cfg
起動時にVFが作成されるようrc.localの設定
vi /etc/rc.local 最下行に追加 echo 4 > /sys/class/net/ens1f0/device/sriov_numvfs echo 4 > /sys/class/net/ens1f1/device/sriov_numvfs sleep 1 ip link set ens1f0 vf 0 mac 00:11:22:33:44:50 ip link set ens1f0 vf 1 mac 00:11:22:33:44:51 ip link set ens1f0 vf 2 mac 00:11:22:33:44:52 ip link set ens1f0 vf 3 mac 00:11:22:33:44:53 ip link set ens1f1 vf 0 mac 00:11:22:33:44:60 ip link set ens1f1 vf 1 mac 00:11:22:33:44:61 ip link set ens1f1 vf 2 mac 00:11:22:33:44:62 ip link set ens1f1 vf 3 mac 00:11:22:33:44:63 sleep 1 ip link set ens1f0 vf 0 spoofchk off ip link set ens1f0 vf 1 spoofchk off ip link set ens1f0 vf 2 spoofchk off ip link set ens1f0 vf 3 spoofchk off ip link set ens1f1 vf 0 spoofchk off ip link set ens1f1 vf 1 spoofchk off ip link set ens1f1 vf 2 spoofchk off ip link set ens1f1 vf 3 spoofchk off exit 0 保存後、実行権限を付与 chmod +x /etc/rc.d/rc.local
VFがホストOSに読み込まれないよう設定
vi /lib/modprobe.d/dist-blacklist.conf 最下行に追加 # ixgbevf driver blacklist ixgbevf
2-3.VFIOの設定*2
ファイルを新規作成 vi /etc/modprobe.d/vfio_pci.conf 以下を追記して保存 options vfio_pci ids=8086:10ed こちらも追記 echo 'vfio_pci' > /etc/modules-load.d/vfio_pci.conf 一旦再起動 reboot
8086:10edはlspciで表示されるVFのBus,Slot,Function番号(筐体ごとに異なる)から、lspci -n -s 0008:10.2のようにコマンドを入力することでPCIデバイスのベンダID(8086)とデバイスID(10ed)を確認し、ベンダID(8086)とデバイスID(10ed)をVFIO-PCI driverに登録します。
3.ゲストOSの設定
ゲストOSの設定の前にVirt-Managerなどで仮想マシンを作成してください。
その際、CPUは4コア、Memは8GB以上が理想です。また、管理用IP以外にPCI Host Deviceとして、VFを2つ追加してください。
VF追加は、こんな感じのイメージです。*3
3-1.HugePageとIOMMUの設定
vi /etc/default/grub GRUB_CMDLINE_LINUX=行の最後に以下を追記。 default_hugepagesz=1G hugepagesz=1G hugepages=8 intel_iommu=on iommu=pt grub2-mkconfig -o /boot/grub2/grub.cfg
4.DPDKのインストール
4-1.ソースのDLとビルド
ソースをDLします。 cd /usr/src wget http://fast.dpdk.org/rel/dpdk-17.11.1.tar.gz tar zxvf dpdk-17.11.1.tar.gz cd dpdk-stable-17.11.1 展開したディレクトリでビルドを実施 make install T=x86_64-native-linuxapp-gcc DESTDIR=/usr/local EXTRA_CFLAGS="-O3"
5.pktgenのインストール
5-1.ソースのDLとビルド
ソースをDLします。 cd /usr/src wget http://www.dpdk.org/browse/apps/pktgen-dpdk/snapshot/pktgen-3.5.0.tar.gz tar zxvf pktgen-3.5.0.tar.gz 一旦パスを通す export RTE_SDK=/usr/src/dpdk-stable-17.11.1 export RTE_TARGET=x86_64-native-linuxapp-gcc 展開したディレクトリでビルドを実施 cd pktgen-3.5.0 make
6.負荷試験
6-1.DPDKにバインド
SR-IOVでパススルーされたVFをゲストOSのKernelからDPDK管理下におくためにバインドします。
dpdk-devbind --status Network devices using DPDK-compatible driver ============================================Network devices using kernel driver =================================== 0000:00:07.0 '82599 Ethernet Controller Virtual Function' if=ins2f0 drv=ixgbevf unused=igb_uio,vfio-pci 0000:00:08.0 '82599 Ethernet Controller Virtual Function' if=ins2f1 drv=ixgbevf unused=igb_uio,vfio-pci ~略~ dpdk-devbind -b igb_uio 0000:00:07.0 0000:00:08.0 dpdk-devbind --status
上記バインドを実施することにより、ゲストOS上のカーネルドライバで動作していたVFがDPDKドライバで動作するようになります。バインド後、ゲストOS上でip link showなどを実施しても、ゲストOS上からVFが認識されなくなります(DPDK管理下におかれます)。
6-2.pktgenの起動
ビルドしたディレクトリに移動*4 cd /usr/src/pktgen-3.5.0 移動後のディレクトリ上で、pktgenの起動 app/x86_64-native-linuxapp-gcc/pktgen -- -m "1.0,2.1"
6-3.pktgenで負荷試験実行
pktgenが起動すると以下のような画面となります。
プロンプトが Pktgen:/>となるので、 start all と入力
これを3台のゲストOSで同時に実施し、
行 Pkts /s Max/Tx
列 TotalRate
のフィールドが5Mppsくらいになると、
ワイヤーレート(14.8Mpps)が出てそうな雰囲気になります。
実際にやるとこんな感じです。
1台あたり5Mpps超えてるのがかなり怪しいですが・・・
ホストOS単体では思うようにワイヤーレートが出なかったので、この辺りはもう少しチューニングが必要だと考えています。
以上です。
7.最後に
以下のサイトを参考にさせて頂きました。
みらくるブログ — サイバートラスト株式会社
Getting Started with Pktgen — Pktgen 3.2.4 documentation
私自身もまだまだ勉強不足なため、不要な設定が入っている気がしています。具体的にはホストOSでSR-IOVしているため、ホストOS上のVFIO設定は不要なのでは?といったところです。ホストとゲスト、ユーザ空間とカーネル空間のどこで必要とされている設定なのか?など、一度整理してみないとダメだなと考えています。
*1:詳細は過去記事を参照してください。CentOS7でSR-IOV設定 - Metonymical Deflection
*2:詳細は過去記事を参照してください。CentOS7でvThunderのセットアップ - Metonymical Deflection
*3:画像はX540のものですが、X520でも同様です。
*4:cdした/usr/src/pktgen-3.5.0のディレクトリ上からでないとpktgenが起動しませんでした。make時のパスの通し方がダメな気がしています。要調査