Azure Kubernetes Service (AKS) で Azure Blob Storage を使用してボリュームを作成して使用する

コンテナーベースのアプリケーションは、データへのアクセスとデータの永続化の手段として、外部データ ボリュームが必要になることが少なくありません。 複数のポッドが同じストレージ ボリュームに同時にアクセスする必要がある場合は、Azure Blob Storage を使用し、blobfuse またはネットワーク ファイル システム (NFS) を使用して接続できます。

この記事で取り上げるテクニック:

  • Container Storage Interface (CSI) ドライバーをインストールし、Azure Blob Storage コンテナーを動的に作成してポッドに接続して、動的永続ボリューム (PV) を操作します。
  • Azure Blob Storage コンテナーを作成して静的 PV を操作するか、既存のものを使用してポッドにアタッチします。

Kubernetes ボリュームの詳細については、AKS でのアプリケーションのストレージ オプションに関するページを参照してください。

開始する前に

  • AKS クラスターで Blob Storage CSI ドライバーを有効にします

  • blobfuse マウントを使用するときに Azure DataLake Gen2 ストレージ アカウントをサポートするには、次の操作を行う必要があります。

    • 動的プロビジョニングでドライバーを使用して ADLS アカウントを作成するには、ストレージ クラス パラメーターで isHnsEnabled: "true" を指定します。
    • 静的プロビジョニングで ADLS アカウントへの blobfuse アクセスを有効にするには、永続ボリュームでマウント オプション --use-adls=true を指定します。
    • 階層型名前空間でストレージ アカウントを有効にする場合は、--use-adls=true マウント オプションを使って既存の永続ボリュームをマウントし直す必要があります。
  • blobfuse キャッシュについて

    • 既定では、blobfuse キャッシュは、/mnt ディレクトリにあります。 VM SKU が一時ディスクを備えている場合、/mnt ディレクトリは一時ディスクにマウントされます。 ただし、VM SKU が一時ディスクを備えていない場合、/mnt ディレクトリは OS ディスクにマウントされます。また、--tmp-path= マウント オプションは、別のキャッシュ ディレクトリを指定するように設定できます

ボリュームを動的にプロビジョニングする

このセクションでは、ワークロードで使用する BLOB ストレージの詳細を含む 1 つ以上の永続ボリュームをプロビジョニングするクラスター管理者向けのガイダンスを提供します。 永続ボリューム要求 (PVC) は、ストレージ クラス オブジェクトを使用して、Azure Blob Storage コンテナーを動的にプロビジョニングします。

動的 PersistentVolumes のストレージ クラス パラメータ

次の表には、PersistentVolumeClaim のカスタム ストレージ クラスを定義するために使用できるパラメータが含まれています。

名前 Description Mandatory 既定値
skuName Azure ストレージ アカウントの種類 (別名: storageAccountType) を指定します。 Standard_LRSPremium_LRSStandard_GRS, Standard_RAGRS いいえ Standard_LRS
location Azure の場所を指定します。 eastus いいえ 空の場合、ドライバーでは現在のクラスターと同じ場所名が使用されます。
resourceGroup Azure リソース グループ名を指定します。 myResourceGroup いいえ 空の場合、ドライバーでは現在のクラスターと同じリソース グループ名が使用されます。
storageAccount Azure ストレージ アカウントの名前を指定します。 storageAccountName - blobfuse マウントの場合は、いいえ
- NFSv3 マウントの場合は、はい。
- blobfuse マウントの場合: 空の場合、ドライバーは同じリソース グループ内の skuName に一致する適切なストレージ アカウントを見つけます。 ストレージ アカウント名が指定されている場合は、ストレージ アカウントが存在する必要があります。
- NFSv3 マウントの場合は、ストレージ アカウント名を指定する必要があります。
networkEndpointType ドライバーによって作成されたストレージ アカウントのネットワーク エンドポイントの種類を指定します。 privateEndpoint が指定されている場合、ストレージ アカウントのプライベート エンドポイントが作成されます。 それ以外の場合は、NFS プロトコルのサービス エンドポイントが作成されます。1 privateEndpoint いいえ AKS クラスターの場合は、VNET をホストするリソース グループの共同作成者ロールに AKS クラスター名を追加します。
protocol blobfuse マウントまたは NFSv3 マウントを指定します。 fusenfs いいえ fuse
containerName 既存のコンテナー (ディレクトリ) 名を指定します。 container いいえ 空の場合、ドライバーは、blobfuse の場合は pvc-fuse、NFS v3 の場合は pvc-nfs から始まる新しいコンテナー名を作成します。
containerNamePrefix ドライバーによって作成された Azure Storage ディレクトリ プレフィックスを指定します。 my 小文字、数字、ハイフンのみを含めることができ、長さは 21 文字未満にする必要があります。 いいえ
server Azure ストレージ アカウントのドメイン名を指定します。 既存のストレージ アカウントの DNS ドメイン名。たとえば、<storage-account>.privatelink.blob.core.windows.net いいえ 空の場合、ドライバーは既定の <storage-account>.blob.core.windows.net またはその他のソブリン クラウド ストレージ アカウントの DNS ドメイン名を使用します。
allowBlobPublicAccess ドライバーによって作成されたストレージ アカウントのすべての BLOB またはコンテナーへのパブリック アクセスを許可または禁止します。 truefalse いいえ false
storageEndpointSuffix Azure Storage エンドポイント サフィックスを指定します。 core.windows.net いいえ 空の場合、ドライバーはクラウド環境に応じて既定のストレージ エンドポイント サフィックスを使用します。
tags タグは新しいストレージ アカウントに作成されます。 タグの形式: 'foo=aaa,bar=bbb' いいえ ""
matchTags ドライバーが適切なストレージ アカウントを検索しようとしたときにタグを照合します。 truefalse いいえ false
--- 次のパラメーターは blobfuse 専用です --- --- ---
subscriptionID Blob Storage ディレクトリが作成される Azure サブスクリプション ID を指定します。 Azure サブスクリプション ID いいえ 空でない場合は、resourceGroup を指定する必要があります。
storeAccountKey Kubernetes シークレットにストア アカウント キーを指定します。

