AKSからAzure Files NFS 4.1をTLS暗号化してマウントする方法|CSI設定と確認手順

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またはPersistentVolumeAKSノードからAzure FilesへのNFS通信をAZNFSとStunnel経由のTLS通信にする
Require Encryption in Transit for NFSAzure 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 SKUNFS対応の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_LRSPremiumV2_ZRSは現在推奨されるSSDプロビジョニングv2のSKUですが、利用にはAzure Files CSI driver 1.35.0以降が必要です。条件を満たさない環境では、同じTLS設定を使用しつつPremium_LRSまたはPremium_ZRSを選択します。(マイクロソフトラーニング)

TLS暗号化対応のStorageClassを作成する

動的プロビジョニングでは、parameters内にprotocol: nfsencryptInTransit: "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=4noresvportactimeo=30の組み合わせが示されています。(マイクロソフトラーニング)

各設定の意味は次のとおりです。

項目内容
provisionerAzure File CSI driverを指定する
protocol: nfsSMBではなくNFS共有を作成する
skuName使用するPremium SSD SKUを指定する
encryptInTransitAZNFSとStunnelを使用したTLSマウントを有効にする
nconnect=4NFS接続を複数化し、Azure Filesで推奨される接続数にする
noresvport再接続時の可用性を高める
actimeo=30属性キャッシュを30秒にしてメタデータ処理の負荷を抑える
reclaimPolicy: RetainPVCや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.1sec=sysを指定することがありますが、Azure File CSI driverを使う場合、次の項目をStorageClassへ追加してはいけません。

mountOptions:
  - vers=4.1
  - minorversion=1
  - sec=sys

versminorversionsecはCSI driverが管理しており、マニフェストで明示的に指定する構成はサポートされていません。TLSを有効にするために必要なのは、parametersencryptInTransit: "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へ移行する

推奨手順は次のとおりです。

  1. 暗号化対応StorageClassと新しいPVCを作成する
  2. テスト用Podで読み書きとTLSマウントを確認する
  3. アプリケーションからの書き込みを停止する
  4. 既存PVCから新しいPVCへデータを同期する
  5. DeploymentまたはStatefulSetのclaimNameを変更する
  6. Podを再作成して動作確認する
  7. 一定期間後に旧PVCを廃止する

コピー中に旧PVCと新PVCを同じPodへマウントする場合、同一ノードから同一サーバーエンドポイントへTLSと非TLSを混在させないよう注意してください。AZNFSは同じ接続先に対するTLSマウントと非TLSマウントの混在を防止します。ストレージアカウントが異なっていても、同じIPアドレスへ名前解決される場合は同じ制約を受けることがあります。(マイクロソフトラーニング)

同じAzureファイル共有を静的PVで再マウントする

データコピーを避けて既存共有を使い続ける場合は、静的PVのvolumeAttributesencryptInTransit: "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"}}'

その後、次の順序で作業します。

  1. 対象DeploymentやStatefulSetを停止する
  2. 共有へ書き込むすべてのPodが停止したことを確認する
  3. 既存PV、PVC、ストレージアカウント名、共有名を記録する
  4. Retainになっていることを再確認する
  5. 既存のPVCとPVオブジェクトを削除する
  6. encryptInTransit: "true"を含む静的PVとPVCを作成する
  7. アプリケーションを再起動する
  8. データの読み書きとTLS通信を確認する

reclaimPolicy: DeleteのままPVCやPVを削除すると、基になるAzureファイル共有まで削除される可能性があります。既存データを再利用する移行では、削除操作の前にRetainを確認することが重要です。

Microsoftの公式例でも、既存PVにはvolumeAttributesとしてprotocol: nfsencryptInTransit: "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で接続している状態で暗号化を強制すると、そのクライアントは再マウントに失敗します。安全な適用順序は次のとおりです。

  1. AKSで暗号化対応StorageClassまたはPVを作成する
  2. 対象ワークロードをTLSマウントへ切り替える
  3. AZNFSとStunnelの動作を確認する
  4. AKS以外のNFSクライアントを棚卸しする
  5. すべてのクライアントが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.aznfsaznfswatchdogを確認する
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関連エラーversminorversionsecを手動指定した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では次の順序で対応するのが適切です。

  1. AKSバージョンが1.33以降か確認する
  2. サポート対象のノードOSを使用する
  3. 最新のAKSノードイメージへ更新する
  4. Azure File CSI driverのバージョンを確認する
  5. それでも不足する場合に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"がある
  • [ ] versminorversionsecを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層を順番に設定・確認することが、停止時間と移行リスクを抑えるポイントです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次