全部產品
Search
文件中心

Container Service for Kubernetes:OSS儲存卷FAQ

更新時間:Sep 03, 2024

本文為您介紹OSS儲存卷常見問題的處理方法。

類型

問題

掛載問題

使用問題

卸載問題

OSS靜態卷卸載失敗,Pod一直處於Terminating狀態

控制台檢測失敗問題

其他

OSS儲存卷掛載時間延長

問題現象

OSS儲存卷掛載時間延長。

問題原因

同時滿足以下配置,kubelet在儲存卷掛載過程中將執行chmodchown操作,導致掛載時間延長。

  • 在PV及PVC模板中配置的參數AccessModes值為ReadWriteOnce

  • 在應用模板中配置了securityContext.fsgroup參數。

解決方案

  • 若應用模板中配置了securityContext.fsgroup參數,請刪除securityContext下的fsgroup參數。

  • 若需要將掛載目錄內檔案變成期望的UID和mode,可以手動將Bucket掛載到一台ECS。再通過命令列執行chownchmod,完成後通過CSI使用OSS儲存卷。關於如何通過CSI使用OSS儲存卷,請參見使用OSS靜態儲存卷

  • 對於1.20及之後版本的Kubernetes叢集,除了上述兩種解決方案外,也可通過將fsGroupChangePolicy配置為OnRootMismatch,這時只有在初次開機時才會執行chmodchown操作,導致存在掛載時間延長的問題,後續掛載OSS儲存卷時掛載時間將恢複正常。關於fsGroupChangePolicy參數的更多資訊,請參見為Pod或容器配置資訊安全內容

  • ossfs PVC不建議進行寫操作,預設唯讀。

OSS儲存掛載許可權問題

當您在以下幾種情境中進行操作時,出現錯誤提示Permission Denied

情境1:訪問掛載目錄時,出現錯誤提示Permission Denied

問題原因

OSS預設使用Linux的root使用者進行掛載,許可權為700。當容器進程以非root使用者運行時,許可權不足。

解決方案

通過增加配置項修改掛載根目錄的許可權。

參數

說明

allow_other

設定掛載目錄的許可權為777。

mp_umask

用於設定掛載目錄的許可權掩碼,只有當allow_other選項設定後,該選項才生效。預設值為000。例如:

  • 需設定掛載目錄的許可權為770,則增加-o allow_other -o mp_umask=007

  • 需設定掛載目錄的許可權為700,則增加-o allow_other -o mp_umask=077

情境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.runAsUsersecurityContext.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重掛載?

情境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:若Event的內容中包含Failed to find executable /usr/local/bin/ossfs: No such file or directory時,則掛載失敗是因為OSSFS在節點上安裝失敗。

  • 原因4:若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的預設版本。

  • 原因5:Bucket配置了鏡像回源,掛載目錄未從來源站點同步。

  • 原因6:Bucket配置了靜態網站託管,ossfs檢查OSS端掛載目錄時,請求轉寄到index.html等檔案中。

解決方案

  • 原因1解決方案:

    檢查子路徑在OSS Server端是否存在。

    假設PV的掛載路徑為sub/path/,您可以使用stat(查看Bucket和Object資訊)查詢objectnamesub/path/的對象,或使用openapi HeadObject查詢keysub/path/的對象。若返回為404,確認Server端不存在該子路徑。

    1. 您可以通過ossutil、SDK、OSS控制台等工具手動建立缺失的Bucket或子目錄,然後重新掛載。

    2. 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解決方案:

    1. 建議您將csi-plugin版本升級到v1.26.2或以上版本,該版本修複了剛擴容出的節點初始化時,ossfs安裝失敗的問題。

    2. 執行以下命令,嘗試重啟對應節點上的csi-plugin後,查看Pod是否能正常啟動。以下代碼中csi-plugin-****為節點所在csi-plugin的Pod名稱。

      kubectl -n kube-system delete pod csi-plugin-****
    3. 若升級或重啟組件後,問題仍無法解決,請登入節點,執行以下命令。

      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包,請提交工單處理。

  • 原因4解決方案:

    • 若您手動安裝過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
  • 原因5解決方案:

    您需要同步來源站點資料後,再進行掛載。更多資訊,請參見回源概述

  • 原因6解決方案:

    您需要關閉或調整靜態網站託管的配置,再進行掛載。更多資訊,請參見靜態網站託管概述

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解決方案:

  1. 將CSI plugin組件版本升級至v1.26.6後,ossfs可支援通過listObjectsV2訪問Bucket。

  2. 在OSS靜態卷PV的otherOpts欄位中增加-o listobjectsv2來解決。