注:
false は、ドライバーが kubelet ID を使用してアカウント キーを取得することを意味します。
truefalse いいえ true
secretName アカウント キーを格納するシークレット名を指定します。 いいえ
secretNamespace アカウント キーを格納するシークレットの名前空間を指定します。 defaultkube-systemなど いいえ pvc 名前空間
isHnsEnabled Azure DataLake ストレージ アカウントの Hierarchical namespace を有効にします。 truefalse いいえ false
--- 次のパラメーターは NFS プロトコル専用です --- --- ---
mountPermissions マウントされたフォルダーのアクセス許可を指定します。 既定値は、0777 です。 0 に設定すると、ドライバーはマウント後に chmod を実行しません。 0777 いいえ

1 ドライバーによってストレージ アカウントが作成されている場合は、ストレージ クラスで networkEndpointType: privateEndpoint パラメーターを指定するだけで済みます。 CSI ドライバーは、アカウントと共にプライベート エンドポイントを作成します。 独自のストレージ アカウントを使用する場合は、ストレージ アカウントのプライベート エンドポイントを作成する必要があります。

組み込みのストレージ クラスを使用して永続ボリューム要求を作成する

永続ボリューム要求 (PVC) は、ストレージ クラス オブジェクトを使用して、Azure Blob Storage コンテナーを動的にプロビジョニングします。 次の YAML を使うと、組み込みのストレージ クラスを使用して、サイズが 5 GB で、<ReadWriteMany> アクセス権の永続ボリューム要求を作成できます。 アクセス モードの詳細については、Kubernetes 永続ボリュームに関するドキュメントを参照してください。

  1. blob-nfs-pvc.yaml という名前のファイルを作成し、そこに以下の YAML をコピーします。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: azure-blob-storage
    spec:
      accessModes:
      - ReadWriteMany
      storageClassName: azureblob-nfs-premium
      resources:
        requests:
          storage: 5Gi
    
  2. kubectl create コマンドを使用して、永続ボリューム要求を作成します。

    kubectl create -f blob-nfs-pvc.yaml
    

完了すると、Blob Storage コンテナーが作成されます。 kubectl get コマンドを使用すると、PVC の状態を表示できます。

kubectl get pvc azure-blob-storage

コマンドの出力は、次の例のようになります。

NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS                AGE
azure-blob-storage   Bound    pvc-b88e36c5-c518-4d38-a5ee-337a7dda0a68   5Gi        RWX            azureblob-nfs-premium       92m

永続ボリューム要求を使用する

