EBS Multi-Attachの使いどころを考えてみた

2020.02.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

しばたです。

先日EBS(プロビジョンドIOPS io1ボリューム)の複数インスタンスによるアタッチ(Multi-Attach)がサポートされましたが、本記事ではその使いどころについて考えてみました。

[アップデート]Amazon EBSの複数インスタンスへのアタッチが可能になりました!(プロビジョンドIOPS io1ボリュームに限る)

AWS公式の案内はこちら。

はじめに

はじめに言い訳で申し訳ないのですが、この記事では明確な答えを出せていません。
EBS Multi-Attachの使いどころについては現在進行形で悩み続けています。

本記事の内容に関してコメントなどでフィードバックを頂けると非常に嬉しいです。

EBS Multi-Attachの制限事項

使いどころについて触れるまえに、まずは現在のEBS Multi-Attachの制限事項から「何に使えないのか」を考えることにします。
先述の記事から引用すると現時点では以下の制限があります。

  • I/Oフェンシングプロトコルに対応していないため、アプリケーション側で同時書き込みの排他制御を担保する必要がある
  • ボリュームタイプはプロビジョンドIOPS(io1)である必要がある
  • マルチアタッチするEC2インスタンスはEBSボリュームと同一アベイラビリティゾーンである必要がある
  • マルチアタッチするEC2インスタンスはNitroベースのインスタンスである必要がある
  • マルチアタッチできるのは最大16台まで
  • 現状マルチアタッチできるのはus-east-1、us-east-2、us-west-2、eu-west-1、ap-northeast-2である
  • マルチアタッチ対応ボリュームはブートボリュームとして作成できない
  • マルチアタッチ対応ボリュームはインスタンスごとにアタッチできるのは1つのデバイスのみ
  • ボリュームの作成後にマルチアタッチの有効/無効を変更することはできない
  • マルチアタッチ対応ボリュームのボリュームタイプ、サイズ、プロビジョンドIOPSを変更することはできない
  • EBSの物理ホストに影響があった場合、マルチアタッチしているEC2インスタンスすべてで使用できない
  • EC2インスタンスにおけるEBSボリュームの「終了時に削除」の有効/無効は、最後にアタッチされたEC2インスタンスの設定が採用される

公式のドキュメントはこちら。

同一AZ制限

  • マルチアタッチするEC2インスタンスはEBSボリュームと同一アベイラビリティゾーンである必要がある

まずはこの制限から。

恐らく多くの方はEBSのMulti-Attachと聞いて下図の様にマルチAZ構成でアタッチする画を想像されたのではないかと推測しますが、残念ながらそれはできず、同一AZ内である必要があります。

これはEBSの仕組みを想像すれば割と納得のいく仕様だと思います。

排他制御

【2020.02.27追記】

AWSから公式に通常のファイルシステムではEBS Multi-Attachを使えない旨の発表がでました。
内容としてはこの記事で述べていることと大体同じですが、こちらの発表もご一読ください。

【追記ここまで】


  • I/Oフェンシングプロトコルに対応していないため、アプリケーション側で同時書き込みの排他制御を担保する必要がある

EBS Multi-AttachにおいてEBS側で排他制御の仕組みは提供されていません。

例えばAzureでプレビューリリースされている類似サービスのAzure Shared Disksでは共有ストレージ側の排他制御機構としてSCSI Persistent Reservations (PR)が用意されています。
しかしながら、ストレージ側に排他制御機構があれば何も考えず無条件にMulti-Attachできるわけではなく、あくまでも共有ストレージを扱えるソフトウェアの幅が広がるだけですので注意してください。
(たとえばSCSI Persistent Reservationsの場合であれば、共有ボリュームを扱うクラスターなどのソフトウェアが正しくプロトコルに従う必要があります)

また、ありがちな誤解として、単純にWrite/Readのノードを分けてマウントすれば手軽にMulti-Attachを利用できるのでは?と思われがちですが、この様な構成はまず使えません。

ノード間の調整なしにMulti-Attachに対応しているファイルシステムがあれば話は別ですが(そんなのあるんですかね?)、一般的なファイルシステムではあるノードのWrite完了を他のノードに伝えることができません。

たとえばWrite可能なノードが巨大なファイルをストレージにコピーしている場合を考えると、途中の状態はファイルシステム依存でありReadするノードが期待したデータはきっと得ることができないでしょう。
また、大抵のOSやファイルシステムにはWrite Cacheが存在しておりWriteするノードが書き込んだデータが直ちにストレージに書き込まれる保証がありません。

そもそも論として一般的なファイルシステムは複数ノードからのマウントを前提にしていないものばかりです。
人間が気を付けて運用して問題の無い状態を作り出すことは不可能ではないでしょうが、非常に限定的な使い方しかできないことは分かるかと思います。

加えてこの様な構成にして運用をミスすると一発でデータやファイルシステムが壊れる可能性が高いので、私個人としては、こんな恐ろしいことは絶対にすべきでないと考えています。

【2020.02.20】ちょっと追記

