このトピックでは、Container Service for Kubernetes (ACK) および Alibaba Cloud Container Service (ACS) クラスターにおける Network Attached Storage (NAS) ボリュームに関する一般的な課題について説明します。具体的には、マウント失敗、権限エラー、アンマウントタイムアウトなどが含まれます。
クイックナビゲーション
マウント
chown: Operation not permitted(マウント中に操作が許可されていません)
コンテナプロセスに NAS ボリューム上のファイル所有者を変更する権限がありません。以下のいずれかの方法で対応してください。
ルートとして実行するか、`fsGroup` を使用する:
accessModesがReadWriteOnceに設定されている場合、securityContext.fsGroupを設定して、Pod のボリュームの所有者を指定します。詳細については、「Pod またはコンテナの Security Context を設定する」をご参照ください。NAS 権限グループを確認する: root として実行してもエラーが継続する場合、マウントターゲットの権限ルールにより root が匿名ユーザーにマッピングされている可能性があります。no_squash に権限ルールを設定することで、この挙動を防止できます。詳細については、「権限グループの管理」をご参照ください。
動的にプロビジョニングされた NAS ボリュームのマウント時にコントローラーのタスクキューが満杯になる
reclaimPolicy が Delete に、archiveOnDelete が false に設定されている場合、StorageClass 内でサブディレクトリの削除は作成よりも遅くなります。これにより、コントローラーのタスクキューがブロックされ、新しい永続ボリューム(PV)の作成ができなくなります。
StorageClass 内の archiveOnDelete を true に設定してください。この設定により、PV の削除時にサブディレクトリの内容が削除されるのではなく、名前が変更されます。これは大幅に高速な処理です。名前が変更されたサブディレクトリは別途クリーンアップしてください。たとえば、定期実行ジョブを実行するか、特定の命名パターンに一致するサブディレクトリを複数の Pod で並列に削除するなどの方法があります。
マウント時間が予想より長くなる
以下の 2 つの条件が同時に満たされる場合、Kubernetes はマウント済みボリュームに対して再帰的に chmod および chown を実行し、マウント操作が大幅に遅くなります。
永続ボリューム(PV)および永続ボリューム要求(PVC)において、
accessModesがReadWriteOnceに設定されているPod の仕様(spec)で
securityContext.fsGroupが設定されている
以下のいずれかの方法を選択してください。
fsGroup を削除する:ワークロードで必要でない場合は、
securityContextからfsGroupフィールドを削除します。手動で事前に権限を設定する:対象ディレクトリを ECS インスタンスにマウントし、
chownまたはchmodを実行して必要な権限を設定した後、Container Storage Interface(CSI)経由で NAS ボリュームを使用します。詳細については、「静的にプロビジョニングされた NAS ボリュームのマウント」または「動的にプロビジョニングされた NAS ボリュームの使用」をご参照ください。fsGroupChangePolicy を使用する(Kubernetes 1.20+): Pod の
securityContextでfsGroupChangePolicyをOnRootMismatchに設定します。これにより、Kubernetes はボリューム初回マウント時のみchmodおよびchownを実行し、2 回目以降のマウントは大幅に高速になります。詳細については、「Pod またはコンテナの Security Context の設定」をご参照ください。
unknown filesystem type "xxx"(マウント時に「不明なファイルシステムタイプ "xxx"」エラーが発生する)
Pod がスケジュールされたノードに必要なストレージ依存関係が不足しています。ボリューム構成が正しいことを確認してください。
2 つの NAS PVC をマウントする際に Pod が ContainerCreating 状態で停止する
Pod が同一の NAS ファイルシステムを指す 2 つの PVC をマウントし、ContainerCreating 状態で停止する場合、2 つの PV がおそらく同一の spec.csi.volumeHandle を共有しています。kubelet はこれらを同一の PV とみなすため、マウント競合が発生します。ただし、個別にいずれかの PVC をマウントすると正常に動作します。
各 PV に対して一意の spec.csi.volumeHandle を設定してください。推奨される方法は、これを PV 名(metadata.name)と同じ値に設定することです。
CSI を使用して TLS 暗号化で NAS ファイルシステムをマウントする方法
NAS ボリュームの TLS 暗号化には、alinas マウントプロトコルが使用され、トラフィックは Alibaba Cloud NAS クライアントを経由してルーティングされます。
NAS クライアントは TLS 暗号化に Stunnel を使用します。高スループットのワークロードでは、CPU リソースを多量に消費する可能性があります。極端なケースでは、単一のマウントポイントが CPU コア 1 つを占有することもあります。詳細については、「NFS ファイルシステムの転送中暗号化」をご参照ください。
アドオン ページで、
csi-pluginの構成を編集し、AlinasMountProxy=trueFeatureGate を有効化します。以下の YAML をクラスターに適用します。どちらの例でも
mountProtocol: alinasおよびtlsマウントオプションが使用されています。動的にプロビジョニングされたボリューム
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: alicloud-nas-tls mountOptions: - nolock,tcp,noresvport - vers=3 - tls # TLS 暗号化を有効化します。 parameters: volumeAs: subpath server: "0cd8b4a576-g****.cn-hangzhou.nas.aliyuncs.com:/k8s/" mountProtocol: alinas # Alibaba Cloud NAS クライアントを使用します。 provisioner: nasplugin.csi.alibabacloud.com reclaimPolicy: Retain --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: nas-tls spec: accessModes: - ReadWriteMany storageClassName: alicloud-nas-tls resources: requests: storage: 20Giパラメーター 説明 parameters.mountProtocolマウントクライアントを指定します。 alinasを設定すると、Alibaba Cloud NAS クライアントが使用されます。デフォルト値は""(標準 NFS プロトコル)です。mountOptionsマウントオプションのリストです。 tlsを追加すると TLS 暗号化が有効化されます。tlsオプションは、mountProtocolがalinasに設定されている場合にのみ有効です。静的にプロビジョニングされたボリューム
apiVersion: v1 kind: PersistentVolume metadata: name: pv-nas-tls labels: alicloud-pvname: pv-nas-tls spec: capacity: storage: 5Gi accessModes: - ReadWriteMany csi: driver: nasplugin.csi.alibabacloud.com volumeHandle: pv-nas # PV 名と一致させる必要があります。 volumeAttributes: server: "2564f4****-ysu87.cn-shenzhen.nas.aliyuncs.com" path: "/csi" mountProtocol: alinas # Alibaba Cloud NAS クライアントを使用します。 mountOptions: - nolock,tcp,noresvport - vers=3 - tls # TLS 暗号化を有効化します。 --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: pvc-nas-tls spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi selector: matchLabels: alicloud-pvname: pv-nas-tlsパラメーター 説明 spec.csi.volumeAttributes.mountProtocolマウントクライアントを指定します。 alinasを設定すると、Alibaba Cloud NAS クライアントが使用されます。デフォルト値は""(標準 NFS プロトコル)です。spec.mountOptionsマウントオプションのリストです。 tlsを追加すると TLS 暗号化が有効化されます。tlsオプションは、mountProtocolがalinasに設定されている場合にのみ有効です。
NAS 上でユーザーまたはグループの隔離を実装する方法
共有 NAS ボリューム上で異なるユーザーおよびグループ間のアクセスを隔離するには、コンテナプロセスを nobody ユーザー(UID/GID 65534)として実行します。
ワークロードマニフェストに
securityContextフィールドを追加します。apiVersion: apps/v1 kind: StatefulSet metadata: name: nas-sts spec: selector: matchLabels: app: nginx serviceName: "nginx" replicas: 1 template: metadata: labels: app: nginx spec: securityContext: fsGroup: 65534 # 新規ファイルおよびディレクトリの UID/GID を 65534(nobody)に設定します。 fsGroupChangePolicy: "OnRootMismatch" # ルートディレクトリの権限が一致しない場合にのみ所有権を更新します。 containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 securityContext: runAsUser: 65534 # 全プロセスを UID 65534(nobody)として実行します。 runAsGroup: 65534 # 全プロセスのプライマリ GID を 65534(nobody)として実行します。 allowPrivilegeEscalation: false volumeMounts: - name: nas-pvc mountPath: /data volumeClaimTemplates: - metadata: name: nas-pvc spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "alicloud-nas-subpath" resources: requests: storage: 100Giコンテナプロセスが
nobodyとして実行されていることを確認します。kubectl exec nas-sts-0 -- "top"期待される出力:
Mem: 11538180K used, 52037796K free, 5052K shrd, 253696K buff, 8865272K cached CPU: 0.1% usr 0.1% sys 0.0% nic 99.7% idle 0.0% io 0.0% irq 0.0% sirq Load average: 0.76 0.60 0.58 1/1458 54 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 49 0 nobody R 1328 0.0 9 0.0 top 1 0 nobody S 1316 0.0 10 0.0 sleep 3600NAS マウントパス内の新規ファイルおよびディレクトリが
nobodyの所有権を持つことを確認します。kubectl exec nas-sts-0 -- sh -c "touch /data/test; mkdir /data/test-dir; ls -arlth /data/"期待される出力:
total 5K drwxr-xr-x 1 root root 4.0K Aug 30 10:14 .. drwxr-sr-x 2 nobody nobody 4.0K Aug 30 10:14 test-dir -rw-r--r-- 1 nobody nobody 0 Aug 30 10:14 test drwxrwsrwx 3 root nobody 4.0K Aug 30 10:14 .
複数のアプリケーションが同じ NAS ボリュームを共有できますか?
はい。NAS は共有ストレージを提供するため、単一の PVC を複数の Pod が同時にマウントできます。
同時書き込み時の動作および既知の制限事項については、「複数のプロセスまたはクライアントがログファイルに同時に書き込む際に発生する例外を防ぐ方法」および「NFS ファイルシステムへのデータ書き込み遅延を解決する方法」をご参照ください。
マウント手順については、「CNFS を使用した NAS ファイルシステムの管理(推奨)」、「静的にプロビジョニングされた NAS ボリュームのマウント」および「動的にプロビジョニングされた NAS ボリュームの使用」をご参照ください。
ACS で NAS ボリュームをマウントする際に failed to do setup volume(ボリュームのセットアップに失敗しました)エラーが発生する
このエラーは、通常、NAS マウントターゲットがクラスターとは異なる仮想プライベートクラウド(VPC)内にあることを意味します。以下の手順で確認してください。
クラスターの VPC ID を取得します。
ACS コンソール にログインします。左側のナビゲーションウィンドウで クラスター をクリックします。
クラスター名をクリックします。左側のナビゲーションウィンドウで 構成 > ConfigMap を選択します。
kube-system名前空間に切り替え、acs-profileをクリックします。vpcIdの値(例:vpc-gw87c9kdqs25al2z****)を記録します。
NAS マウントターゲットの VPC ID を取得します。
2 つの VPC ID を比較します。一致しない場合、NAS マウントポイントはクラスターからアクセスできません。詳細については、「ACS への NAS ファイルシステムのマウント」をご参照のうえ、正しい VPC 内にマウントポイントを作成するか、StorageClass を更新して正しいマウントターゲットアドレスを使用してください。
使用
NAS ボリューム上でディレクトリを作成または変更できない
非 root のコンテナプロセスには、マウント済み PV に対する書き込み権限がありません。以下のいずれかの方法で対応してください。
init コンテナを使用する: root 権限を持つ init コンテナを起動し、PV をマウントして、マウントディレクトリの権限を設定するために
chmodまたはchownを実行します。fsGroupChangePolicy を使用する: Pod の
securityContextでfsGroupChangePolicyをOnRootMismatchに設定します。Kubernetes は、ボリューム初回マウント時に自動的にchmodおよびchownを実行します。
読み取り/書き込み操作中に NFS Stale File Handle エラーが発生する
これは標準的な NFS の動作です。あるクライアントがファイルを削除した際に、別のクライアントがそのファイルのオープンファイルディスクリプタを保持している場合に発生します。
クライアント A が
/data/file.txtを開きます。クライアント B が
/data/file.txtを削除します。クライアント A が無効になったファイルディスクリプタを使用して読み取りまたは書き込みを試みると、このエラーが発生します。
NAS はこのレベルでのデータ整合性を保証しません。アプリケーションのロジック内でこのエラーを処理してください。たとえば、ファイルロックを実装するか、このエラーが発生した際にファイルハンドルを再オープンするなどの方法があります。
アンマウント
アンマウントがタイムアウトし、Pod が Terminating 状態で停止する
マウント済み NAS ボリュームを持つ Pod を削除した際に Terminating 状態で停止する場合、原因は通常、csi-plugin DaemonSet の誤った構成にあります。具体的には、/var/run が hostPath ボリュームとしてマウントされている場合です。
以下のコマンドを実行して確認します。
kubectl patch -n kube-system daemonset csi-plugin -p '
spec:
template:
spec:
containers:
- name: csi-plugin
volumeMounts:
- mountPath: /host/var/run/efc
name: efc-metrics-dir
- mountPath: /host/var/run/ossfs
name: ossfs-metrics-dir
- mountPath: /host/var/run/
$patch: delete
volumes:
- name: ossfs-metrics-dir
hostPath:
path: /var/run/ossfs
type: DirectoryOrCreate
- name: efc-metrics-dir
hostPath:
path: /var/run/efc
type: DirectoryOrCreate
- name: fuse-metrics-dir
$patch: delete'コマンドが何らかの出力を返す場合、誤った構成が存在します。DaemonSet をパッチで修正します。
このパッチにより、csi-plugin Pod が再起動します。本番環境に適用する前に、ワークロードへの影響を評価してください。
kubectl patch -n kube-system daemonset csi-plugin -p '
spec:
template:
spec:
containers:
- name: csi-plugin
volumeMounts:
- mountPath: /host/var/run/efc
name: efc-metrics-dir
- mountPath: /host/var/run/ossfs
name: ossfs-metrics-dir
- mountPath: /host/var/run/
$patch: delete
volumes:
- name: ossfs-metrics-dir
hostPath:
path: /var/run/ossfs
type: DirectoryOrCreate
- name: efc-metrics-dir
hostPath:
path: /var/run/efc
type: DirectoryOrCreate
- name: fuse-metrics-dir
$patch: delete'パッチ適用後、csi-plugin Pod が正しい構成で再起動され、アンマウントの問題が解消されます。