次の YAML は、永続ボリューム請求 azure-blob-storage を使って、`/mnt/blob' パスに Azure Blob Storage をマウントするポッドを作成します。

  1. blob-nfs-pv という名前のファイルを作成し、そこに以下の YAML をコピーします。 claimName が前のステップで作成した PVC と一致していることを確認します。

    kind: Pod
    apiVersion: v1
    metadata:
      name: mypod
    spec:
      containers:
      - name: mypod
        image: mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi
        volumeMounts:
        - mountPath: "/mnt/blob"
          name: volume
          readOnly: false
      volumes:
        - name: volume
          persistentVolumeClaim:
            claimName: azure-blob-storage
    
  2. kubectl apply コマンドを使用してポッドを作成します。

    kubectl apply -f blob-nfs-pv.yaml
    
  3. ポッドが実行中状態になったら、次のコマンドを実行して、test.txt という新しいファイルを作成します。

    kubectl exec mypod -- touch /mnt/blob/test.txt
    
  4. ディスクが正しくマウントされていることを検証するには、次のコマンドを実行して、出力に test.txt ファイルが表示されることを確認します。

    kubectl exec mypod -- ls /mnt/blob
    

    コマンドの出力は、次の例のようになります。

    test.txt
    

カスタム ストレージ クラスを作成する

既定のストレージ クラスは最も一般的なシナリオに適合しますが、すべてに適合するわけではありません。 場合によっては、独自のストレージ クラスを独自のパラメーターを使用してカスタマイズすることもできます。 このセクションでは、2 つの例を示します。 1 つ目は NFS プロトコルを使用し、2 つ目は blobfuse を使用します。

NFS プロトコルを使用したストレージ クラス

この例では、次のマニフェストは、NFS プロトコルを使用して Blob Storage コンテナーのマウントを構成します。 これを使用して tags パラメーターを追加します。

  1. blob-nfs-sc.yaml という名前のファイルを作成し、次のマニフェストの例を貼り付けます。

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: azureblob-nfs-premium
    provisioner: blob.csi.azure.com
    parameters:
      protocol: nfs
      tags: environment=Development
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
    mountOptions:
      - nconnect=4
    
  2. kubectl apply コマンドを使用してストレージ クラスを作成します。

    kubectl apply -f blob-nfs-sc.yaml
    

    コマンドの出力は、次の例のようになります。

    storageclass.storage.k8s.io/blob-nfs-premium created
    

blobfuse を使用したストレージ クラス

この例では、次のマニフェストは blobfuse を使用して構成し、Blob Storage コンテナーをマウントします。 これを使用して skuName パラメーターを更新します。

  1. blobfuse-sc.yaml という名前のファイルを作成し、次のマニフェストの例を貼り付けます。

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: azureblob-fuse-premium
    provisioner: blob.csi.azure.com
    parameters:
      skuName: Standard_GRS  # available values: Standard_LRS, Premium_LRS, Standard_GRS, Standard_RAGRS
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
    mountOptions:
      - -o allow_other
      - --file-cache-timeout-in-seconds=120
      - --use-attr-cache=true
      - --cancel-list-on-mount-seconds=10  # prevent billing charges on mounting
      - -o attr_timeout=120
      - -o entry_timeout=120
      - -o negative_timeout=120
      - --log-level=LOG_WARNING  # LOG_WARNING, LOG_INFO, LOG_DEBUG
      - --cache-size-mb=1000  # Default will be 80% of available memory, eviction will happen beyond that.
    
  2. kubectl apply コマンドを使用してストレージ クラスを作成します。

    kubectl apply -f blobfuse-sc.yaml
    

    コマンドの出力は、次の例のようになります。

    storageclass.storage.k8s.io/blob-fuse-premium created
    

ボリュームを静的にプロビジョニングする

このセクションでは、ワークロードで使用する BLOB ストレージの詳細を含む 1 つ以上の永続ボリュームを作成するクラスター管理者向けのガイダンスを提供します。

永続ボリュームの静的プロビジョニング パラメーター

次の表には、永続ボリュームを定義するために使用できるパラメーターが含まれています。

名前 Description Mandatory 既定値
volumeHandle ドライバーがクラスター内のストレージ BLOB コンテナーを一意に識別するために使用する値を指定します。 一意の値を生成するには、{account-name}_{container-name} のように、グローバルに一意のストレージ アカウント名とコンテナー名を組み合わせることをお勧めします。
注: #/ 文字は内部使用のために予約されており、ボリューム ハンドルでは使用できません。
はい
volumeAttributes.resourceGroup Azure リソース グループ名を指定します。 myResourceGroup いいえ 空の場合、ドライバーでは、現在のクラスターと同じリソース グループ名が使われます。
volumeAttributes.storageAccount 既存の Azure ストレージ アカウント名を指定します。 storageAccountName はい
volumeAttributes.containerName 既存のコンテナー名を指定します。 container はい
volumeAttributes.protocol blobfuse マウントまたは NFS v3 マウントを指定します。 fusenfs いいえ fuse
--- 次のパラメーターは blobfuse 専用です --- --- ---
volumeAttributes.secretName ストレージ アカウント名とキーを格納するシークレット名 (SMB にのみ適用されます)。 いいえ
volumeAttributes.secretNamespace アカウント キーを格納するシークレットの名前空間を指定します。 default いいえ pvc 名前空間
nodeStageSecretRef.name 次のいずれかを保存するシークレット名を指定します。
azurestorageaccountkey
azurestorageaccountsastoken
msisecret
azurestoragespnclientsecret
いいえ 既存の Kubernetes シークレット名
nodeStageSecretRef.namespace シークレットの名前空間を指定します。 Kubernetes 名前空間 はい
--- 次のパラメーターは NFS プロトコル専用です --- --- ---
volumeAttributes.mountPermissions マウントされたフォルダーのアクセス許可を指定します。 0777 いいえ
--- 次のパラメーターは NFS VNet 設定専用です --- --- ---
vnetResourceGroup 仮想ネットワークをホストする VNet リソース グループを指定します。 myResourceGroup いいえ 空の場合、ドライバーには Azure クラウド構成ファイルに指定されている vnetResourceGroup 値が使われます。
vnetName 仮想ネットワーク名を指定します。 aksVNet いいえ 空の場合、ドライバーには Azure クラウド構成ファイルに指定されている vnetName 値が使われます。
subnetName エージェント ノードの既存のサブネット名を指定します。 aksSubnet いいえ 空の場合、ドライバーには Azure クラウド構成ファイル内の subnetName 値が使われます。
--- 次のパラメーターは次の機能専用です: blobfuse
マネージド ID とサービス プリンシパル名の認証
--- --- ---
volumeAttributes.AzureStorageAuthType 認証の種類を指定します。 KeySASMSI, SPN いいえ Key
volumeAttributes.AzureStorageIdentityClientID ID クライアント ID を指定します。 いいえ
volumeAttributes.AzureStorageIdentityObjectID ID オブジェクト ID を指定します。 いいえ
volumeAttributes.AzureStorageIdentityResourceID ID リソース ID を指定します。 いいえ
volumeAttributes.MSIEndpoint MSI エンドポイントを指定します。 いいえ
volumeAttributes.AzureStorageSPNClientID Azure サービス プリンシパル名 (SPN) クライアント ID を指定します。 いいえ
volumeAttributes.AzureStorageSPNTenantID Azure SPN テナント ID を指定します。 いいえ
volumeAttributes.AzureStorageAADEndpoint Microsoft Entra エンドポイントを指定します。 いいえ
--- 次のパラメーターは次の機能専用です: blobfuse の読み取りアカウント キーまたはキー コンテナーの SAS トークン --- --- ---
volumeAttributes.keyVaultURL Azure Key Vault の DNS 名を指定します。 {vault-name}.vault.azure.net いいえ
volumeAttributes.keyVaultSecretName Azure Key Vault のシークレット名を指定します。 既存の Azure Key Vault のシークレット名。 いいえ
volumeAttributes.keyVaultSecretVersion Azure Key Vault シークレットのバージョン。 既存のバージョン。 いいえ 空の場合、ドライバーには現在のバージョンが使われます。

BLOB ストレージ コンテナーを作成する

AKS で使用するための Azure BLOB ストレージ リソースを作成する場合は、ノード リソース グループ内にディスク リソースを作成することができます。 この方法により、AKS クラスターから BLOB ストレージ リソースにアクセスし、管理できるようになります。

この記事では、ノード リソース グループ内にコンテナーを作成します。 最初に、az aks show コマンドを使用してリソース グループ名を取得し、--query nodeResourceGroup クエリ パラメーターを追加します。 次の例では、リソース グループ名 myResourceGroup にある myAKSCluster という名前の AKS クラスターのノード リソース グループを取得しています。

az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv

コマンドの出力は、次の例のようになります。

MC_myResourceGroup_myAKSCluster_eastus

次に、BLOB ストレージの管理に関する記事の手順に従って BLOB を格納するためのコンテナーを作成し、アクセスを認可してからコンテナーを作成します。

ボリュームをマウントする

このセクションでは、NFS プロトコルまたは Blobfuse を使用して永続ボリュームをマウントします。

NFS v3 プロトコルを使って BLOB ストレージをマウントする場合、アカウント キーを使って認証が行われません。 AKS クラスターは、エージェント ノードと同じ、またはピアリングされた仮想ネットワーク内に存在する必要があります。 ストレージ アカウントのデータをセキュリティで保護する唯一の方法は、仮想ネットワークと、その他のネットワーク セキュリティ設定を使用することです。 ストレージ アカウントへの NFS アクセスを設定する方法の詳細については、「ネットワーク ファイル システム (NFS) 3.0 プロトコルを使用して Blob Storage をマウントする」を参照してください。

次の例は、NFS プロトコルを使って BLOB ストレージ コンテナーを永続ボリュームとしてマウントする方法を示しています。

  1. pv-blob-nfs.yaml という名前のファイルを作成し、そこに以下の YAML をコピーします。 storageClass の下にある resourceGroupstorageAccountcontainerName を更新します。

    Note

    volumeHandle 値は、クラスター内のすべての同一のストレージ BLOB コンテナーに対して一意の volumeID である必要があります。 文字 # および / は内部使用のために予約されており、使用できません。

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      annotations:
        pv.kubernetes.io/provisioned-by: blob.csi.azure.com
      name: pv-blob
    spec:
      capacity:
        storage: 1Pi
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Retain  # If set as "Delete" container would be removed after pvc deletion
      storageClassName: azureblob-nfs-premium
      mountOptions:
        - nconnect=4
      csi:
        driver: blob.csi.azure.com
        # make sure volumeid is unique for every identical storage blob container in the cluster
        # character `#` and `/` are reserved for internal use and cannot be used in volumehandle
        volumeHandle: account-name_container-name
        volumeAttributes:
          resourceGroup: resourceGroupName
          storageAccount: storageAccountName
          containerName: containerName
          protocol: nfs
    

    Note

    Kubernetes API容量属性は必須ですが、ストレージ アカウントの容量制限に達するまで柔軟にデータを書き込むことができるため、この値は Azure Blob Storage CSI ドライバーでは使用されません。 capacity 属性の値は、PersistentVolumesPersistentVolumeClaims の間のサイズ一致にのみ使用されます。 架空の高い値を使用することをお勧めします。 ポッドには、5 ペタバイトの架空のサイズのマウントされたボリュームが表示されます。

  2. 次のコマンドを実行し、先ほど作成した YAML ファイルを参照する kubectl create コマンドを使って、永続ボリュームを作成します。

    kubectl create -f pv-blob-nfs.yaml
    
  3. pvc-blob-nfs.yamlPersistentVolumeClaim を使用して ファイルを作成します。 次に例を示します。

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc-blob
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 10Gi
      volumeName: pv-blob
      storageClassName: azureblob-nfs-premium
    
  4. 次のコマンドを実行し、先ほど作成した YAML ファイルを参照する kubectl create コマンドを使って、永続ボリューム要求を作成します。

    kubectl create -f pvc-blob-nfs.yaml
    

