本文為您介紹OSS儲存卷常見問題的處理方法。
類型 | 問題 |
掛載問題 | |
使用問題 | |
卸載問題 | |
控制台檢測失敗問題 | |
其他 |
OSS儲存卷掛載時間延長
問題現象
OSS儲存卷掛載時間延長。
問題原因
同時滿足以下配置,kubelet在儲存卷掛載過程中將執行chmod或chown操作,導致掛載時間延長。
在PV及PVC模板中配置的參數AccessModes值為ReadWriteOnce。
在應用模板中配置了securityContext.fsgroup參數。
解決方案
若應用模板中配置了securityContext.fsgroup參數,請刪除securityContext下的fsgroup參數。
若需要將掛載目錄內檔案變成期望的UID和mode,可以手動將Bucket掛載到一台ECS。再通過命令列執行
chown
和chmod
,完成後通過CSI使用OSS儲存卷。關於如何通過CSI使用OSS儲存卷,請參見使用OSS靜態儲存卷。對於1.20及之後版本的Kubernetes叢集,除了上述兩種解決方案外,也可通過將fsGroupChangePolicy配置為OnRootMismatch,這時只有在初次開機時才會執行
chmod
或chown
操作,導致存在掛載時間延長的問題,後續掛載OSS儲存卷時掛載時間將恢複正常。關於fsGroupChangePolicy參數的更多資訊,請參見為Pod或容器配置資訊安全內容。ossfs PVC不建議進行寫操作,預設唯讀。
OSS儲存掛載許可權問題
當您在以下幾種情境中進行操作時,出現錯誤提示Permission Denied。
情境1:訪問掛載目錄時,出現錯誤提示Permission Denied
問題原因
OSS預設使用Linux的root使用者進行掛載,許可權為700。當容器進程以非root使用者運行時,許可權不足。
解決方案
通過增加配置項修改掛載根目錄的許可權。
參數 | 說明 |
allow_other | 設定掛載目錄的許可權為777。 |
mp_umask | 用於設定掛載目錄的許可權掩碼,只有當
|
情境2:訪問通過ossutil、OSS控制台、SDK等其他方式上傳的檔案時,出現錯誤提示Permission Denied
問題原因
通過其他方式上傳的檔案在ossfs中預設許可權為640。當容器進程以非root使用者運行時,許可權不足。
解決方案
以root角色chmod修改目標檔案的許可權。或者通過以下配置項修改掛載目錄下子目錄及檔案的許可權。
umask:用於設定掛載目錄下子目錄及檔案的許可權掩碼。使用方式與mp_umask類似,但無需依賴allow_other配置項。
umask只能修改當前ossfs中看到的檔案的許可權,再次掛載或對其他ossfs進程並不生效。例如:
配置
-o umask=022
後,使用stat
查看一個通過OSS控制台上傳的檔案,許可權為755;取消-o umask=022
配置項後再次掛載,許可權仍為640。容器進程以root使用者配置
-o umask=133
後,通過chmod配置某檔案許可權為777,stat
該檔案許可權仍為644;取消-o umask=133
後再次掛載,許可權變更為777。
情境3:通過不同的容器進行讀寫操作時,讀、寫、運行其他容器建立的檔案。
問題原因
在ossfs中建立的普通檔案預設許可權為644。配置securityContext
中的fsGroup
欄位,或建立後chmod、chown檔案,都可能導致許可權或所有者的變更。當另一個容器進程以其他使用者操作檔案時,可能會出現許可權不足的問題。
解決方案
stat
目標檔案的許可權,若許可權不足,請以root使用者chmod修改目標檔案的許可權。
以上三種情境的解決均通過增加目錄或檔案的許可權,解決當前容器進程使用者權限不足的問題,您也可以通過修改ossfs掛載目錄下子目錄及檔案所屬使用者來解決。
容器鏡像構建時指定運行使用者,或部署時應用模板的securityContext.runAsUser
及securityContext.runAsGroup
欄位非空,都會使應用的容器進程以非root使用者運行。
通過以下配置項修改ossfs掛載目錄下子目錄及檔案的UID和GID,使其與容器進程使用者一致。
參數 | 說明 |
uid | 指定掛載目錄下子目錄及檔案歸屬使用者的使用者UID。 |
gid | 指定掛載目錄下子目錄及檔案歸屬使用者的使用者GID。 |
例如,容器訪問OSS的進程ID為uid=1000(biodocker)
、gid=1001(biodocker)
、groups=1001(biodocker)
,則需配置-o uid=1000
,-o gid=1001
。
情境4:OSS掛載時使用Secret記錄AccessKey資訊,並在PV中通過nodePublishSecretRef
欄位指定Secret。因為AK輪轉等原因撤銷了原AK,Secret中AccessKey資訊修改後不生效
問題原因
OSS資料卷是使用ossfs檔案進行掛載的FUSE檔案系統,掛載成功後無法更新AccessKey資訊,已經掛載了OSS儲存卷的應用仍然使用原AK向OSS Server端發送請求。
解決方案
切換Secret中新的AccessKey資訊後重新掛載。非容器化版本或開啟了獨享掛載方式的容器化版本,您只需要重啟應用Pod觸發ossfs重啟。具體操作,請參見共用掛載方式下,如何重啟ossfs進程?。
情境5:永久連結操作時,返回Operation not permitted
問題原因
OSS儲存卷不支援永久連結操作。在早期的CSI版本中,永久連結操作返回的報錯為Operation not permitted。
解決方案
改造業務,使用OSS儲存卷時,應避免永久連結操作。若您的業務必須使用永久連結操作,建議您更換儲存。
情境6:使用subpath或subpathExpr方式掛載OSS儲存卷,讀寫操作許可權不足
問題原因
非root使用者啟動並執行業務容器沒有/path/subpath/in/oss/
目錄下檔案的許可權(預設為640)。subpath方式掛載OSS儲存卷時,ossfs在OSS服務端實際的掛載目錄為PV中定義的path目錄,即上述樣本中的/path
,而非/path/subpath/in/oss/
。配置allow_other或mp_umask掛載項僅對/path
目錄生效,/path/subpath/in/oss/
目錄作為子目錄仍預設為640。
解決方案
通過umask配置項修改子目錄預設許可權,例如-o umask=000
將預設許可權修改為777。
OSS靜態卷掛載失敗
問題現象
OSS靜態卷掛載失敗,Pod無法啟動,Event提示FailedMount。
問題原因
原因1:ossfs早期的版本不支援掛載到Bucket中不存在的目錄中,原掛載目錄不存在導致掛載失敗。
重要OSS控制台中可見的子路徑在Server端不一定真實存在,以ossutil或OSS API的返回為準。例如,直接建立
/a/b/c/
目錄,/a/b/c/
為單獨的目錄對象,而/a/
或/a/b/
目錄對象實際並不存在。同理,如上傳/a/*
檔案,/a/b
、/a/c
等為單獨的檔案對象,/a/
目錄對象不存在。原因2:AccessKey或RRSA使用的角色資訊填寫錯誤或許可權不足導致掛載失敗。
原因3:CSI版本在1.30.4及以上時,OSSFS所在的Pod運行在
ack-csi-fuse
命名空間中。掛載時CSI將先拉起OSSFS所在的Pod,再通過RPC請求實際啟動Pod中的OSSFS進程。若Event的內容中包含FailedMount /run/fuse.ossfs/xxxxxx/mounter.sock: connect: no such file or directory
,則掛載失敗是因為OSSFS所在Pod未正常拉起或被意外刪除。原因4:若Event的內容中包含
Failed to find executable /usr/local/bin/ossfs: No such file or directory
,則掛載失敗是因為OSSFS在節點上安裝失敗。原因5:若Event的內容中包含
error while loading shared libraries: xxxxx: cannot open shared object file: No such file or directory
,掛載失敗的原因為當前CSI版本ossfs直接運行在節點上,且作業系統缺乏部分ossfs運行所需的動態庫。以下情況都可能導致該報錯:手動在節點安裝過其他版本的ossfs工具,且適配的作業系統與當前節點不一致。
節點作業系統版本升級導致OpenSSL預設版本變更,例如Alibaba Cloud Linux 2升級至Alibaba Cloud Linux 3。
ossfs運行在節點上時,不支援CentOS、Alibaba Cloud Linux、ContainerOS和龍蜥以外的作業系統。
在符合作業系統要求的節點上刪除過預設的FUSE、cURL、xml2等ossfs運行需要的動態庫,或變更過OpenSSL的預設版本。
原因6:Bucket配置了鏡像回源,掛載目錄未從來源站點同步。
原因7:Bucket配置了靜態網站託管,ossfs檢查OSS端掛載目錄時,請求轉寄到index.html等檔案中。
解決方案
原因1解決方案:
檢查子路徑在OSS Server端是否存在。
假設PV的掛載路徑為
sub/path/
,您可以使用stat(查看Bucket和Object資訊)查詢objectname
為sub/path/
的對象,或使用openapi HeadObject查詢key
為sub/path/
的對象。若返回為404,確認Server端不存在該子路徑。您可以通過ossutil、SDK、OSS控制台等工具手動建立缺失的Bucket或子目錄,然後重新掛載。
ossfs1.91+版本不強制要求掛載目錄存在,您也可以通過升級ossfs版本解決該問題。更多資訊,請參見ossfs 1.91及以上版本新功能介紹及效能壓測。
原因2解決方案:
確認掛載使用的RAM使用者或RAM角色的策略許可權包括步驟二:為demo-role-for-rrsa角色授權中列舉的許可權。
確認掛載點根路徑及subpath路徑的檔案系統許可權,詳情請參考OSS儲存掛載許可權問題中的情境1和情境6。
對於通過RAM使用者AccessKey鑒權方式掛載的儲存卷,確認掛載時使用的AccessKey是否被禁用或已輪轉,詳情請參考OSS儲存掛載許可權問題中的情境4.
對於通過RRSA鑒權方式掛載的儲存卷,確認是否為RAM角色配置正確的信任策略。信任策略的配置請參考(可選)步驟一:建立RAM角色。預設情況下,信任的ServiceAccount為ack-csi-fuse命名空間下的csi-fuse-ossfs,而非業務使用的ServiceAccount。
說明RRSA功能目前僅支援1.26及以上版本的叢集,即ACK叢集基礎版、ACK叢集Pro版、ACK Serverless叢集基礎版和ACK Serverless叢集Pro版,且叢集使用的CSI組件版本為1.30.4及以上版本。若您在1.30.4版本之前使用了RRSA功能,請儘快參考【產品變更】CSI ossfs版本升級與掛載流程最佳化增加RAM角色授權配置。
原因3解決方案:
執行以下命令,確認OSSFS所在Pod存在。其中
PV_NAME
為掛載的OSS PV名稱,NODE_NAME
為需掛載儲存卷的業務Pod所在的節點名稱。kubectl -n ack-csi-fuse get pod -l csi.alibabacloud.com/volume-id=<PV_NAME> -owide | grep <NODE_NAME>
若Pod存在且狀態異常,請排查Pod的異常原因,確保Pod正常Running後重啟業務Pod觸發重新掛載。若Pod不存在,請按後續步驟繼續排查。
(可選)通過查詢審計日誌等方式確認Pod是否被意外刪除,常見的意外刪除原因包括業務指令碼清理、節點排水、節點自愈等。建議您做相關調整,避免問題重現。
確認CSI provisioner與CSI plugin均升級到1.30.4及以上後,重啟業務Pod觸發重新掛載,並確認OSSFS Pod有正常建立流程。
原因4解決方案:
建議您將csi-plugin版本升級到v1.26.2或以上版本,該版本修複了剛擴容出的節點初始化時,ossfs安裝失敗的問題。
執行以下命令,嘗試重啟對應節點上的csi-plugin後,查看Pod是否能正常啟動。以下代碼中
csi-plugin-****
為節點所在csi-plugin的Pod名稱。kubectl -n kube-system delete pod csi-plugin-****
若升級或重啟組件後,問題仍無法解決,請登入節點,執行以下命令。
ls /etc/csi-tool
部分預期輸出:
... ossfs_<ossfsVer>_<ossfsArch>_x86_64.rpm ...
若輸出中存在OSSFS的RPM包,則執行以下命令,查看Pod是否能正常啟動。
rpm -i /etc/csi-tool/ossfs_<ossfsVer>_<ossfsArch>_x86_64.rpm
若輸出中不存在OSSFS的RPM包,請提交工單處理。
原因5解決方案:
若您手動安裝過ossfs工具,請檢查適配的作業系統與節點是否一致。
若您升級過叢集的節點作業系統,可以執行以下指令重啟csi-plugin,更新ossfs版本後再嘗試掛載。
kubectl -n kube-system delete pod -l app=csi-plugin
建議您升級CSI至1.28或以上版本,掛載OSS儲存卷時ossfs以容器的方式運行在叢集中,對節點作業系統無要求。
若您的叢集無法升級CSI版本,可以切換至符合要求的OS或手動安裝缺少的動態庫,以Ubuntu節點為例:
使用which指令,查詢當前ossfs的安裝位置(預設安裝路徑為
/usr/local/bin/ossfs
)。which ossfs
使用ldd指令,查詢ossfs缺失的動態庫檔案。
ldd /usr/local/bin/ossfs
使用apt-file指令,查詢缺失的動態庫檔案(如libcrypto.so.10)所屬的Package。
apt-get install apt-file apt-file update apt-file search libcrypto.so.10
使用apt-get指令安裝對應Package(如libssl.1.0.0)。
apt-get install libssl1.0.0
原因6解決方案:
您需要同步來源站點資料後,再進行掛載。更多資訊,請參見回源概述。
原因7解決方案:
您需要關閉或調整靜態網站託管的配置,再進行掛載。更多資訊,請參見靜態網站託管概述。
OSS靜態卷訪問Bucket失敗
問題現象
OSS靜態卷訪問Bucket失敗。
問題原因
使用OSS待用資料卷時,沒有填寫AK/SK資訊。
解決方案
您需要填寫AK/SK作為OSS靜態卷訪問Bucket的憑證。具體操作,請參見使用OSS靜態儲存卷。
OSS靜態卷訪問Bucket過慢
問題現象
OSS靜態卷訪問Bucket過慢。
問題原因
原因1:OSSObject Storage Service本身沒有檔案數限制,但當檔案數量大於1000時,會使OSS的FUSE訪問中繼資料過多,導致Bucket訪問過慢。
原因2:OSS開啟版本控制後,當Bucket中存在大量刪除標記時,listObjectsV1效能下降。
原因3:OSS服務端設定儲存類型為標準儲存(Standard)以外的儲存,其他儲存類型將不同程度地降低資料訪問的效能。
解決方案
原因1解決方案:
容器內掛載OSS時,建議以唯讀形式訪問Bucket,針對大量平鋪對象,可採用OSS SDK方式或CLI方式等非檔案系統掛載方式,訪問Bucket的資料。更多資訊,請參見SDK樣本簡介。
原因2解決方案:
將CSI plugin組件版本升級至v1.26.6後,ossfs可支援通過listObjectsV2訪問Bucket。
在OSS靜態卷PV的
otherOpts
欄位中增加-o listobjectsv2
來解決。
原因3解決方案:
您需要修改儲存類型或者解凍檔案。
OSS控制台看到檔案大小為0
問題現象
容器內掛載OSS資料卷時,在檔案中寫入資料,但在OSS控制台看到檔案大小為0。
問題原因
容器使用ossfs掛載OSS,即基於FUSE方式掛載OSS的Bucket,只有在檔案執行close或者flush時,檔案內容才會上傳至OSS的服務端。
解決方案
使用lsof+檔案名稱的方式,查看當前檔案是否被其他進程佔用,關閉相應進程,釋放檔案fd。關於lsof更多資訊,請參見lsof。
檔案目錄掛載後,顯示為檔案對象
問題現象
容器內掛載OSS資料卷時,檔案原本是目錄,掛載後,顯示為檔案對象。
問題原因
原因1:目錄對象在OSS服務端content-type類型是非預設的application/octet-stream
類型(例如text/html, image/jpeg等),或目錄對象的大小非0,ossfs根據其元資訊將其視為相應的檔案對象。
原因2:非原因1的情況,但目錄對象缺少元資訊x-oss-meta-mode
。
解決方案
原因1解決方案:
通過HeadObject或stat(查看Bucket和Object資訊)擷取目錄對象元資訊,目錄對象需要以"/"
結尾(例如a/b/
),以API返回為例。
{
"server": "AliyunOSS",
"date": "Wed, 06 Mar 2024 02:48:16 GMT",
"content-type": "application/octet-stream",
"content-length": "0",
"connection": "keep-alive",
"x-oss-request-id": "65E7D970946A0030334xxxxx",
"accept-ranges": "bytes",
"etag": "\"D41D8CD98F00B204E9800998ECFxxxxx\"",
"last-modified": "Wed, 06 Mar 2024 02:39:19 GMT",
"x-oss-object-type": "Normal",
"x-oss-hash-crc6xxxxx": "0",
"x-oss-storage-class": "Standard",
"content-md5": "1B2M2Y8AsgTpgAmY7Phxxxxx",
"x-oss-server-time": "17"
}
以上返回樣本中:
content-type
:為application/octet-stream
,即目錄對象為application/octet-stream類型。content-length
:為0,即目錄對象大小為0。
若不滿足以上條件,您可以通過以下方式修複:
通過GetObject或命令列工具ossutil快速入門擷取該對象,確認資料是否有用。若資料有用或不能確定,建議對其進行備份,例如變更名稱(對
xx/
目錄對象,請勿使用xx
作為新的名稱)後上傳至OSS。通過DeleteObject或rm(刪除)刪除有問題的目錄對象,然後確認ossfs是否正常顯示目錄。
原因2解決方案:
若通過原因1的解決方案未修複問題,您可以在容器內掛載OSS資料卷時,在OSS靜態卷PV的otherOpts
欄位中增加-o complement_stat
來解決。
CSI plugin組件版本為v1.26.6及以上版本時,配置項已預設開啟,您可以將儲存群組件升級至v1.26.6或以上版本,重啟業務Pod並重新掛載OSS靜態卷解決。
OSS服務端監控到大量異常請求流量
問題現象
在容器內掛載OSS資料卷時,OSS服務端監控到請求數量遠超出業務預期產生量。
問題原因
通過ossfs掛載OSSObject Storage Service時,將在節點上產生掛載路徑,ECS上的其他進程對掛載點的掃描也會轉換為向OSS的請求。如果請求次數很多,會產生費用。
解決方案
通過審計追蹤產生請求的進程,並進行相應修複。您可以在節點上進行如下操作。
執行以下命令,安裝auditd並啟動。
sudo yum install auditd sudo service auditd start
將對ossfs掛載路徑設為監測目錄。
如需添加所有掛載路徑,請執行以下命令。
for i in $(mount | grep -i ossfs | awk '{print $3}');do auditctl -w ${i};done
如需添加某個PV的掛載路徑,請執行以下命令。其中,
<pv-name>
為指定的PV名稱。for i in $(mount | grep -i ossfs | grep -i <pv-name> | awk '{print $3}');do auditctl -w ${i};done
通過以下命令,在auditlog中查看存在哪些進程訪問了OSS Bucket中的路徑。
ausearch -i
審計日誌分析樣本如下。以下樣本中,
---
分隔字元間的審計日誌為一組,記錄對監控掛載點的單次操作。該樣本表示updatedb
進程對掛載點中的子目錄進行了open
的操作,進程PID為1636611。--- type=PROCTITLE msg=audit(2023年09月22日 15:09:26.244:291) : proctitle=updatedb type=PATH msg=audit(2023年09月22日 15:09:26.244:291) : item=0 name=. inode=14 dev=00:153 mode=dir,755 ouid=root ogid=root rdev=00:00 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 type=CWD msg=audit(2023年09月22日 15:09:26.244:291) : cwd=/subdir1/subdir2 type=SYSCALL msg=audit(2023年09月22日 15:09:26.244:291) : arch=x86_64 syscall=open success=yes exit=9 a0=0x55f9f59da74e a1=O_RDONLY|O_DIRECTORY|O_NOATIME a2=0x7fff78c34f40 a3=0x0 items=1 ppid=1581119 pid=1636611 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts1 ses=1355 comm=updatedb exe=/usr/bin/updatedb key=(null) ---
藉助日誌進一步確認是否存在非業務的進程調用,並進行修複。
例如,通過auditlog查到updatedb掃描了所掛載的目錄,可以通過修改
/etc/updatedb.conf
讓它跳過。具體操作如下。在
RUNEFS =
後面加上fuse.ossfs
。在
PRUNEPATHS =
後面加上掛載的目錄。
通過OSS儲存卷寫入的檔案對象的中繼資料Content-Type全為application/octet-stream類型
問題現象
通過OSS儲存卷寫入的檔案對象的中繼資料Content-Type全為application/octet-stream類型,導致瀏覽器或其他用戶端未能夠正確識別和處理這些檔案。
問題原因
未指定Content-Type類型,ossfs預設將檔案對象視為二進位流檔案。
通過/etc/mime.types設定檔指定Content-Type類型,但未生效。
解決方案
確認CSI組件版本,1.26.6和1.28.1版本的組件對Content-Type配置存在相容性問題。若使用了相關版本,請升級CSI至最新版本。更多資訊,請參見【組件公告】關於1.26.6和1.28.1版本的csi-plugin和csi-provisioner組件相容性問題。
若您已經通過使用
mailcap
、mime-support
在節點上產生/etc/mime.types
的方式指定Content-Type類型,升級CSI版本後,重新掛載對應OSS儲存卷即可。若您未指定Content-Type類型,可通過以下兩種方式指定:
節點層級配置:在節點上產生
/etc/mime.types
設定檔,對所有新掛載到該節點上的OSS儲存卷生效。更多資訊,請參見常見問題。叢集層級配置:該方式對叢集所有新掛載的OSS儲存卷生效,
/etc/mime.types
內容與mailcap
預設產生的內容一致。執行以下命令,檢查csi-plugin設定檔是否存在。
kubectl -n kube-system get cm csi-plugin
若不存在,使用以下內容,建立csi-plugin同名ConfigMap;若不存在,則需要在原ConfigMap中增加
data.fuse-ossfs
中的內容mime-support="true"
。apiVersion: v1 kind: ConfigMap metadata: name: csi-plugin namespace: kube-system data: fuse-ossfs: | mime-support=true
重啟csi-plugin,使配置生效,重啟csi-plugin不會影響當前已經成功掛載的儲存卷的使用。
kubectl -n kube-system delete pod -l app=csi-plugin
重新掛載對應的OSS儲存卷。
如何在RRSA鑒權方式中使用指定的ARNs或ServiceAccount?
通過RRSA方式的OSS儲存卷鑒權時,無法滿足例如使用第三方OIDC身份供應商、使用非預設ServiceAccount等需求。
此時,您只需要在PV中通過roleName配置項指定RAM角色名稱,即可由CSI儲存外掛程式擷取預設的Role ARN及OIDC Provider ARN。若您需要實現定製化的RRSA鑒權,則需要更改PV的配置資訊如下:
其中,roleArn
與oidcProviderArn
需要一起配置,配置後無需再配置roleName
。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-oss
spec:
capacity:
storage: 5Gi
accessModes:
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
csi:
driver: ossplugin.csi.alibabacloud.com
volumeHandle: pv-oss # 需要和PV名字一致。
volumeAttributes:
bucket: "oss"
url: "oss-cn-hangzhou.aliyuncs.com"
otherOpts: "-o umask=022 -o max_stat_cache_size=0 -o allow_other"
authType: "rrsa"
oidcProviderArn: "<oidc-provider-arn>"
roleArn: "<role-arn>"
#roleName: "<role-name>" #配置roleArn和oidcProviderArn後,roleName失效。
serviceAccountName: "csi-fuse-<service-account-name>"
參數 | 說明 |
oidcProviderArn | OidcProviderArn需要在建立OIDC身份供應商後擷取。更多資訊,請參見管理OIDC身份供應商。 |
roleArn | RoleArn需要在建立可信實體為上述OIDC身份供應商的RAM角色後擷取。更多資訊,請參見使用OIDC進行角色SSO的樣本。 |
serviceAccountName | 可選,ossfs容器所在的Pod使用ServiceAccount名稱,需要預先建立。 配置為空白時,使用CSI維護的預設ServiceAccount。 重要 ServiceAccount名稱必須以csi-fuse-開頭。 |
建立永久連結時返回錯誤Operation not supported或Operation not permitted
問題現象
建立永久連結時返回錯誤Operation not supported或Operation not permitted。
問題原因
OSS儲存卷不支援永久連結操作,將返回Operation not supported錯誤。在早期的CSI版本中,永久連結操作返回的報錯為Operation not permitted。
解決方案
改造業務,在使用OSS儲存卷時,應避免永久連結操作。若您的業務必須使用永久連結操作,建議您更換儲存。
OSS靜態卷卸載失敗,Pod一直處於Terminating狀態
問題現象
OSS靜態卷卸載失敗,Pod一直處於Terminating狀態。
問題原因
Pod刪除時卡在Terminating的原因較多,可先藉助kubelet日誌定位。導致OSS儲存卷卸載失敗的常見原因如下:
原因1:對應掛載點在節點上被佔用,CSI儲存外掛程式無法正常unmount掛載點。
原因2:PV中指定的OSS bucket或目錄(path)被刪除,無法判斷當前掛載點狀態。
解決方案
原因1解決方案
在叢集中執行以下命令,擷取Pod的UID。
替換以下<ns-name>和<pod-name>為您的業務實際值。
kubectl -n <ns-name> get pod <pod-name> -ogo-template --template='{{.metadata.uid}}'
預期輸出:
5fe0408b-e34a-497f-a302-f77049****
登入Terminating的Pod所在的節點。
在節點上執行以下命令,查詢當前是否有進程佔用掛載點。
lsof /var/lib/kubelet/pods/<pod-uid>/volumes/kubernetes.io~csi/<pv-name>/mount/
若有輸出,請確認並清理相關進程。
原因2解決方案
登入OSS管理主控台。
查詢Bucket或目錄是否被刪,若您使用了subpath方式掛載OSS儲存卷,還需要確認subpath掛載目錄是否被刪除。
確認上由於刪除目錄導致的卸載失敗,請參考以下操作處理。
在叢集中執行以下命令,擷取Pod的UID。
替換以下<ns-name>和<pod-name>為您的業務實際值。
kubectl -n <ns-name> get pod <pod-name> -ogo-template --template='{{.metadata.uid}}'
預期輸出:
5fe0408b-e34a-497f-a302-f77049****
登入Terminating的Pod所在的節點,在節點上執行以下命令,查詢Pod相關的掛載點。
mount | grep <pod-uid> | grep fuse.ossfs
預期輸出:
ossfs on /var/lib/kubelet/pods/<pod-uid>/volumes/kubernetes.io~csi/<pv-name>/mount type fuse.ossfs (ro,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other) ossfs on /var/lib/kubelet/pods/<pod-uid>/volume-subpaths/<pv-name>/<container-name>/0 type fuse.ossfs (ro,relatime,user_id=0,group_id=0,allow_other)
其中
ossfs on
與type
之間路徑為節點上的實際掛載點。手動umount掛載點。
umount /var/lib/kubelet/pods/<pod-uid>/volumes/kubernetes.io~csi/<pv-name>/mount umount /var/lib/kubelet/pods/<pod-uid>/volume-subpaths/<pv-name>/<container-name>/0
等待kubelet重試時正常回收,或者直接通過
--force
刪除Pod。
其他卸載失敗問題,請提交工單諮詢。
控制台檢測長期卡住,或失敗無資訊透出,或顯示unknown error
問題現象
檢測長期卡住,或失敗無資訊透出,或顯示unknown error。
問題原因
若檢測長期卡在進行中狀態,基本判斷為網路原因。對於其他未知錯誤,您可以通過查詢日誌,或手動通過ossutil進行原因定位。
解決方案
您可以通過日誌和ossutil工具定位具體問題。
通過日誌定位具體問題
執行以下命令,找到執行檢測任務的Pod。
osssecret-namespace
:保密字典所在命名空間。pv-name
:PV的名稱。
kubectl -n <osssecret-namespace> get pod | grep <pv-name>-check
預期輸出:
<pv-name>-check-xxxxx
執行以下命令,查詢失敗原因。
kubectl -n <osssecret-namespace> logs -f <pv-name>-check-xxxxx
預期輸出:
check ossutil endpoint: oss-<region-id>-internal.aliyuncs.com bucket: <bucket-name> path: <path> Error: oss: service returned error: StatusCode=403, ErrorCode=InvalidAccessKeyId, ErrorMessage="The OSS Access Key Id you provided does not exist in our records.", RequestId=65267325110A0C3130B7071C, Ec=0002-00000901, Bucket=<bucket-name>, Object=<path>
通過ossutil工具定位具體問題
如果您的相關Pod已被刪除,您可以通過ossutil工具複現檢測,定位具體問題。
OSS訪問檢測通過stat(查看Bucket和Object資訊)實現,您可以在叢集內任意節點上安裝ossutil並執行以下指令複現。
ossutil -e "<endpoint>" -i "<accessKeyID>" -k "<accessKeySecret>" stat oss://"<bucket><path>"
參數 | 說明 |
endpoint |
|
accessKeyID | 保密字典中的AccessKeyID。 |
accessKeySecret | 保密字典中的AccessKeySecret。 |
bucket | Bucket ID。 |
path | 路徑。填寫的路徑需要以 |
例如,如果您在建立如下的儲存卷的配置資訊,則您需要執行的命令如下。
ossutil -e "oss-<region-id>-internal.aliyuncs.com" -i "<accessKeyID>" -k "<accessKeySecret>" stat oss://"cnfs-oss-xxx-xxx/xx/"
網路問題:connection timed out
問題現象
錯誤資訊為connection timed out。
問題原因
訪問OSS Bucket逾時,可能的逾時原因如下
選擇的Bucket與叢集不在同一地區時,選擇私人網域名稱,導致訪問不通。
選擇公有網域名稱,但叢集無公網訪問能力,導致訪問不通。
解決方案
重建PV,並選擇公有網域名稱。
若您的叢集與Bucket在同一地區,可重建PV並選擇私人網域名稱。否則,您可以檢查安全性群組、網路等相關配置,修複後再重建PV。
許可權問題:錯誤碼StatusCode=403
問題現象
錯誤資訊為service returned error: StatusCode=403
。
問題原因
掛載OSS儲存卷時,AccessKey至少需要Bucket的讀許可權,當前許可權不足。
StatusCode=403, ErrorCode=AccessDenied, ErrorMessage="You do not have read acl permission on this object."
,提供的AccessKey許可權不足。StatusCode=403, ErrorCode=InvalidAccessKeyId, ErrorMessage="The OSS Access Key Id you provided does not exist in our records."
,提供的AccessKey不存在。StatusCode=403, ErrorCode=SignatureDoesNotMatch, ErrorMessage="The request signature we calculated does not match the signature you provided. Check your key and signing method."
,提供的AccessKey可能存在拼字錯誤。
解決方案
確認AccessKey已存在、無拼字錯誤,且至少擁有對該Bucket的讀許可權。
Bucket或目錄對象不存在:錯誤碼StatusCode=404
問題現象
錯誤資訊為service returned error: StatusCode=404
。
問題原因
OSS靜態儲存卷不支援掛載到不存在的Bucket或子目錄中,需要預先手動建立Bucket。
StatusCode=404, ErrorCode=NoSuchBucket, ErrorMessage="The specified bucket does not exist."
,選擇的Bucket不存在。StatusCode=404, ErrorCode=NoSuchKey, ErrorMessage="The specified key does not exist."
,選擇的子目錄對象不存在。重要OSS控制台中可見的子路徑在Server端不一定真實存在,以ossutil或OSS API的返回為準。例如,直接建立
/a/b/c/
目錄,/a/b/c/
為單獨的目錄對象,而/a/
或/a/b/
目錄對象實際並不存在。同理,如上傳/a/*
檔案,/a/b
、/a/c
等為單獨的檔案對象,/a/
目錄對象不存在。
解決方案
通過ossutil、SDK、OSS控制台等工具手動建立缺失的Bucket或子目錄,然後重建PV。
其他OSS返回錯誤碼
問題現象
錯誤資訊為service returned error: StatusCode=xxx
。
問題原因
當訪問OSS出現錯誤時,OSS會返回StatusCode、ErrorCode、ErrorMessage等資訊,方便您定位並解決問題。
解決方案
當您遇到其他OSS的StatusCode或ErrorCode時,請參見HTTP錯誤碼解決。
ossfs容器化後如何開啟獨享掛載模式?
問題現象
同一節點上掛載了相同OSS儲存卷的多個Pod共用掛載點。
問題原因
ossfs容器化前,預設使用獨享方式掛載,即每個掛載OSS儲存卷的Pod,都將在對應節點上為該儲存卷拉起ossfs進程。不同ossfs進程對應的掛載點之間完全獨立,即對於掛載了同一OSS儲存卷的不同Pod在讀寫時互不影響。
ossfs容器化後,ossfs進程將以容器的方式運行在叢集的Pod中,具體為kube-system
或ack-csi-fuse
命名空間的csi-fuse-ossfs-*
Pod。在多掛載的情境下,獨享方式掛載將在叢集中拉起大量Pod,進而導致彈性網卡不足等問題。因此,容器化後將預設使用共用方式掛載,即同一節點上掛載了相同OSS儲存卷的多個Pod共用掛載點,均對應同一個csi-fuse-ossfs-*
Pod,實際由同一ossfs進程實現掛載。
解決方案
1.30.4及以上版本CSI不再支援開啟獨享掛載模式,如果您需要重啟或變更ossfs的相關配置,可以參考共用掛載方式下,如何重啟ossfs進程?如果您有其他ossfs獨享掛載的需求,請提交工單。
如果您期望恢複到容器化前的獨享掛載,請在建立OSS儲存卷時增加useSharedPath
配置項,並將其設為"false"
。樣本如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: oss-pv
spec:
accessModes:
- ReadOnlyMany
capacity:
storage: 5Gi
csi:
driver: ossplugin.csi.alibabacloud.com
nodePublishSecretRef:
name: oss-secret
namespace: default
volumeAttributes:
bucket: bucket-name
otherOpts: -o max_stat_cache_size=0 -o allow_other
url: oss-cn-zhangjiakou.aliyuncs.com
useSharedPath: "false"
volumeHandle: oss-pv
persistentVolumeReclaimPolicy: Delete
volumeMode: Filesystem
共用掛載方式下,如何重啟ossfs進程?
問題現象
修改鑒權資訊或ossfs版本後,已經在啟動並執行ossfs進程無法自動變更。
問題原因
ossfs運行後無法變更鑒權資訊等配置,變更配置後,需要重啟ossfs進程(容器化版本後,即為
kube-system
或ack-csi-fuse
命名空間下的csi-fuse-ossfs-*
Pod)與對應的應用Pod,造成業務中斷。因此,預設情況下CSI不會對已經啟動並執行ossfs進行變更。正常使用流程中,ossfs的部署與刪除均由CSI完成。手動刪除ossfs進程所在的Pod,無法觸發CSI的部署流程。
解決方案
重啟ossfs進程的流程中需要重啟掛載對應OSS儲存卷的業務Pod,請謹慎操作。
若您使用的是非容器化的CSI版本,或開啟了獨享掛載,可以直接重啟對應的應用Pod。容器化版本後,預設使用共用掛載方式,即每個節點上掛載同一OSS儲存卷的所有應用Pod共用ossfs進程實現掛載。
確認當前FUSE Pod被哪些應用Pod使用。
執行以下命令,確認需要變更的
csi-fuse-ossfs-*
Pod。其中
<pv-name>
為PV名稱,<node-name>
為節點名稱。CSI版本小於1.30.4時,執行以下操作:
kubectl -n kube-system get pod -lcsi.alibabacloud.com/volume-id=<pv-name> -owide | grep <node-name>
CSI版本大於等於1.30.4時,執行以下操作
kubectl -n ack-csi-fuse get pod -lcsi.alibabacloud.com/volume-id=<pv-name> -owide | grep <node-name>
預期輸出:
csi-fuse-ossfs-xxxx 1/1 Running 0 10d 192.168.128.244 cn-beijing.192.168.XX.XX <none> <none>
執行以下命令,確認正在掛載該OSS儲存卷的所有Pod。
其中
<ns>
為命名空間名稱,<pvc-name>
為PVC名稱。kubectl -n <ns> describe pvc <pvc-name>
預期輸出(包含User By):
Used By: oss-static-94849f647-4**** oss-static-94849f647-6**** oss-static-94849f647-h**** oss-static-94849f647-v**** oss-static-94849f647-x****
執行以下命令,擷取通過
csi-fuse-ossfs-xxxx
掛載的Pod,即與csi-fuse-ossfs-xxxx運行在同一節點的Pod。kubectl -n <ns> get pod -owide | grep cn-beijing.192.168.XX.XX
預期輸出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES oss-static-94849f647-4**** 1/1 Running 0 10d 192.168.100.11 cn-beijing.192.168.100.3 <none> <none> oss-static-94849f647-6**** 1/1 Running 0 7m36s 192.168.100.18 cn-beijing.192.168.100.3 <none> <none>
重啟業務與ossfs進程。
將應用Pod(上述樣本中為oss-static-94849f647-4****和oss-static-94849f647-6****)通過
kubectl scale
等方式同時刪除。在無應用Pod掛載時,csi-fuse-ossfs-xxxx
Pod將自動被回收;恢複副本數後,將使用PV的新配置重新掛載,由CSI建立新的csi-fuse-ossfs-yyyy
Pod。如果無法保證這些Pod能同時被刪除(如刪除Deployment, StatefulSet, DaemonSet管理的Pod均會立即觸發重啟),或Pod能容忍OSS讀寫失敗:
CSI版本小於1.30.4時,您可以直接刪除
csi-fuse-ossfs-xxxx
Pod,此時應用Pod內讀寫OSS將返回disconnected error
。CSI版本大於等於1.30.4時,您可以執行以下操作:
kubectl get volumeattachment | grep <pv-name> | grep cn-beijing.192.168.XX.XX
預期輸出:
csi-bd463c719189f858c2394608da7feb5af8f181704b77a46bbc219b********** ossplugin.csi.alibabacloud.com <pv-name> cn-beijing.192.168.XX.XX true 12m
直接刪除該VolumeAttachment,此時應用Pod內讀寫OSS將返回
disconnected error
。
然後,逐個重啟業務Pod,重啟後的Pod將通過CSI建立的
csi-fuse-ossfs-yyyy
Pod恢複OSS讀寫。
如何查看通過OSS儲存卷訪問OSS的記錄?
調用OSS的操作記錄統一在OSS管理主控台查看,且要求已開通OSS的日誌查詢功能。關於開通日誌查詢的操作,請參見開通即時日誌查詢。
登入OSS管理主控台。
單擊Bucket 列表,然後單擊目標Bucket名稱。
在左側導覽列,選擇
。在即時查詢頁簽下,根據查詢文法和分析文法,輸入查詢和分析語句,對OSS日誌進行分析。您可以通過user_agent和client_ip欄位定位日誌是否來源於ACK。
定位由ACK發送的OSS操作請求時,您需要選擇user_agent欄位,展開後看到user_agent裡包含ossfs的都可以選擇。
重要user-agent欄位的取值與ossfs版本有關,ossfs版本不同,user-agent欄位的值也不一樣,但均以
aliyun-sdk-http/1.0()/ossfs
開頭。如果您在ECS上也通過ossfs掛載,相關日誌也會被耦合到這裡。
如需定位到某個ECS執行個體或叢集,您還可以選擇client_ip欄位,然後選擇對應的IP。
結合以上兩個欄位選擇,查詢到的日誌樣本如下圖所示。
日誌查詢部分欄位說明
欄位 | 說明 |
operation | 對OSS操作的類型。例如GetObject、GetBucketStat等。更多資訊,請參見API概覽。 |
object | 對象名稱,OSS中的目錄、檔案。 |
request_id | 請求的唯一標識,如果有請求ID,您可以精確查詢某個請求。 |
http_status、error_code | 針對請求結果的查詢。更多資訊,請參見HTTP錯誤碼。 |
使用subpath或subpathExpr方式掛載OSS儲存卷異常
問題現象
使用subpath或subpathExpr方式掛載OSS儲存卷時,出現以下異常:
掛載失敗:掛載OSS儲存卷的Pod建立後,一直處在CreateContainerConfigError狀態,並且出現如下類似Event。
Warning Failed 10s (x8 over 97s) kubelet Error: failed to create subPath directory for volumeMount "pvc-oss" of container "nginx"
讀寫異常:掛載OSS儲存卷進行OSS讀寫操作時,出現許可權不足的報錯提示
Operation not permitted
或Permission denied
。卸載失敗:刪除掛載了OSS儲存卷的Pod時,一直處在Terminating狀態。
問題原因
為方便闡述原因及解決方案,假設:
PV的相關配置為:
...
volumeAttributes:
bucket: bucket-name
path: /path
...
Pod的相關配置為:
...
volumeMounts:
- mountPath: /path/in/container
name: oss-pvc
subPath: subpath/in/oss
...
則OSS服務端subpath掛載目錄為Bucket中的/path/subpath/in/oss/
。
原因1:OSS服務端不存在掛載目錄
/path/subpath/in/oss/
,且OSS儲存卷使用的使用者或角色未被授權PutObject許可權(例如唯讀情境中僅配置了OSS ReadOnly許可權)。kubelet嘗試在OSS服務端建立
/path/subpath/in/oss/
目錄時因許可權不足失敗。原因2:非root使用者啟動並執行業務容器沒有
/path/subpath/in/oss/
目錄下檔案的許可權(預設為640)。subpath方式掛載OSS儲存卷時,ossfs在OSS服務端實際的掛載目錄為PV中定義的path目錄,即上述樣本中的/path
,而非/path/subpath/in/oss/
。配置allow_other或mp_umask掛載項僅對/path
目錄生效,/path/subpath/in/oss/
目錄作為子目錄仍預設為640。原因3:OSS服務端中
/path/subpath/in/oss/
掛載目錄被刪除,阻塞kubelet回收subpath路徑,導致卸載失敗。
解決方案
原因1解決方案:
在OSS服務端預先建立
/path/subpath/in/oss/
目錄,提供kubelet掛載subpath路徑。若需要建立的目錄較多(例如通過subpathExpr方式掛載OSS儲存卷),無法全部預先建立時,可為OSS儲存卷使用的使用者或角色增加putObject許可權授權。
原因2解決方案:通過umask配置項修改子目錄預設許可權,例如-o umask=000
將預設許可權修改為777。
原因3解決方案:請參見OSS靜態卷卸載失敗,Pod一直處於Terminating狀態中的原因2解決方案。
OSS儲存卷的容量配置是否生效?實際儲存超出此配置時是否需要擴容儲存卷?
OSS本身不限制Bucket或子路徑的容量,也未提供容量限額功能。因此pv.spec.capacity
與pvc.spec.resources.requests.storage
配置均不起作用。您只需保證需要綁定PV、PVC配置的容量相等即可。
實際儲存超出此配置時,不影響正常使用,也無需擴容儲存卷。