AKSの既存アプリを変更せず、Azure Files Premium SSDのNFS 4.1通信をTLS暗号化したい場合は、Azure File CSI driverのカスタムStorageClassにencryptInTransit: "true"を設定します。AKSノード上のAZNFS mount helperがStunnelを介してTLSトンネルを作成するため、Podは従来どおりPVCをファイルシステムとして利用でき、アプリケーションコードやコンテナイメージの変更は必要ありません。(マイクロソフトラーニング)
ただし、StorageClassを変更しただけでは、すでに作成・マウントされているPVは暗号化接続へ切り替わりません。新しいStorageClassとPVCを作成するか、既存のAzureファイル共有を静的PVとして再定義し、Podを再マウントする必要があります。また、クライアント側のTLSマウント設定に加え、ストレージアカウント側でも「Require Encryption in Transit for NFS」を有効にすると、非暗号化接続そのものを拒否できます。(マイクロソフトラーニング)
Azure Update ID 567787で案内されたこの機能は、現在、SSD Azureファイル共有を提供するリージョンで一般提供されています。AKSではバージョン1.33以降が対象で、Ubuntu 20.04ノードとWindowsノードは現時点でサポート対象外です。(マイクロソフトラーニング)
結論:AKS側のTLSマウントとAzure Files側の強制設定を組み合わせる
必要な設定は、次の2段階に分けて考えると分かりやすくなります。
| 設定 | 設定場所 | 役割 |
|---|---|---|
encryptInTransit: "true" | StorageClassまたはPersistentVolume | AKSノードからAzure FilesへのNFS通信をAZNFSとStunnel経由のTLS通信にする |
| Require Encryption in Transit for NFS | Azure Filesのストレージアカウント | TLSを使用しないNFSクライアントからの接続を拒否する |
| PVCの指定 | DeploymentやStatefulSet | アプリから利用する暗号化対応PVを選択する |
| Podの再作成 | AKSワークロード | 既存のNFSセッションを終了し、TLS対応で再マウントする |
encryptInTransitだけでも、そのPVのマウント通信は暗号化できます。しかし、同じAzure Filesへ接続する別のVMやAKSクラスターが非TLSでマウントする可能性は残ります。セキュリティ基準や監査要件で暗号化を必須とする場合は、AKS側の設定を確認した後、ストレージアカウント側でも暗号化を強制する構成が適切です。(マイクロソフトラーニング)
AZNFS mount helperとStunnelで暗号化される仕組み
TLS暗号化を有効にした場合、通信経路は概念的に次のようになります。
アプリケーション
↓ 通常のファイル読み書き
Pod内のマウントパス
↓
PVC/PV
↓
Azure File CSI driver
↓
AZNFS mount helperのローカルエンドポイント
↓
StunnelによるTLS暗号化
↓
Azure Files NFS 4.1
AZNFS mount helperは、NFSクライアントからの要求をローカルエンドポイントで受け取ります。ストレージアカウントごとに動作するStunnelプロセスが、その通信をTLSで暗号化してAzure Filesへ転送します。AZNFS watchdogはStunnelの稼働状態を監視し、異常終了したトンネルの再起動や、不要になったプロセスのクリーンアップを行います。(マイクロソフトラーニング)
この処理はAKSノードのストレージ層で行われます。Podから見ると通常のNFSファイルシステムであり、アプリケーション側でTLSライブラリを追加したり、Stunnelのサイドカーコンテナを配置したりする必要はありません。
一方、TLS暗号化はNFSのユーザー認証方式を置き換えるものではありません。Azure File CSI driverがNFS 4.1のバージョンやsec設定を管理するため、ネットワーク制限、ファイル所有者、POSIXアクセス権、root squashなどは引き続き適切に設定する必要があります。(マイクロソフトラーニング)
設定前に確認する前提条件
本番環境へ適用する前に、次の項目を確認します。
| 確認項目 | 判断基準 |
|---|---|
| AKSバージョン | 1.33以降 |
| ノードOS | 対応するLinuxノード。Ubuntu 20.04とWindowsは対象外 |
| CSIドライバー | file.csi.azure.comが有効 |
| Azure Files SKU | NFS対応のPremium SSD |
| PremiumV2利用時 | Azure Files CSI driver 1.35.0以降 |
| ネットワーク | VNet接続またはプライベートエンドポイントが構成済み |
| 名前解決 | Azure FilesのFQDNが正しいプライベートIPまたは接続先へ解決される |
| 権限 | AKSのIDにVNet、NSG、ストレージアカウントを操作するための必要な権限がある |
| AZNFS | 対応するノードイメージにmount helperが存在する |
Azure FilesのNFS 4.1はPremium SSDファイル共有とVNet対応ストレージアカウントを必要とします。選択したVNetへのアクセス許可の代わりに、プライベートエンドポイントも使用できます。(マイクロソフトラーニング)
AKSとCSIドライバーを確認するコマンド
AKS_RG="rg-aks"
AKS_NAME="aks-production"
az aks show \
--resource-group "$AKS_RG" \
--name "$AKS_NAME" \
--query kubernetesVersion \
--output tsv
kubectl get csidriver file.csi.azure.com
kubectl get storageclass
ノードプールのOSやノードイメージも確認します。
az aks nodepool list \
--resource-group "$AKS_RG" \
--cluster-name "$AKS_NAME" \
--output table
PremiumV2 SKUを使う場合は、Azure File CSI driverのイメージタグも確認してください。
kubectl -n kube-system get daemonset csi-azurefile-node \
-o jsonpath='{range .spec.template.spec.containers[*]}{.name}{"\t"}{.image}{"\n"}{end}'
PremiumV2_LRSとPremiumV2_ZRSは現在推奨されるSSDプロビジョニングv2のSKUですが、利用にはAzure Files CSI driver 1.35.0以降が必要です。条件を満たさない環境では、同じTLS設定を使用しつつPremium_LRSまたはPremium_ZRSを選択します。(マイクロソフトラーニング)
TLS暗号化対応のStorageClassを作成する
動的プロビジョニングでは、parameters内にprotocol: nfsとencryptInTransit: "true"を指定します。
次の例では、PremiumV2_LRS、NFS 4.1、TLS暗号化を使用します。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azurefile-csi-premiumv2-eit
provisioner: file.csi.azure.com
reclaimPolicy: Retain
volumeBindingMode: Immediate
allowVolumeExpansion: true
parameters:
protocol: nfs
skuName: PremiumV2_LRS
encryptInTransit: "true"
mountOptions:
- nconnect=4
- noresvport
- actimeo=30
MicrosoftのAKS向け構成例でも、encryptInTransit: "true"と、nconnect=4、noresvport、actimeo=30の組み合わせが示されています。(マイクロソフトラーニング)
各設定の意味は次のとおりです。
| 項目 | 内容 |
|---|---|
provisioner | Azure File CSI driverを指定する |
protocol: nfs | SMBではなくNFS共有を作成する |
skuName | 使用するPremium SSD SKUを指定する |
encryptInTransit | AZNFSとStunnelを使用したTLSマウントを有効にする |
nconnect=4 | NFS接続を複数化し、Azure Filesで推奨される接続数にする |
noresvport | 再接続時の可用性を高める |
actimeo=30 | 属性キャッシュを30秒にしてメタデータ処理の負荷を抑える |
reclaimPolicy: Retain | PVCやPVを削除しても基になるファイル共有を自動削除しない |
reclaimPolicy: RetainはTLSの必須条件ではありませんが、本番データを誤って削除しないための安全策です。検証用や一時データで、PVC削除時にAzureファイル共有も削除したい場合はDeleteを選択します。
既存のストレージアカウントを使う場合
CSI driverに既存のストレージアカウントを使わせる場合は、必要に応じて次のパラメーターを追加します。
parameters:
protocol: nfs
skuName: PremiumV2_LRS
encryptInTransit: "true"
storageAccount: mystorageaccount
resourceGroup: rg-storage
この場合、指定したストレージアカウントは事前に作成されている必要があります。また、AKSのマネージドIDまたはサービスプリンシパルに、対象ストレージアカウントとネットワークを操作するための権限が必要です。(マイクロソフトラーニング)
vers=4.1をmountOptionsへ書かない
通常のLinux NFSマウントではvers=4.1やsec=sysを指定することがありますが、Azure File CSI driverを使う場合、次の項目をStorageClassへ追加してはいけません。
mountOptions:
- vers=4.1
- minorversion=1
- sec=sys
vers、minorversion、secはCSI driverが管理しており、マニフェストで明示的に指定する構成はサポートされていません。TLSを有効にするために必要なのは、parametersのencryptInTransit: "true"です。(マイクロソフトラーニング)
暗号化対応PVCを作成して既存アプリへ接続する
StorageClassを適用します。
kubectl apply -f storageclass-azurefile-nfs-eit.yaml
kubectl get storageclass azurefile-csi-premiumv2-eit
続いて、暗号化対応StorageClassを指定したPVCを作成します。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-files-eit
namespace: production
spec:
accessModes:
- ReadWriteMany
storageClassName: azurefile-csi-premiumv2-eit
resources:
requests:
storage: 100Gi
kubectl apply -f pvc-azurefile-nfs-eit.yaml
kubectl get pvc shared-files-eit -n production --watch
PVCがBoundになったら、DeploymentやStatefulSetから指定します。
spec:
template:
spec:
containers:
- name: application
volumeMounts:
- name: shared-files
mountPath: /data
volumes:
- name: shared-files
persistentVolumeClaim:
claimName: shared-files-eit
アプリケーションが従来から/dataを使っている場合、変更するのはclaimNameだけです。コンテナ内のパス、ファイル操作、アプリケーションコードはそのまま維持できます。
変更後はPodを再作成し、新しいTLS対応マウントを確立します。
kubectl rollout restart deployment/my-application -n production
kubectl rollout status deployment/my-application -n production
StatefulSetの場合は次のように実行します。
kubectl rollout restart statefulset/my-application -n production
kubectl rollout status statefulset/my-application -n production
既存PVはStorageClassを変更しただけでは暗号化されない
運用上、最も注意すべき点です。
StorageClassを後から編集してencryptInTransit: "true"を追加しても、すでに作成されているPVには反映されません。PersistentVolumeのボリューム属性は作成後に変更できず、StorageClassの更新は新しくプロビジョニングされるボリュームだけに影響します。(マイクロソフトラーニング)
既存アプリを移行する方法は、主に次の2つです。
| 移行方法 | 向いているケース | 特徴 |
|---|---|---|
| 新しい暗号化PVCへデータをコピー | 新旧環境を並行検証したい | 元データを残せるため安全性が高い |
| 同じAzureファイル共有を静的PVとして再登録 | データ量が多くコピーを避けたい | メンテナンス停止とPV/PVCの再作成が必要 |
安全性を優先するなら新しいPVCへ移行する
推奨手順は次のとおりです。
- 暗号化対応StorageClassと新しいPVCを作成する
- テスト用Podで読み書きとTLSマウントを確認する
- アプリケーションからの書き込みを停止する
- 既存PVCから新しいPVCへデータを同期する
- DeploymentまたはStatefulSetの
claimNameを変更する - Podを再作成して動作確認する
- 一定期間後に旧PVCを廃止する
コピー中に旧PVCと新PVCを同じPodへマウントする場合、同一ノードから同一サーバーエンドポイントへTLSと非TLSを混在させないよう注意してください。AZNFSは同じ接続先に対するTLSマウントと非TLSマウントの混在を防止します。ストレージアカウントが異なっていても、同じIPアドレスへ名前解決される場合は同じ制約を受けることがあります。(マイクロソフトラーニング)
同じAzureファイル共有を静的PVで再マウントする
データコピーを避けて既存共有を使い続ける場合は、静的PVのvolumeAttributesにencryptInTransit: "true"を設定します。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-azurefile-nfs-eit
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: ""
mountOptions:
- nconnect=4
- noresvport
- actimeo=30
csi:
driver: file.csi.azure.com
volumeHandle: "rg-storage#mystorageaccount#myshare"
volumeAttributes:
protocol: nfs
encryptInTransit: "true"
resourceGroup: "rg-storage"
storageAccount: "mystorageaccount"
shareName: "myshare"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-files-eit
namespace: production
spec:
accessModes:
- ReadWriteMany
storageClassName: ""
volumeName: pv-azurefile-nfs-eit
resources:
requests:
storage: 100Gi
既存PVを再作成する前に、再利用ポリシーを必ずRetainへ変更します。
kubectl patch pv <既存PV名> \
-p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
その後、次の順序で作業します。
- 対象DeploymentやStatefulSetを停止する
- 共有へ書き込むすべてのPodが停止したことを確認する
- 既存PV、PVC、ストレージアカウント名、共有名を記録する
Retainになっていることを再確認する- 既存のPVCとPVオブジェクトを削除する
encryptInTransit: "true"を含む静的PVとPVCを作成する- アプリケーションを再起動する
- データの読み書きとTLS通信を確認する
reclaimPolicy: DeleteのままPVCやPVを削除すると、基になるAzureファイル共有まで削除される可能性があります。既存データを再利用する移行では、削除操作の前にRetainを確認することが重要です。
Microsoftの公式例でも、既存PVにはvolumeAttributesとしてprotocol: nfsとencryptInTransit: "true"を設定し、再利用ポリシーをRetainにしています。(マイクロソフトラーニング)
Azure Files側で非TLS接続を拒否する
AKS側でTLSマウントを確認したら、ストレージアカウント側でNFS暗号化を必須化します。
Azure CLIでは次のコマンドを使用します。
STORAGE_RG="rg-storage"
STORAGE_ACCOUNT="mystorageaccount"
az storage account file-service-properties update \
--nfs-eit \
--require-nfs-encryption-in-transit true \
--name "$STORAGE_ACCOUNT" \
--resource-group "$STORAGE_RG" \
--output json
Azure PowerShellでは次のコマンドレットを使用できます。
Update-AzStorageFileServiceProperty `
-ResourceGroupName "rg-storage" `
-StorageAccountName "mystorageaccount" `
-NfsEncryptionInTransitRequired $true
Azure portalでは、既存ストレージアカウントの「File share settings」から「Security」を開き、NFSの転送中暗号化を要求する設定を有効にします。(マイクロソフトラーニング)
ポータルから新規作成したストレージアカウントでは、この設定が既定で有効になります。一方、Azure CLI、PowerShell、FileREST APIで作成したストレージアカウントは、下位互換性のため「未選択」になる場合があります。Terraform、Bicep、CLIなどを使う環境では、既定値に依存せず明示的に設定してください。(マイクロソフトラーニング)
暗号化強制は移行の最後に有効にする
既存クライアントが非TLSで接続している状態で暗号化を強制すると、そのクライアントは再マウントに失敗します。安全な適用順序は次のとおりです。
- AKSで暗号化対応StorageClassまたはPVを作成する
- 対象ワークロードをTLSマウントへ切り替える
- AZNFSとStunnelの動作を確認する
- AKS以外のNFSクライアントを棚卸しする
- すべてのクライアントがTLS対応した後に暗号化を強制する
ロールバックの可能性がある検証期間中は強制設定を待ち、クライアント側の移行完了後に有効化すると、障害時の切り戻しが容易です。
TLS暗号化が有効になったことを確認する方法
設定値だけでなく、Kubernetes、ノード、ネットワークの3層で確認します。
PVのvolumeAttributesを確認する
PVCに割り当てられたPV名を取得します。
PV_NAME=$(kubectl get pvc shared-files-eit \
-n production \
-o jsonpath='{.spec.volumeName}')
echo "$PV_NAME"
続いて、encryptInTransitを確認します。
kubectl get pv "$PV_NAME" \
-o jsonpath='{.spec.csi.volumeAttributes.encryptInTransit}{"\n"}'
次のように表示されれば、PVに暗号化属性が設定されています。
true
StorageClassも確認します。
kubectl get storageclass azurefile-csi-premiumv2-eit -o yaml
Podから読み書きを確認する
アプリケーションコンテナ、または検証用Podからファイルを作成します。
kubectl exec -n production deployment/my-application -- \
sh -c 'date -u > /data/eit-test.txt && cat /data/eit-test.txt'
コンテナにshが含まれていない場合は、同じPVCを接続した検証用Podを作成してください。
AZNFSとStunnelをノード側で確認する
対象Podが配置されているノードを確認します。
kubectl get pod -n production -o wide
組織で許可されたSSHやノードデバッグ方法を使って対象ノードへ入り、次のコマンドを確認します。
systemctl is-active aznfswatchdog
command -v mount.aznfs
pgrep -a stunnel
df -Th
findmnt
AZNFSによるTLSマウントでは、ノード側のマウント情報に127.0.0.1を経由する接続が表示されます。NFSクライアントはローカルのStunnelへ接続し、StunnelがAzure FilesへTLSで転送します。(マイクロソフトラーニング)
AZNFS関連のログは、次の場所で確認できます。
/opt/microsoft/aznfs/data/aznfs.log
/etc/stunnel/microsoft/aznfs/nfsv4_fileShare/logs
パケットキャプチャで確認する
より厳密に確認する場合は、検証用ノードで2049番ポートの通信をキャプチャします。
sudo tcpdump \
-i any \
port 2049 \
-c 200 \
-w /tmp/azurefiles-nfs-eit.pcap
キャプチャをWiresharkで開き、NFSのファイル内容が平文で表示されず、暗号化されたApplication Dataとして確認できれば、TLSトンネルが機能しています。パケットキャプチャには接続先などの情報が含まれるため、本番環境では取得範囲と保管先を制限してください。(マイクロソフトラーニング)
マウントに失敗したときの確認ポイント
| 症状 | 主な原因 | 対応 |
|---|---|---|
unknown filesystem type 'aznfs' | ノードにAZNFS mount helperがない、またはノードイメージが古い | AKSとノードイメージを更新し、mount.aznfsとaznfswatchdogを確認する |
PodがContainerCreatingのまま | CSIマウント失敗 | PodイベントとCSI node podのログを確認する |
MountVolume.SetUp failedのタイムアウト | DNS、NSG、VNet、プライベートエンドポイントの問題 | FQDNの名前解決と2049番ポートへの到達性を確認する |
access denied by server | ストレージネットワーク規則、root squash、POSIX権限 | ストレージアカウントのネットワーク設定と共有権限を確認する |
PVCがPending | 非対応SKU、容量、CSI driverのバージョン、権限不足 | Premium SSD、100Gi以上の構成例、CSI driver、AKS IDの権限を確認する |
encryptInTransitを追加しても変化しない | 既存PVをそのまま使用している | 新しいPVを作成してPodを再マウントする |
| mount option関連エラー | vers、minorversion、secを手動指定した | 3項目をStorageClassから削除する |
| TLS移行中だけマウントに失敗する | 同一エンドポイントへのTLSと非TLSの混在 | 対象Podを別ノードへ分離するか、同時にTLSへ切り替える |
Kubernetesイベントを確認する
kubectl describe pod <pod-name> -n production
kubectl get events -n production --sort-by=.lastTimestamp
Azure File CSI node podを確認する
kubectl -n kube-system get pods -o wide | grep csi-azurefile-node
対象ノード上のCSI podを特定し、コンテナ名を確認します。
kubectl -n kube-system get pod <csi-pod-name> \
-o jsonpath='{.spec.containers[*].name}{"\n"}'
その後、Azure File CSI driverのログを取得します。
kubectl -n kube-system logs <csi-pod-name> \
-c azurefile \
--since=15m
AKSノードへAZNFSを手動インストールすべきか
通常のLinux VMでは、Microsoftのパッケージリポジトリからaznfsをインストールできます。しかしAKSのノードは、アップグレード、再イメージ化、オートスケールによって置き換えられます。ノードへ個別に手動インストールしても、その変更は将来のノードへ自動継承されません。
そのため、AKSでは次の順序で対応するのが適切です。
- AKSバージョンが1.33以降か確認する
- サポート対象のノードOSを使用する
- 最新のAKSノードイメージへ更新する
- Azure File CSI driverのバージョンを確認する
- それでも不足する場合にMicrosoftサポートへ確認する
ノードへの手動インストールは、一時的な検証や原因切り分けには利用できますが、本番環境の恒久対策には向きません。AZNFS自体はStunnelのインストールと設定、ローカルエンドポイントの作成、watchdogによる監視を担います。(マイクロソフトラーニング)
性能と運用で注意したいポイント
導入前後でI/O性能を比較する
TLS暗号化処理はAKSノード上のStunnelが担当します。実際の影響は、ファイルサイズ、IOPS、同時接続数、ノードサイズによって異なるため、代表的なワークロードで次の項目を比較します。
- 読み書きのスループット
- 1操作あたりのレイテンシ
- AKSノードのCPU使用率
- StunnelプロセスのCPU使用率
- Pod起動時のマウント時間
- メタデータ操作の応答時間
nconnect=4はAzure Filesで推奨される値です。最大16まで設定できますが、Microsoftは現時点で4を超えても性能向上が得られないと説明しています。(マイクロソフトラーニング)
actimeo=30はアプリ特性に合わせる
actimeo=30はメタデータキャッシュを利用して、属性確認が多いワークロードの待ち時間を抑える設定です。
一方、複数Podが同じファイル名や属性を短時間で頻繁に更新し、即時のメタデータ反映を必要とするアプリでは、キャッシュ時間が動作へ影響する可能性があります。既存のStorageClassで別の値を使っている場合は、TLS化と同時に変更せず、まず現在のmount optionを維持して暗号化だけを追加する方が、問題を切り分けやすくなります。
ネットワーク分離は継続する
TLSを有効にしても、Azure Filesをインターネットへ広く公開してよいわけではありません。次の対策は継続します。
- 選択したVNetまたはプライベートエンドポイントを使用する
- ストレージアカウントのパブリックネットワークアクセスを制限する
- プライベートDNSゾーンを正しくVNetへリンクする
- NSGで必要な通信だけを許可する
- root squashとPOSIXアクセス権をアプリ要件に合わせる
NFSの通信暗号化、ネットワーク境界、ファイルアクセス権は、それぞれ別のセキュリティ層として設定する必要があります。
適用時の最終チェックリスト
- [ ] AKSがバージョン1.33以降になっている
- [ ] Ubuntu 20.04またはWindowsノードを使用していない
- [ ]
file.csi.azure.comが有効になっている - [ ] Azure FilesがPremium SSDのNFS 4.1共有になっている
- [ ] PremiumV2利用時はCSI driver 1.35.0以降になっている
- [ ] StorageClassまたはPVに
encryptInTransit: "true"がある - [ ]
vers、minorversion、secをmountOptionsへ追加していない - [ ] 既存PVではなく、TLS設定を持つ新しいPVとして再マウントしている
- [ ] AZNFS watchdogとStunnelがノード上で動作している
- [ ] 読み書きテストが成功している
- [ ] ノード側で127.0.0.1経由のマウントを確認している
- [ ] 必要に応じてパケットキャプチャでTLS通信を確認している
- [ ] すべてのクライアント移行後にAzure Files側の暗号化強制を有効にしている
- [ ] 本番移行前に
reclaimPolicyとロールバック方法を確認している
AKSの既存アプリを変更せずにAzure Files NFS 4.1を暗号化する場合、最初に現在のStorageClassを別名で複製し、encryptInTransit: "true"を追加するのが安全です。そのStorageClassで検証用PVCを作成し、AZNFS、Stunnel、読み書き、ネットワーク通信を確認してから対象アプリを段階的に移行します。
最後にAzure Files側の「Require Encryption in Transit for NFS」を有効にすれば、AKSだけでなく、同じ共有へ接続するすべてのNFSクライアントにTLSを要求できます。アプリケーション改修ではなく、CSI、PV、ノード、ストレージアカウントの4層を順番に設定・確認することが、停止時間と移行リスクを抑えるポイントです。

コメント