アップロードファイル用のストレージの追加 (Pro)

アップロードされたファイルはホスト上のmediaディレクトリに保存され、Docker Composeデプロイメントでは、それらに利用できる容量はVMのディスクの残り容量に依存します。SBOMのような大きなアップロードは、そのディスクを満杯にしてしまうことがあります。このページでは、デプロイ自体を変更することなく容量を拡張する方法について説明します。

OSレベルで対応できる理由

Docker Composeデプロイメントは、ホストのmediaディレクトリを、それを必要とするコンテナ(アプリケーションコンテナと、アップロードされたファイルをユーザーに返すnginxの両方)にバインドマウントします。コンテナはホスト上のパスに対して読み書きを行うため、そのパスにマウントされているファイルシステムが実際に使用されるものになります。そこにより大きな容量をマウントしても、アプリケーションからは透過的です。

そのため、ここで紹介するアプローチはデプロイメントの変更ではなく、オペレーティングシステムの変更となります。リリースに同梱されているComposeファイルを変更しないままにしておくことで、インストールを他のオンプレミスデプロイメントと一貫性のある状態に保つことができ、アップグレードでそのファイルが置き換えられた際に変更が失われることも回避できます。

ブロックストレージ:シンプルな選択肢

追加のブロックデバイスをマウントすることは、Linuxでディスクの満杯に対処する一般的な方法であり、まず最初に検討すべき選択肢です。NASやSANのボリュームでも機能しますし、Amazon EBSボリュームのようなクラウドプロバイダーのブロックストレージでも機能します。

アプリケーションのストレージをオペレーティングシステムのディスクから分離することは、一般的には良い実践です。したがって、妥当な選択肢は2つあります。デバイスをmediaディレクトリにマウントして、アップロードファイル専用の容量を確保する方法と、1階層上のデプロイメントディレクトリにマウントして、すべてのアプリケーションデータをVMとは別のファイルシステム上に配置する方法です。

オブジェクトストレージ(注意点あり)

Amazon S3のようなオブジェクトストレージでアップロードを支えることは可能であり、容量の上限を完全に取り払うことができますが、ブロックデバイスほど自然な適合ではありません。選択する前に、以下の点を検討してください。

オブジェクトストレージはファイルシステムではありません。S3はランダムな書き込み、既存ファイルへの追記、ファイルロックをサポートしていません。FUSEレイヤーがそのギャップを覆い隠しますが、それは基盤となるストアが本来持っていないセマンティクスをエミュレートしているに過ぎません。

レイテンシはブロックデバイスよりも高くなります。これはアップロードに影響しますし、nginxが同じディレクトリからアップロードされたファイルを配信するため、ダウンロードにも影響します。

ネットワーク依存関係が追加されます。VMがネットワーク内のどこに位置するかによっては、バケットに到達するために追加のネットワーク経路が必要になる場合があり、アップロードを機能させるにはそのパスが利用可能である必要があります。

再起動には注意が必要です。バケットは起動時にマウントする必要があり、これによりマウントの完了とDefectDojoの起動との間にタイミングの依存関係が生じます。レイテンシによっては、再起動がハングしたり、マウントがまだ準備できていない状態で起動してしまったりする可能性があります。

権限を一致させる必要があります。バケットのIAM権限は、アプリケーションがアップロードを書き込むために必要とするファイルシステムの権限と整合させる必要があります。

オブジェクトストレージをマウントするためのツール

Linux上でS3をファイルシステムとしてマウントするために、一般的に3つのツールが使用されます。

rclone mountは安定していて活発にメンテナンスされており、読み書きのバッファリングをうまく処理する仮想ファイルシステムのキャッシュモードを提供します。この3つの中で、この方法を選ぶのであれば私たちが推奨するのはこれです。

goofysは速度に最適化されています。ファイルの作成や書き込みを非同期に行い、ランダムな書き込みやファイルロックなど、S3がネイティブにサポートしていない操作を無視することでそれを実現しています。

s3fs-fuseは3つの中で最もPOSIX互換性が高く、所有権やパーミッションの変更といった操作もサポートしていますが、実際のファイルシステムを模倣しているため、goofysに比べてかなり低速です。

mediaディレクトリを新しいファイルシステムに移動する

コピー中はアプリケーションがアップロードファイルへの書き込みを行ってはならないため、この作業にはダウンタイムが必要です。

  1. dojo-compose-cli app stopでDefectDojoを停止し、移動中に何も変更されないようにします。
  2. 既存のmediaディレクトリの名前を変更して、ロールバックポイントとして残しておきます。たとえば、デプロイメントディレクトリ内でmediaold-mediaに変更します。
  3. 元のmediaパスに、マウントポイントとして機能する空のディレクトリを作成します。
  4. 新しいファイルシステムをアタッチします。具体的な手順は上記でどれを選んだかによって異なりますが、要点は3つです。ストレージをLinuxから利用可能にすること(オブジェクトストレージの場合はバケットとその権限を作成すること)、mediaパスにマウントすること、そして通常は/etc/fstabのエントリ、あるいは使用するツールに応じた同等の設定によって、再起動後もマウントが維持されるようにすることです。
  5. 所有権とパーミッションを保持したまま、既存のコンテンツをコピーします。古いディレクトリから新しいディレクトリに対してrsync -Pavを実行すると、これを行いつつ進捗状況を報告してくれるため、移動するデータ量が多い場合に便利です。
  6. ファイルが正しく届いたことを確認します。オブジェクトストレージの場合、プロバイダーのコンソールでバケットを確認するのが、マウントが本当に想定した場所に書き込まれているかを確かめる最も速い方法です。
  7. dojo-compose-cli app startでDefectDojoを起動し、テストファイルをアップロードします。アップロードが失敗した場合は、コンテナのログにその理由が記録されており、たいていの原因は権限にあります。

テストアップロードが成功し、そこから移行したファイルがUI上で読み取れることを確認できるまでは、古いディレクトリを残しておいてください。新しいファイルシステムが期待どおりに動作しなかった場合に戻る手段となります。

サポート範囲

これらは一般的な推奨事項です。VMへのストレージ追加はオペレーティングシステムのタスクであり、選択した方法(特にFUSEでマウントするオブジェクトストアの場合)の詳細は、オンプレミスサポートの対象外です。このアプローチは、他のすべてのオンプレミスインストールとデプロイメントの一貫性を保ち、私たちが提供するComposeファイルを変更せず、容量の問題を本来あるべきOSレイヤーで解決するように意図的に構成されています。

ご自身の環境に合わせて選択肢を検討している場合は、までご連絡ください。決定する前に、トレードオフについて一緒に相談させていただきます。