アプリケーションポッドのライフサイクル中に、Filesystem in Userspace (FUSE) デーモンが予期せずクラッシュすることがあります。 その結果、アプリケーションポッドはFUSEファイルシステムを使用してデータにアクセスできなくなります。 このトピックでは、FUSEファイルシステムのマウントターゲットの自動回復機能を有効にして、アプリケーションポッドを再起動することなくアプリケーションデータへのアクセスを復元する方法について説明します。
前提条件
非ContainerOSオペレーティングシステムを実行するContainer Service for Kubernetes (ACK) ProクラスターまたはACK Serverless Proクラスターが作成されます。 クラスターのKubernetesバージョンが1.18以降です。 詳細については、「ACK Proクラスターの作成」および「ACKサーバーレスクラスターの作成」をご参照ください。
クラウドネイティブAIスイートがインストールされ、ack-fluidコンポーネントがデプロイされます。 ack-fluidのバージョンは1.0.9以降です。
重要オープンソースFluidをインストールしている場合は、ack-fluidコンポーネントを展開する前にアンインストールします。
クラウドネイティブAIスイートをインストールしていない場合は、スイートのインストール時にFluidアクセラレーションを有効にします。 詳細については、「クラウドネイティブAIスイートのデプロイ」をご参照ください。
クラウドネイティブAIスイートをインストールしている場合は、[ACKコンソール] にログインし、[クラウドネイティブAIスイート] ページから [ack-fluid] をデプロイします。
Object Storage Service (OSS) が有効化され、バケットが作成されます。 詳細については、「OSSの有効化」および「バケットの作成」をご参照ください。
kubectlクライアントがACK Proクラスターに接続されています。 詳細については、「kubectlを使用したクラスターへの接続」をご参照ください。
概要
Fluidデータセットを使用するアプリケーションポッドは、FUSEファイルシステムを使用して、分散キャッシュシステム内のデータにアクセスします。 各FUSEファイルシステムは、FUSEファイルシステムに送信されたファイルアクセス要求を処理するFUSEデーモンに対応する。
アプリケーションポッドのライフサイクル中に、FUSEデーモンが予期せずクラッシュする可能性があります。 たとえば、メモリ使用量が上限を超え、デーモンが強制終了されたとします。 その結果、アプリケーションポッドがFUSEファイルシステム内のファイルにアクセスすると、「Transport Endpoint is Not Connected」エラーが表示されます。 この問題を解決するには、アプリケーションポッドを手動で再起動または再構築して、FUSEファイルシステムへのアクセスを復元する必要があります。
Fluidは、FUSEファイルシステムのマウントターゲットの自動回復機能を提供します。 ノード上の各アプリケーションポッドにマウントされているFUSEファイルシステムのステータスを定期的に照会することで、Fluidを使用すると、アプリケーションポッドを再起動または再構築することなく、アプリケーションポッドのデータアクセスを復元できます。
使用上の注意
自動回復プロセスには遅延があり、ビジネスアプリケーションのシームレスな自動回復をサポートしていません。 ビジネスアプリケーションは、データアクセスの失敗を許容し、データアクセスが回復するまで再試行を続ける必要があります。
自動回復は、読み取り専用データセットに対してのみ有効にできます。 クラスターに読み書き可能なデータセットが含まれている場合は、データが予期せずデータセットに書き込まれた場合に備えて、この機能が無効になっていることを確認してください。
この機能では、subPathモードでデータセットの永続ボリュームクレーム (PVC) にアプリケーションポッドをマウントすることはできません。
FUSEデーモンが自動的に再起動された後、FUSEの自動回復機能を有効にする必要があります。 FUSEデーモンはコンテナで実行されます。 FUSEデーモンが頻繁にクラッシュすると、Kubernetesがコンテナを再起動する間隔が指数関数的に増加します。 これにより、FUSEの自動リカバリの期間が長くなります。
ACKクラスターでのFUSEマウントターゲットの自動回復の有効化
ステップ1: FUSEマウントターゲットの自動回復の有効化
次のコマンドを実行して、FUSEマウントターゲットの自動回復を有効にします。
kubectl get ds -n fluid-system csi-nodeplugin-fluid -oyaml | sed 's/FuseRecovery=false/FuseRecovery=true/g' | kubectl apply -f -
期待される出力:
daemonset.apps/csi-nodeplugin-fluid configured
次のコマンドを実行して、FUSEマウントターゲットの自動回復が有効になっているかどうかを確認します。
kubectl get ds -n fluid-system csi-nodeplugin-fluid -oyaml | grep '\- \-\-feature-gates='
次の出力が返された場合、FUSEマウントターゲットの自動回復が有効になります。
- --feature-gates=FuseRecovery=true
ステップ2: 流体データセットの作成
この例では、OSSへのアクセスを高速化するためにJindoFSがデプロイされています。
secret.yamlという名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: v1
kind: Secret
metadata:
name: mysecret
stringData:
fs.oss.accessKeyId: <YOUR_ACCESS_KEY_ID>
fs.oss.accessKeySecret: <YOUR_ACCESS_KEY_SECRET>
fs.oss.accessKeyId
およびfs.oss.accessKeySecret
は、OSSへのアクセスに使用されるAccessKey ID
およびAccessKey secret
を指定します。
次のコマンドを実行して、シークレットを作成します。
kubectl create -f secret.yaml
dataset.yamlという名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: demo-dataset
spec:
mounts:
- mountPoint: oss://<oss_bucket>/<bucket_dir>
options:
fs.oss.endpoint: <oss_endpoint>
name: mybucket
path: "/"
encryptOptions:
- name: fs.oss.accessKeyId
valueFrom:
secretKeyRef:
name: mysecret
key: fs.oss.accessKeyId
- name: fs.oss.accessKeySecret
valueFrom:
secretKeyRef:
name: mysecret
key: fs.oss.accessKeySecret
---
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
name: demo-dataset
spec:
replicas: 2
tieredstore:
levels:
- mediumtype: MEM
path: /dev/shm
volumeType: emptyDir
quota: 2Gi
high: "0.99"
low: "0.95"
下表に、各パラメーターを説明します。
パラメーター | 説明 |
mountPoint | oss://<oss_bucket>/<bucket_dir> は、マウントされるUFSへのパスを指定します。 パスにエンドポイントは必要ありません。 |
fs.oss.endpoint | OSSバケットのパブリックエンドポイントまたはプライベートエンドポイント。 詳細は、「リージョンとエンドポイント」をご参照ください。 |
レプリカ | JindoFSクラスター内のワーカーの数。 |
mediumtype | キャッシュのタイプ。 JindoRuntimeテンプレートを作成すると、JindoFSはHDD、SDD、MEMのいずれかのキャッシュタイプのみをサポートします。 |
パス | ストレージパス。 指定できるパスは1つだけです。 mediumtypeをMEMに設定した場合、ログなどのデータを格納するオンプレミスストレージのパスを指定する必要があります。 |
クォータ | キャッシュされたデータの最大サイズ。 (単位:GB) |
高い | ストレージ容量の上限。 |
低い | ストレージ容量の下限。 |
次のコマンドを実行して、DatasetオブジェクトとJindoRuntimeオブジェクトを作成します。
kubectl create -f dataset.yaml
手順3: アプリケーションポッドの作成とFluidデータセットのマウント
この例では、FluidデータセットがNGINXポッドにマウントされ、ポッドがデータセット内のデータにアクセスするために使用されます。
app.yamlという名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: v1
kind: Pod
metadata:
name: demo-app
labels:
fuse.serverful.fluid.io/inject: "true"
spec:
containers:
- name: demo
image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
volumeMounts:
- mountPath: /data
name: data-vol
volumes:
- name: data-vol
persistentVolumeClaim:
claimName: demo-dataset # The value of this parameter must be the same as the name of the Dataset.
fuse.serverful.fluid.io/inject=true
ラベルは、ポッドのFUSEマウントターゲットの自動リカバリを有効にするために使用されます。
次のコマンドを実行して、アプリケーションポッドを作成します。
kubectl create -f app.yaml
次のコマンドを実行して、ポッドのステータスを表示します。
kubectl get pod demo-app
ポッドのSTATUSフィールドがRunningの場合、ポッドは起動されます。
NAME READY STATUS RESTARTS AGE
demo-app 1/1 Running 0 16s
ステップ4: FUSEマウントターゲットの自動回復機能の確認
次のコマンドを実行してポッドにログインし、定期的にファイルメタデータにアクセスするスクリプトを実行します。 スクリプトは、マウントされたFluidデータセットのファイルを1秒ごとに一覧表示します。
kubectl exec -it demo-app -- bash -c 'while true; do ls -l /data; sleep 1; done'
上記のスクリプトをバックグラウンドで実行したままにし、次のコマンドを実行してFUSEコンポーネントのクラッシュをシミュレートします。
# Obtain the node where demo-pod resides.
demo_pod_node_name=$(kubectl get pod demo-app -ojsonpath='{.spec.nodeName}')
# Obtain the name of the FUSE pod on the same node as demo-pod.
fuse_pod_name=$(kubectl get pod --field-selector spec.nodeName=$demo_pod_node_name --selector role=jindofs-fuse,release=demo-dataset -oname)
# Simulate a crash in the FUSE pod.
kubectl exec -it $fuse_pod_name -- bash -c 'kill 1'
demo-appで実行されるスクリプトの出力を表示します。 次の出力が返されると、FUSEマウントポイントが復元されます。
...
total 172
-rwxrwxr-x 1 root root 18 Jul 1 15:17 myfile
-rwxrwxr-x 1 root root 154 Jul 1 17:06 myfile.txt
total 172
-rwxrwxr-x 1 root root 18 Jul 1 15:17 myfile
-rwxrwxr-x 1 root root 154 Jul 1 17:06 myfile.txt
ls: cannot access '/data/': Transport endpoint is not connected
ls: cannot access '/data/': Transport endpoint is not connected
ls: cannot access '/data/': Transport endpoint is not connected
ls: cannot access '/data/': Transport endpoint is not connected
ls: cannot access '/data/': Transport endpoint is not connected
ls: cannot access '/data/': Transport endpoint is not connected
ls: cannot access '/data/': Transport endpoint is not connected
ls: cannot access '/data/': Transport endpoint is not connected
total 172
-rwxrwxr-x 1 root root 18 Jul 1 15:17 myfile
-rwxrwxr-x 1 root root 154 Jul 1 17:06 myfile.txt
total 172
-rwxrwxr-x 1 root root 18 Jul 1 15:17 myfile
-rwxrwxr-x 1 root root 154 Jul 1 17:06 myfile.txt
...
サーバーレス環境でのFUSEマウントターゲットの自動回復の有効化
手順1: Fluidデータセットの作成
この例では、OSSへのアクセスを高速化するためにJindoFSがデプロイされています。
secret.yamlという名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: v1
kind: Secret
metadata:
name: mysecret
stringData:
fs.oss.accessKeyId: <YOUR_ACCESS_KEY_ID>
fs.oss.accessKeySecret: <YOUR_ACCESS_KEY_SECRET>
fs.oss.accessKeyId
およびfs.oss.accessKeySecret
は、OSSへのアクセスに使用されるAccessKey ID
およびAccessKey Secret
を指定します。
次のコマンドを実行して、シークレットを作成します。
kubectl create -f secret.yaml
dataset.yamlという名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: demo-dataset
spec:
mounts:
- mountPoint: oss://<oss_bucket>/<bucket_dir>
options:
fs.oss.endpoint: <oss_endpoint>
name: mybucket
path: "/"
encryptOptions:
- name: fs.oss.accessKeyId
valueFrom:
secretKeyRef:
name: mysecret
key: fs.oss.accessKeyId
- name: fs.oss.accessKeySecret
valueFrom:
secretKeyRef:
name: mysecret
key: fs.oss.accessKeySecret
---
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
name: demo-dataset
spec:
replicas: 2
tieredstore:
levels:
- mediumtype: MEM
path: /dev/shm
volumeType: emptyDir
quota: 2Gi
high: "0.99"
low: "0.95"
下表に、各パラメーターを説明します。
パラメーター | 説明 |
mountPoint | oss://<oss_bucket>/<bucket_dir> は、マウントされたUFSへのパスを指定します。 パスにエンドポイントは必要ありません。 |
fs.oss.endpoint | OSSバケットのパブリックエンドポイントまたはプライベートエンドポイント。 詳細は、「リージョンとエンドポイント」をご参照ください。 |
レプリカ | JindoFSクラスター内のワーカーの数。 |
mediumtype | キャッシュのタイプ。 JindoRuntimeテンプレートを作成すると、JindoFSはHDD、SDD、MEMのいずれかのキャッシュタイプのみをサポートします。 |
パス | ストレージパス。 指定できるパスは1つだけです。 mediumtypeをMEMに設定した場合、ログなどのデータを格納するオンプレミスストレージのパスを指定する必要があります。 |
クォータ | キャッシュされたデータの最大サイズ。 (単位:GB) |
高い | ストレージ容量の上限。 |
低い | ストレージ容量の下限。 |
次のコマンドを実行して、DatasetオブジェクトとJindoRuntimeオブジェクトを作成します。
kubectl create -f dataset.yaml
手順2: アプリケーションポッドの作成とFluidデータセットのマウント
この例では、FluidデータセットがNGINXポッドにマウントされ、ポッドがデータセット内のデータにアクセスするために使用されます。
app.yamlという名前のファイルを作成し、次の内容をファイルにコピーします。
apiVersion: v1
kind: Pod
metadata:
name: demo-app
labels:
alibabacloud.com/fluid-sidecar-target: eci
annotations:
# Disable the virtual node-based pod scheduling policy.
alibabacloud.com/burst-resource: eci_only
# Enable auto recovery for FUSE
alibabacloud.com/fuse-recover-policy: auto
spec:
containers:
- name: demo
image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
volumeMounts:
- mountPath: /data
name: data-vol
volumes:
- name: data-vol
persistentVolumeClaim:
claimName: demo-dataset # The value of this parameter must be the same as the name of the Dataset.
alibabacloud.com/fuse-recover-policy=auto
アノテーションは、ポッドのFUSEマウントターゲットの自動回復を有効にするために使用されます。 このアノテーションは、サーバーレス環境で実行されるアプリケーションポッドにのみ有効です。
以下のコマンドを実行して、ポッドを作成します。
kubectl create -f app.yaml
次のコマンドを実行して、ポッドのステータスを表示します。
kubectl get pod demo-app
ポッドのSTATUSフィールドがRunningの場合、ポッドは起動されます。
NAME READY STATUS RESTARTS AGE
demo-app 2/2 Running 0 110s
ステップ3: FUSEマウントターゲットの自動回復機能の確認
次のコマンドを実行してポッドにログインし、定期的にファイルメタデータにアクセスするスクリプトを実行します。 スクリプトは、マウントされたFluidデータセットのファイルを1秒ごとに一覧表示します。
kubectl exec -it demo-app -c demo -- bash -c 'while true; do ls -l /data; sleep 1; done'
上記のスクリプトをバックグラウンドで実行したままにし、次のコマンドを実行してFUSEコンポーネントのクラッシュをシミュレートします。
# Simulate a crash in the FUSE pod.
kubectl exec -it demo-app -c fluid-fuse-0 -- bash -c 'kill 1'
demo-appで実行されるスクリプトの出力を表示します。 次の出力が返されると、FUSEマウントポイントが復元されます。
total 172
-rwxrwxr-x 1 root root 18 Jul 1 15:17 myfile
-rwxrwxr-x 1 root root 154 Jul 1 17:06 myfile.txt
total 172
-rwxrwxr-x 1 root root 18 Jul 1 15:17 myfile
-rwxrwxr-x 1 root root 154 Jul 1 17:06 myfile.txt
ls: cannot access '/data/demo2': Transport endpoint is not connected
ls: cannot access '/data/demo2': Transport endpoint is not connected
ls: cannot access '/data/demo2': Transport endpoint is not connected
ls: cannot access '/data/demo2': Transport endpoint is not connected
total 172
-rwxrwxr-x 1 root root 18 Jul 1 15:17 myfile
-rwxrwxr-x 1 root root 154 Jul 1 17:06 myfile.txt
total 172
-rwxrwxr-x 1 root root 18 Jul 1 15:17 myfile
-rwxrwxr-x 1 root root 154 Jul 1 17:06 myfile.txt