永続ボリュームの使用

次の YAML では、先ほど作成した pvc-BLOB という永続ボリュームまたは永続ボリューム要求を使い、/mnt/blob パスにある Azure Blob ストレージをマウントするポッドを作成しています。

  1. nginx-pod-blob.yaml という名前のファイルを作成し、そこに以下の YAML をコピーします。 NFS または Blobfuse 用の永続ボリュームを作成するときに前の手順で作成した PVC と、claimName が一致することを確認します。

    kind: Pod
    apiVersion: v1
    metadata:
      name: nginx-blob
    spec:
      nodeSelector:
        "kubernetes.io/os": linux
      containers:
        - image: mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine
          name: nginx-blob
          volumeMounts:
            - name: blob01
              mountPath: "/mnt/blob"
              readOnly: false
      volumes:
        - name: blob01
          persistentVolumeClaim:
            claimName: pvc-blob
    
  2. 次のコマンドを実行し、先ほど作成した YAML ファイルを参照する kubectl create コマンドを使って、ポッドを作成し、PVC をマウントします。

    kubectl create -f nginx-pod-blob.yaml
    
  3. 次のコマンドを実行してポッドとの対話型シェル セッションを作成し、マウントされた BLOB ストレージを確認します。

    kubectl exec -it nginx-blob -- df -h
    

    コマンドの出力は、次の例のようになります。

    Filesystem      Size  Used Avail Use% Mounted on
    ...
    blobfuse         14G   41M   13G   1% /mnt/blob
    ...
    

次のステップ