原因3解決方案:

您需要修改儲存類型或者解凍檔案

OSS控制台看到檔案大小為0

問題現象

容器內掛載OSS資料卷時,在檔案中寫入資料,但在OSS控制台看到檔案大小為0。

問題原因

容器使用ossfs掛載OSS,即基於FUSE方式掛載OSS的Bucket,只有在檔案執行close或者flush時,檔案內容才會上傳至OSS的服務端。

解決方案

使用lsof+檔案名稱的方式,查看當前檔案是否被其他進程佔用,關閉相應進程,釋放檔案fd。關於lsof更多資訊,請參見Isof

檔案目錄掛載後,顯示為檔案對象

問題現象

容器內掛載OSS資料卷時,檔案原本是目錄,掛載後,顯示為檔案對象。

問題原因

原因1:目錄對象在OSS服務端content-type類型是非預設的application/octet-stream類型(例如text/html, image/jpeg等),或目錄對象的大小非0,ossfs根據其元資訊將其視為相應的檔案對象。

原因2:非原因1的情況,但目錄對象缺少元資訊x-oss-meta-mode

解決方案

原因1解決方案:

通過HeadObjectstat(查看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。

若不滿足以上條件,您可以通過以下方式修複:

  1. 通過GetObject命令列工具ossutil快速入門擷取該對象,確認資料是否有用。若資料有用或不能確定,建議對其進行備份,例如變更名稱(對xx/目錄對象,請勿使用xx作為新的名稱)後上傳至OSS。

  2. 通過DeleteObjectrm(刪除)刪除有問題的目錄對象,然後確認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的請求。如果請求次數很多,會產生費用。

解決方案

通過審計追蹤產生請求的進程,並進行相應修複。您可以在節點上進行如下操作。

  1. 執行以下命令,安裝auditd並啟動。

    sudo yum install auditd
    sudo service auditd start
  2. 將對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
  3. 通過以下命令,在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)
    ---
  4. 藉助日誌進一步確認是否存在非業務的進程調用,並進行修複。

    例如,通過auditlog查到updatedb掃描了所掛載的目錄,可以通過修改/etc/updatedb.conf讓它跳過。具體操作如下。

    1. RUNEFS =後面加上fuse.ossfs

    2. PRUNEPATHS =後面加上掛載的目錄。

通過OSS儲存卷寫入的檔案對象的中繼資料Content-Type全為application/octet-stream類型

問題現象

通過OSS儲存卷寫入的檔案對象的中繼資料Content-Type全為application/octet-stream類型,導致瀏覽器或其他用戶端未能夠正確識別和處理這些檔案。

問題原因

  • 未指定Content-Type類型,ossfs預設將檔案對象視為二進位流檔案。

  • 通過/etc/mime.types設定檔指定Content-Type類型,但未生效。

解決方案

  1. 確認CSI組件版本,1.26.6和1.28.1版本的組件對Content-Type配置存在相容性問題。若使用了相關版本,請升級CSI至最新版本。更多資訊,請參見【組件公告】關於1.26.6和1.28.1版本的csi-plugin和csi-provisioner組件相容性問題

  2. 若您已經通過使用mailcapmime-support在節點上產生/etc/mime.types的方式指定Content-Type類型,升級CSI版本後,重新掛載對應OSS儲存卷即可。

  3. 若您未指定Content-Type類型,可通過以下兩種方式指定:

    • 節點層級配置:在節點上產生/etc/mime.types設定檔,對所有新掛載到該節點上應用的OSS儲存卷生效。更多資訊,請參見使用ossfs上傳到OSS的檔案的Content-Type全是application/octet-stream

    • 叢集層級配置:該方式對叢集所有新掛載的OSS儲存卷生效,/etc/mime.types內容與mailcap預設產生的內容一致。

      1. 執行以下命令,檢查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"
      2. 重啟csi-plugin,使配置生效,重啟csi-plugin不會影響當前已經成功掛載的儲存卷的使用。

        kubectl -n kube-system delete pod -l app=csi-plugin
  4. 重新掛載對應的OSS儲存卷。

如何在RRSA鑒權方式中使用指定的ARNs或ServiceAccount?

通過RRSA方式的OSS儲存卷鑒權時,無法滿足例如使用第三方OIDC身份供應商、使用非預設ServiceAccount等需求。

此時,您只需要在PV中通過roleName配置項指定RAM角色名稱,即可由CSI儲存外掛程式擷取預設的Role ARN及OIDC Provider ARN。若您需要實現定製化的RRSA鑒權,則需要更改PV的配置資訊如下:

說明