先述のAzure Shared Disksではクラスター向けのファイルシステムであるGlobal File System 2(GFS2)が使える様で、EBSでGFS2が利用可能かはわかりませんが(未検証です)ファイルシステムの運用を考える場合は何らかのクラスター向けファイルシステムを選択する必要があるでしょう。

私はこの様なクラスター向けファイルシステムには全くもって疎いのでググってみつけたRed Hatの資料を参考情報として紹介するに留めておきます。

ボリュームサイズ変更

  • マルチアタッチ対応ボリュームのボリュームタイプ、サイズ、プロビジョンドIOPSを変更することはできない

これは今後改善されるかもしれませんが、現時点においては一度決めたサイズを変える事ができないためデータストアの様なサイズがスケールしうる用途には使いにくいです。
データストアでも容量が固定的であれば使用に問題なさそうです。

EBS Multi-Attachの使いどころ

ここまでを踏まえて、EBS Multi-Attachの使いどころを考えてみましたが、今のところは「フェイルオーバークラスターのクオーラムディスクに使うのが現実的なのかなぁ?」という変哲もない考えに至りました。

ボリュームサイズが固定なのでフェイルオーバークラスターでもデータボリュームは使いにくそうですが、固定容量で構わないのであれば、例えばRDSでサポートされてない機能を使うためにRDBMSのクラスターを組むといった用途には使えそうではあります。
RDBMS以外にも単一AZ内で構わない範囲で可用性を高めたい機能やサービスがあれば適用可能そうであります。

EBS Multi-Attachがあればフェイルオーバークラスターが簡単に組めるのか?

昔から言われておりAWSの基本中の基本ですが、VPC内でフェイルオーバークラスターを構築するのは容易ではなく、EBS Multi-Attachができる様になったからと言ってそれが簡単になったわけではありません。

VPC で Virtual IP、Floating IP ?

VPCの基本として、VPCではブロードキャストとマルチキャストがサポートされていません。
この制約はフェイルオーバークラスターの必須要素であるVirtual IP(およびFloating IP。本記事では両者を含めてVirtual IPで呼称)を扱うのにあたり非常に大きな問題となります。

フェイルオーバークラスターではクラスターに対するアクセス先としてVirtual IPが割り当てられいずれかのノードに紐づきます。基本的にVirtual IPに紐づくMACアドレスは割り当てられたノードのNICのMACアドレスとなり、フェイルオーバー時に紐づくMACアドレスがフェイルオーバー先のノードのものに切り替わりクラスターとしての可用性を維持します。

ここでMACアドレスの切り替わりを通知するためにGratuitous ARPを使うわけですが、Gratuitous ARPはブロードキャストです。
VPC上でGratuitous ARPを送信しても期待した動作をせずフェイルオーバークラスターはその役割を果たすことはできません。(ここは環境を作れず実際に試せてないのですがダメなはず)

VPC と ARP と Mapping Service

ここで少し余談となりますが、ARPではブロードキャストを多用しますがブロードキャストがサポートされないはずのVPCでARPは普通に利用できている様に見え、IP通信も普通にできています。

このあたりの仕組みについてはCodeZineの以下の記事に詳しく記載されています。

※この他にも幾つかのAWSの資料も参考になります

詳細は上記の記事に譲りますが、VPC内でのARPブロードキャスト(ARP Request等)はブロードキャストされる前にAWSの物理ホストと"Mapping Service"によりよしなに処理されてしまう点と、VPC内のIPアドレスは"Mapping Service"の認識下にある必要がある点はVPC独自の仕様として押さえておく必要があります。

(https://www.slideshare.net/AmazonWebServices/ent303-another-day-another-billion-packets-78355688 より引用)

この様な事情がVPC上でフェイルオーバークラスターのVirtual IPを使うにあたり大問題となります。

VPC でのフェイルオーバークラスター構成例

そんなわけでVPC内でフェイルオーバークラスターを使うためには幾つかの代替策を講じる必要があり、たとえばNECのCLUSTERPROの場合であれば以下の記事で構成例が紹介されています。

[CLUSTERPRO]AWSで利用する場合の構成まとめ

この記事で紹介されている方式を順に解説すると、

  • EIP方式 : Virtual IPが使えないのでElastic IPを移動させFloatingさせる(Floating IPパターンの利用)
  • VIP方式 : VPC内でVirtual IPが使えないので、Virtual IPをVPC外のアドレスにしてしまいルートテーブルの設定で各ノードへの固定ルートを作り通信させる
  • ENI切り替え方式 : 追加のENIをVirtual IP代わりに使う

といった方法でVirtual IPをどうにかして代用しています。
この他にもENIにセカンダリのIPをアサインし、EC2インスタンス間でセカンダリIPを付け替えることでVirtual IPの代わりにする方式もある様です。

最後に

ちょっとまとまりのない話になりましたが、ざっとこんなことを考えてみました。
最初に言い訳した様に答えを出せていないので後日全然違う事をブログに書くかもしれません...

拙い内容ですが少しでもEBS Multi-Attachの利用を考えている方の役に立てば嬉しいです。