在應用Pod的生命周期內,FUSE守護進程可能會因為異常情況崩潰,導致應用Pod無法正常訪問數據。本文檔介紹如何開啟并使用FUSE掛載點自愈功能,允許在應用Pod不重啟的前提下恢復應用的數據訪問。
前提條件
已創建一個非ContainerOS操作系統的ACK Pro版集群或ACK Serverless集群Pro版,且集群版本為1.18及以上。具體操作,請參見創建ACK Pro版集群、創建ACK Serverless Pro集群。
已安裝云原生AI套件并部署ack-fluid組件,且ack-fluid版本為1.0.9及以上。
重要若您已安裝開源Fluid,請卸載后再部署ack-fluid組件。
已開通阿里云對象存儲(OSS)服務,并創建存儲空間(Bucket)。具體操作,請參見開通OSS服務和控制臺創建存儲空間。
已通過kubectl連接Kubernetes集群。具體操作,請參見通過kubectl工具連接集群。
功能概述
使用Fluid數據集(Dataset)的應用Pod通過FUSE文件系統訪問分布式緩存系統中的數據,每一個FUSE文件系統對應一個FUSE守護進程(Daemon),該進程負責處理FUSE文件系統上的任何文件訪問請求。
在應用Pod的生命周期內,FUSE守護進程可能會因為異常情況(例如:內存使用超出上限被殺死)崩潰,導致應用Pod訪問文件時出現“端點未連接”(“Transport Endpoint is Not Connected”)錯誤。為了解決此類錯誤,通常需要手動重啟應用容器或重建應用Pod以恢復FUSE文件系統的訪問。
Fluid支持FUSE文件系統掛載點的自愈功能。通過周期性查詢節點各應用Pod掛載的FUSE文件系統狀態,Fluid支持在不重啟應用容器和不重建應用Pod的前提下,恢復應用Pod內的文件訪問。
使用限制
該功能涉及的自愈過程存在一定的延遲,不支持對業務應用的無感自愈。業務應用需要容忍文件訪問失敗的情況,并持續重試直至自愈完成。
該功能僅支持與只讀類型的數據集共同使用,如果集群中包含任意可讀寫的數據集,必須確保該功能處于關閉狀態,以避免預期外的數據寫入問題。
該功能不支持應用Pod通過subPath方式掛載數據集對應的存儲卷聲明(PVC)。
FUSE掛載點自愈操作必須在FUSE守護進程自動重啟后執行,由于FUSE守護進程運行在容器中,當FUSE守護進程頻繁崩潰時,Kubernetes重啟該容器的間隔時間將會指數級增長,這將影響到FUSE掛載點自愈的恢復時間。
在ACK集群環境中使用FUSE自愈功能
步驟一:開啟FUSE掛載點自愈(Feature Gate)
使用以下命令開啟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
步驟二:創建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
。
執行以下命令,創建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的路徑,路徑中不需要包含endpoint信息。 |
fs.oss.endpoint | OSS Bucket的Endpoint信息,公網或私網地址均支持。更多信息,請參見訪問域名和數據中心。 |
replicas | 表示創建JindoFS集群的Worker數量。 |
mediumtype | 表示緩存類型。在創建JindoRuntime模板樣例時,JindoFS暫時只支持HDD/SSD/MEM中的其中一種緩存類型。 |
path | 表示存儲路徑,暫時只支持單個路徑。當選擇MEM做緩存時,需指定一個本地路徑來存儲Log等文件。 |
quota | 表示緩存最大容量,單位GB。 |
high | 表示存儲容量上限大小。 |
low | 表示存儲容量下限大小。 |
執行以下命令,創建Dataset和JindoRuntime資源。
kubectl create -f dataset.yaml
步驟三:創建應用Pod掛載Fluid數據集
本文以一個Nginx容器為例,嘗試掛載Fluid數據集并訪問其中的文件數據。
使用以下內容,創建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 # 與Dataset資源名稱一致
其中fuse.serverful.fluid.io/inject=true
的標簽用于為該Pod啟用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
步驟四:驗證FUSE掛載點自愈功能
執行以下命令,登錄到應用容器中并執行周期性訪問文件元信息的腳本,該腳本會每隔1秒鐘列舉掛載的Fluid數據集中的文件。
kubectl exec -it demo-app -- bash -c 'while true; do ls -l /data; sleep 1; done'
保持上述腳本后臺運行,執行以下命令,模擬FUSE組件異常崩潰的情況。
# 獲取demo-pod所在節點
demo_pod_node_name=$(kubectl get pod demo-app -ojsonpath='{.spec.nodeName}')
# 獲取與demo-pod相同節點的FUSE Pod名字
fuse_pod_name=$(kubectl get pod --field-selector spec.nodeName=$demo_pod_node_name --selector role=jindofs-fuse,release=demo-dataset -oname)
# 模擬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
...
在Serverless環境中使用FUSE自愈功能
步驟一:創建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
。
執行以下命令,創建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的路徑,路徑中不需要包含endpoint信息。 |
fs.oss.endpoint | OSS Bucket的Endpoint信息,公網或私網地址均支持。更多信息,請參見訪問域名和數據中心。 |
replicas | 表示創建JindoFS集群的Worker數量。 |
mediumtype | 表示緩存類型。在創建JindoRuntime模板樣例時,JindoFS暫時只支持HDD/SSD/MEM中的一種緩存類型。 |
path | 表示存儲路徑,暫時只支持單個路徑。當選擇MEM做緩存時,需指定一個本地路徑來存儲Log等文件。 |
quota | 表示緩存最大容量,單位GB。 |
high | 表示存儲容量上限大小。 |
low | 表示存儲容量下限大小。 |
執行以下命令,創建Dataset和JindoRuntime資源。
kubectl create -f dataset.yaml
步驟二:創建應用Pod掛載Fluid數據集
本文以一個Nginx容器為例,嘗試掛載Fluid數據集并訪問其中的文件數據。
使用以下內容,創建app.yaml文件。
apiVersion: v1
kind: Pod
metadata:
name: demo-app
labels:
alibabacloud.com/fluid-sidecar-target: eci
annotations:
# 禁用虛擬節點調度功能。
alibabacloud.com/burst-resource: eci_only
# 開啟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 # 與Dataset資源名稱一致
其中alibabacloud.com/fuse-recover-policy=auto
的注解用于為該Pod啟用FUSE掛載點自愈能力,該注解僅對運行于Serverless環境的應用Pod生效。
執行以下命令,創建應用Pod。
kubectl create -f app.yaml
執行以下命令,查看應用容器狀態。
kubectl get pod demo-app
如果看到容器STATUS字段已經進入Running狀態,則說明應用容器已經成功啟動。
NAME READY STATUS RESTARTS AGE
demo-app 2/2 Running 0 110s
步驟三:驗證FUSE掛載點自愈功能
執行以下命令,登錄到應用容器中并執行周期性訪問文件元信息的腳本,該腳本會每隔1秒鐘列舉掛載的Fluid數據集中的文件。
kubectl exec -it demo-app -c demo -- bash -c 'while true; do ls -l /data; sleep 1; done'
保持上述腳本后臺運行,執行以下命令,模擬FUSE組件異常崩潰的情況。
# 模擬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