其中,roleArnoidcProviderArn需要一起配置,配置後無需再配置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 supportedOperation 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解決方案

  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****
  2. 登入Terminating的Pod所在的節點。

  3. 在節點上執行以下命令,查詢當前是否有進程佔用掛載點。

    lsof /var/lib/kubelet/pods/<pod-uid>/volumes/kubernetes.io~csi/<pv-name>/mount/

    若有輸出,請確認並清理相關進程。

原因2解決方案

  1. 登入OSS管理主控台

  2. 查詢Bucket或目錄是否被刪,若您使用了subpath方式掛載OSS儲存卷,還需要確認subpath掛載目錄是否被刪除。

  3. 確認上由於刪除目錄導致的卸載失敗,請參考以下操作處理。

    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****
    2. 登入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 ontype之間路徑為節點上的實際掛載點。

    3. 手動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
    4. 等待kubelet重試時正常回收,或者直接通過--force刪除Pod。

  4. 其他寫卸載失敗問題,請提交工單諮詢。

控制台檢測長期卡住,或失敗無資訊透出,或顯示unknown error

問題現象

檢測長期卡住,或失敗無資訊透出,或顯示unknown error。

問題原因

若檢測長期卡在進行中狀態,基本判斷為網路原因。對於其他未知錯誤,您可以通過如下查詢日誌及手動通過ossutil進行原因定位。

解決方案

您可以通過日誌和ossutil工具定位具體問題。

通過日誌定位具體問題

  1. 執行以下命令,找到執行檢測任務的Pod。

    • osssecret-namespace:保密字典所在命名空間。

    • pv-name:PV的名稱。

    kubectl -n <osssecret-namespace> get pod | grep <pv-name>-check

    預期輸出:

    <pv-name>-check-xxxxx
  2. 執行以下命令,查詢失敗原因。

    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

  • 若選擇私人網域名稱,取值為oss-<region-id>-internal.aliyuncs.com

  • 若選擇公有網域名稱,取值為oss-<region-id>.aliyuncs.com

accessKeyID

保密字典中的AccessKeyID。

accessKeySecret

保密字典中的AccessKeySecret。

bucket

Bucket ID。

path

路徑。填寫的路徑需要以"/"結尾。

例如,如果您在建立如下的儲存卷的配置資訊,則您需要執行的命令如下。image.png

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-systemack-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-systemack-csi-fuse命名空間下的csi-fuse-ossfs-* Pod)與對應的應用Pod,造成業務中斷。因此,預設情況下CSI不會對已經啟動並執行ossfs進行變更,您需要手動進行重掛載操作。

解決方案

重要

ossfs重掛載將導致業務Pod重啟,引起業務中斷,請謹慎操作。

若您使用的是非容器化的CSI版本,或開啟了獨享掛載,可以直接重啟對應的應用Pod。容器化版本後,預設使用共用掛載方式,即每個節點上掛載同一OSS儲存卷的所有應用Pod共用ossfs進程實現掛載。

  1. 確認當前FUSE Pod被哪些應用Pod在使用。

    1. 執行以下命令,確認需要變更的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>
    2. 執行以下命令,確認正在掛載該OSS儲存卷的所有Pod。

      其中<ns>為命名空間名稱,<pvc-name>為PVC名稱。

    3. 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****
    4. 執行以下命令,擷取通過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>
  2. 進行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被刪除,或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的日誌查詢功能。關於開通日誌查詢的操作,請參見開通即時日誌查詢

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇日誌管理 > 即時查詢

  4. 即時查詢頁簽下,根據查詢文法分析文法,輸入查詢和分析語句,對OSS日誌進行分析。您可以通過user_agentclient_ip欄位定位日誌是否來源於ACK。

    1. 定位由ACK發送的OSS操作請求時,您需要選擇user_agent欄位,展開後看到user_agent裡包含ossfs的都可以選擇。

      重要
      • user-agent欄位的取值與ossfs版本有關,ossfs版本不同,user-agent欄位的值也不一樣,但均以aliyun-sdk-http/1.0()/ossfs開頭。

      • 如果您在ECS上也通過ossfs掛載,相關日誌也會被耦合到這裡。

    2. 如需定位到某個ECS執行個體或叢集,您還可以選擇client_ip欄位,然後選擇對應的IP。

    結合以上兩個欄位選擇,查詢到的日誌樣本如下圖所示。image

日誌查詢部分欄位說明

欄位

說明

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 permittedPermission 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.capacitypvc.spec.resources.requests.storage配置均不起作用。您只需保證需要綁定PV、PVC配置的容量相等即可。

實際儲存超出此配置時,不影響正常使用,也無需擴容儲存卷。