
AWS Solutions Guidance「KNFSD File Cache」のIaCテンプレートを読み解いてみた
はじめに
2026年7月20日、AWS Solutions Guidanceとして「Guidance for KNFSD File Cache on AWS」がPreviewで公開されました。
名前だけを見ると新しいマネージドサービスのようにも見えますが、実体はマネージドサービスではありません。EC2上で動作するNFSキャッシュプロキシのリファレンス実装であり、PackerによるAMIビルドとTerraformモジュールをセットで提供する、オープンソースのIaCテンプレートです。もともとはGoogle Cloud向けの knfsd-cache-utils プロジェクトをAWS向けにポーティングしたもので、ライセンスはApache-2.0です。Terraformモジュールなど一部ファイルのヘッダにはGoogleとAmazonの双方のCopyrightが記載されており、Google Cloud向けプロジェクトを基にした系譜がコード上からも読み取れます。
NFSのソースサーバーとクライアントの間にキャッシュ層を挟み、読み取りをローカルの高速ストレージで肩代わりします。クロスリージョンやハイブリッド構成で問題になりやすいNFSレイテンシに対し、ローカルキャッシュによる緩和を狙う構成です。
本記事では、このGuidanceのリポジトリ(v1.1.0-beta.1、2026-07-17リリース)を静的解析し、AMIの中身とTerraformの構成を読み解いていきます。
検証内容
検証環境
| 項目 | 内容 |
|---|---|
| 対象リポジトリ | https://github.com/awslabs/knfsd-file-cache |
| バージョン | v1.1.0-beta.1(2026-07-17リリース) |
| ステータス | Preview |
| 解析手法 | Packer定義 / Terraformモジュール / シェルスクリプト / Goソースコードの静的解析 |
AMI内部構成(主軸)
Packerテンプレートを解析すると、AMIに含まれるコンポーネントは以下のとおりです。
| カテゴリ | 内容 |
|---|---|
| OS | Ubuntu 26.04 LTS |
| カーネル | Linux 7.1.3(-knfsd suffix)カスタムビルド |
| NFS | nfs-kernel-server + nfs-utils 2.8.5(re-export対応) |
| キャッシュ | cachefilesd 0.10.10(ASLRパッチ適用)+ FS-Cache |
| FSID管理 | knfsd-fsidd(Go, externalモード時はPostgreSQL連携) |
| HTTP API | knfsd-agent(Go, ステータスAPI) |
| メトリクス | knfsd-metrics-agent(Go, OTel Collectorカスタム)+ CloudWatch Agent |
| Export検出 | filter-exports / netapp-exports(Go) |
| ネットワーク | ENA 2.17.2 / amazon-ec2-net-utils 2.7.3 |
| 管理 | SSM Agent / AWS CLI |
カスタムカーネル(Linux 7.1.3)
このテンプレートの特徴的な点は、Ubuntu標準のHWEカーネルを使わず、mainlineのLinux 7.1.3を独自にビルドしていることです。NFS・FS-Cache・NVMe・RAID まわりの機能を有効化する一方で、GPU・WiFi・Bluetooth・サウンドといったサーバー用途では不要なドライバを削除しています。ENAドライバも別途モジュールとしてバージョン2.17.2をビルドし、CONFIG_LOCALVERSION="-knfsd" でカーネルを識別できるようにしています。
.config から、キャッシュプロキシとして必要な機能が有効化されている様子が読み取れます。
CONFIG_FSCACHE=y # FS-Cacheコア
CONFIG_CACHEFILES=m # cachefilesモジュール
CONFIG_NFS_FSCACHE=y # NFSとFS-Cacheの統合
CONFIG_NFSD=y
CONFIG_NFSD_V4=y
CONFIG_XFS_FS=y
CONFIG_BLK_DEV_MD=y # RAID
CONFIG_BLK_DEV_NVME=y # NVMe
CONFIG_LOCALVERSION="-knfsd"
FS-Cacheをカーネル組込み、cachefilesをモジュール、NFS/XFS/RAID/NVMeを有効化しています。ENAドライバはカーネル本体とは別にバージョン2.17.2を個別にモジュールビルドしています。
ビルドにはカーネルコンパイルの高速化のために64 vCPUインスタンス(c6i.16xlarge等)が使用されます。この点については後述の「デプロイの敷居」で触れます。
NFS re-exportアーキテクチャ
キャッシュプロキシの中核は、ソースNFSをマウントしクライアントに再公開するNFS re-exportです。
NFSクライアント → knfsd-proxy(NFS re-export)→ ソースNFSサーバー
↓
FS-Cache / cachefilesd
↓
ローカルNVMe または EBS(XFS、複数デバイス時はRAID0)
re-exportで問題になりやすいのがFSIDの一貫性です。このテンプレートではnfs-utils 2.8.5の reexport=auto-fsidnum 機能を利用しています。/etc/nfs.conf でknfsd-fsiddとの連携や各種ポートを固定的に定義し、Security Groupで許可ポートを絞り込む設計です。
エクスポートの検出方式は3通り用意されており、併用も可能です。静的にマッピングを定義する export_map、showmount -e で自動検出してフィルタリングする方式、そしてNetAppのREST API経由で検出する方式です。
FS-Cache(cachefilesd)
キャッシュの実体は、LinuxのFS-Cacheサブシステムと、そのユーザー空間デーモンであるcachefilesdが担います。キャッシュのバックエンドには、NVMeインスタンスストレージ(またはEBS)上に作成したXFSを使います。XFSは mkfs.xfs -f -L fscache -m reflink=0 でフォーマットされ、reflink(CoW)を無効化しています。複数デバイスがある場合は mdadm でRAID0を構成します。
cachefilesd.confでは、空き容量に応じたキャッシュの削除しきい値が定義されています。
dir /var/cache/fscache
tag mycache
brun 20% # 空きが20%を上回ると削除(カリング)を停止
bcull 7% # 空きが7%を下回ると削除を開始
bstop 3% # 空きが3%を下回るとキャッシュ書込みを停止
cachefilesd自体にもパッチが当てられています。ASLR環境でポインタポイズニング処理が abort() を起こす問題への修正で、オリジナルのコードが0x60000000〜0x6fffffffのアドレス範囲を前提としていたものです。
NFSマウント時に fsc オプションを付与することで、マウントとFS-Cacheが紐づきます。
Go製カスタムデーモン群
AMIにはGo言語で実装されたカスタムコンポーネントが5つ含まれています。このうち knfsd-fsidd、knfsd-agent、knfsd-metrics-agent は常駐サービスとして動作し、filter-exports と netapp-exports はエクスポート検出・変換に用いる実行ファイルです。
| バイナリ | 責務 |
|---|---|
knfsd-fsidd |
FSID管理。externalモード時はPostgreSQL連携でクラスタ間FSID共有 |
knfsd-agent |
HTTP :80 でステータスAPI提供(マウント状態、キャッシュ使用量) |
knfsd-metrics-agent |
OpenTelemetry Collectorカスタムビルド |
filter-exports |
NFSエクスポートのフィルタリング |
netapp-exports |
NetApp REST API経由のエクスポート自動検出 |
knfsd-metrics-agent は7種類の独自レシーバーを持つOTel Collectorカスタムビルドで、/proc/fs/fscache/stats やNFSのマウント統計、slab情報などをスクレイピングします。
| レシーバー | 収集内容 |
|---|---|
| connections | NFSクライアント接続数 |
| mounts | マウント毎のread/write bytes、RPC統計 |
| nfsd | NFSサーバースレッド、パケット統計 |
| fscache | FS-Cache / Netfslib統計 |
| exports | エクスポート毎の操作数/バイト数 |
| slabinfo | dentry_cache / nfs_inode_cacheのslab統計 |
| oldestfile | キャッシュ内最古ファイルの経過時間(診断用、デフォルト無効) |
エクスポート先はCloudWatch Embedded Metric FormatやPrometheusなど複数に対応しています。knfsd-metrics-agent には GOMEMLIMIT=409MiB が設定されています。これはOSレベルの強制上限ではなく、GoランタイムがGC頻度を調整するためのソフトなメモリ上限です。
カーネル/ネットワークチューニング
起動スクリプトにより、NFSワークロード向けのカーネルパラメータとネットワーク設定が適用されます。
# SUNRPC スロットテーブル(RPC並列度)
sunrpc.tcp_slot_table_entries=128
sunrpc.tcp_max_slot_table_entries=128
# メモリ管理
vm.compaction_proactiveness=0 # kcompactdによるNFSフォリオブロック防止
vm.dirty_ratio=40 # FS-Cache書込みバースト対応
vm.dirty_background_ratio=20
vm.vfs_cache_pressure=1 # dentry/inodeキャッシュ保護
vm.swappiness=5 # メモリ常駐優先
vm.min_free_kbytes=<RAMに応じて動的設定> # おおむね1-4GBの範囲でクランプ
# ENA向けネットワーク設定
MTU=8900 # ジャンボフレーム
ethtool -G $iface rx 8192 # Rxリングバッファ拡大
ethtool -C $iface adaptive-rx on # アダプティブ割込み
# RPS全コア分散
echo $rps_mask > /sys/class/net/$iface/queues/rx-*/rps_cpus
vm.compaction_proactiveness=0 はNFSキャッシュプロキシ特有のチューニングです。kcompactdがメモリコンパクションを行う際に、NFSフォリオの PG_fscache フラグ待ちでブロックされることを防いでいます。
Terraformデプロイメント構成(副軸)
Terraformモジュールが作成するリソースは、大きくコアリソースと条件付きリソースに分かれます。
SSM Parameter Storeによる設定注入
このモジュールの設計で目を引くのは、EC2のuser-dataに通常の動作パラメータを直接列挙していない点です。プロキシの動作を決める約35個の設定値はすべてSSM Parameter Storeに格納され、起動スクリプトが /knfsd/${CLUSTER_NAME} 配下から動的に読み込みます。AMIをステートレスに保ち、同じAMIを設定の異なる複数のクラスタで再利用する設計です。
サブネット・AMI ID・エクスポート定義など必要最小限の変数を渡す構成例です。
module "knfsd" {
source = "github.com/awslabs/knfsd-file-cache/deployment/terraform-module-knfsd?ref=v1.1.0-beta.1"
SUBNET = "<subnet-id>"
PROXY_AMI = "<packer-build-ami-id>"
TRAFFIC_MODE = "dns_round_robin"
INSTANCE_TYPE = "i3en.6xlarge"
EXPORT_MAP = "<source-ip>;/remoteexport;/remoteexport"
KNFSD_NODES = 1
}
コアリソース
| リソース | 役割 |
|---|---|
| Launch Template | NFSプロキシのインスタンステンプレート |
| Auto Scaling Group | ノード群のライフサイクル管理 |
| Security Group | NFS固定ポート(111, 2049, 20048, 20050, 20051, 20053, 20055) |
| IAM Role + Policies | SSM, CloudWatch, EC2タグ, ASG情報取得 |
| SSM Parameters(約35個) | 全設定値をSecureStringで格納 |
条件付きリソース
| 条件 | リソース |
|---|---|
| dns_round_robin | Lambda + EventBridge + Route 53(ENI持続化) |
| loadbalancer | NLB + Target Groups + Listeners |
| external FSID | RDS PostgreSQL + Lambda(db_setup) |
| autoscaling | Scaling Policy + CloudWatch Alarm |
3種のTraffic Mode
NFSクライアントからプロキシへのトラフィック分散は3つのモードから選択できます。
dns_round_robin(デフォルト): Route 53のDNSラウンドロビン。ENI持続化により、インスタンスが交換されても同じIPアドレスを引き継ぐ設計loadbalancer: NLBを前段に置いてスケーラブルに分散none: クライアント側で接続先を管理(BYO)
デフォルトの dns_round_robin では、Lambda + EventBridgeによるENI持続化が組み込まれています。Auto Scalingでインスタンスが入れ替わっても同じENI(IPアドレス)を新しいインスタンスに引き継がせることで、クライアント側のマウント先IP変更を避ける狙いです。
FSID管理の3モード
re-exportで使うFSIDの管理方式も3モードから選べます。static は連番で静的に割り当てる方式、local はローカルのSQLiteでFSIDを保持する方式です。external はPostgreSQL(RDS)を使いIAM認証でクラスタ間FSIDを共有する方式で、モジュールのデフォルトです。FSID_DATABASE_DEPLOY = true によってRDS PostgreSQLまで自動で構築します。
起動完了待機とセキュリティ設計
Terraformには cluster_ready という出力があり、ENABLE_STATUS_CHECK = true を指定すると local-exec とEC2タグのポーリングで全ノードの起動完了を待機します。プロキシは起動処理が終わるとインスタンスタグを ready に更新するため、これを検出する仕組みです。デフォルトではこの待機処理は有効ではありません。
セキュリティ面では、IAMの最小権限構成、IMDSv2必須、EBS暗号化、SecureString格納、NFSポート固定化が最初から作り込まれています。
デプロイの敷居
ここまでコードを読み解いてきましたが、実際にデプロイしようとすると、その手前に無視できない敷居があります。
最初の関門はPackerによるAMIビルドです。前述のとおりカーネルをソースからビルドするため、ビルドインスタンスに c6i.16xlarge(64 vCPU)クラスの大型インスタンスがデフォルトで要求されます。プロキシ本体のデフォルトも i3en.6xlarge(24 vCPU)と大きめです。
今回の検証環境では、SCPにより16xlargeのEC2起動が制限されていたため、Packerのビルドに失敗しました。その先のTerraformデプロイとクライアント接続確認には進んでいません。
つまり、このテンプレートは「クローンしてすぐ試す」タイプの構成ではありません。ビルドに必要なvCPUのService Quotaと、組織のガードレールがビルドを許容するかどうかを着手前に確認すべきです。安易に「やってみた」ができない点こそ、この構成の性格を表しています。
まとめ
KNFSD File Cacheは、既存NFSサーバーをAWSに接続する際の課題に対して、NFS re-exportとFS-Cacheで対応するニッチなリファレンス実装です。Packer、Terraform、カスタムカーネル、Go製コンポーネントまで含む構成からも、汎用的にすぐ使うためのテンプレートというより、要件の合う環境で設計・評価して使うことを想定したGuidanceと読み取れます。
既存NFSサーバーを移行できない事情があり、AWS側にキャッシュプロキシを置く構成を具体的に検討しているなら、選択肢に加える価値があります。ただし本記事は静的解析であり、性能、フェイルオーバー、再接続、キャッシュ効率は確認していません。採用判断の前には、それらを自環境のNFSサーバーとクライアントで検証する必要があります。マネージドなNFS環境を必要とする場合には、ストレージをAWSに移設・複製することになりますが、FSx for NetApp ONTAPやEFSを比較検討することもご検討ください。









