簡體   English   中英

更改 Kube.netes Persistent Volume 的 Storage Class 並保留數據

[英]Change Kubernetes Persistent Volume's Storage Class and keep the data

我有 Elasticsearch 當前在 AKS 上運行並連接到使用高級 SSD 托管磁盤存儲 Class 的持久卷的數據 pod,我想將其降級為標准 SSD 托管磁盤而不丟失我在當前使用的持久性上擁有的數據體積。 我創建了一個用標准 SSD 托管磁盤定義的新存儲 Class,但如果我從中創建一個新 PV,它顯然不會保留舊數據,我需要以某種方式復制它,所以我想知道會是什么切換 PV 存儲的最佳實踐 Class。

不幸的是,一旦創建了 PVC 並為其配置了 PV,在不創建新 PVC 的情況下唯一可以更改的是卷的大小

在不利用 CSI 快照/克隆的情況下,我能想到的唯一直接的方法是創建一個新的 PVC 並將兩個卷掛載到其 Pod 的 Deployment 上具有 root 訪問權限和rsync命令。

在這樣的 Pod 上運行rsync -a /old/volume/mount/path /new/volume/mount/path應該可以得到你想要的。

但是,您應該確保在刪除 PVC 或任何其他使用您的 PV 的資源之前這樣做。 默認情況下,大多數默認存儲類都會創建具有回收策略的卷,一旦使用它的所有資源都消失,就會立即刪除 PV,因此數據丟失的風險很小

由於上述原因,在 Kube.netes 中不可能更改 PVC 的存儲 class。 不幸的是,您必須創建一個具有所需存儲空間 class 的新 PVC。

go 的一種方法是創建快照,然后從該快照創建新卷: https://kube.netes.io/docs/concepts/storage/volume-snapshots/

另一個是利用 CSI 克隆: https://kube.netes.io/docs/concepts/storage/volume-pvc-datasource/

兩者都有效地促進了使用現有數據副本創建新 PV

作為對@LeoD 回答的擴展,我正在分享一個完整的分步指南,說明我最終所做的事情。

  1. 將有狀態集縮放為 0。

  2. 在 Azure 找到舊 PV 的 Disk 資源:

  • kubectl describe pv檢查哪些 PV 與我要替換的 PVC 相關聯。
  • 按照字段DiskURI中指定的資源 ID 獲取 Azure 中的磁盤。
  1. 從每個 PVC 磁盤創建一個 Azure 快照資源。

  2. 創建一個新磁盤,其分配的 GiB 至少與當前 PVC 從快照中分配的 GiB 相同。 SKU 在這一點上仍然無關緊要,但我更喜歡使用我想要實施的新 SKU。

  3. 從每個新磁盤創建一個 K8S 持久卷:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-from-azure-disk-0
  namespace: my-namespace
  annotations:
    pv.kubernetes.io/provisioned-by: disk.csi.azure.com
spec:
  capacity:
    storage: 1064
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: managed
  claimRef:
    name: pvc-from-azure-0
    namespace: my-namespace
  csi:
    driver: disk.csi.azure.com
    volumeHandle: /subscriptions/<Your subscription ID>/resourcegroups/<Name of RG where the new Disk is stored at>/providers/microsoft.compute/disks/new-disk-from-pvc-0
    fsType: ext4

確保編輯以下字段:

  • metadata.namespace :到您擁有舊資源的命名空間。
  • spec.capacity.storage :分配給您為新磁盤選擇的 GiB。
  • spec.storageClassName :適合您為磁盤選擇的 SKU 的存儲名稱 Class。
  • spec.claimRef.name :這里我們為尚未創建的 PVC 指定一個名稱,稍后將使用它,只需確保您在此處選擇的名稱是您將在接下來創建 PVC 時使用的名稱步。
  • spec.claimRef.namespace :到您擁有舊資源的名稱空間。
  • csi.volumeHandle :插入新磁盤的資源 ID。
  1. 從您剛剛創建的每個新持久卷創建一個 K8S 持久卷聲明:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-from-azure-0
  namespace: my-namespace
spec:
  storageClassName: managed
  volumeName: pv-from-azure-disk-0
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1064

確保編輯以下字段:

  • metadata.name :使用您在 PV 的spec.claimRef.name字段中使用的完全相同的名稱。
  • metadata.namespace :到您擁有舊資源的名稱空間。
  • spec.storageClassName :到您在spec.storageClassName字段中為 PV 指定的存儲名稱 Class。
  • spec.volumeName :您在上一步中創建的 PV 的名稱。
  • spec.resources.requests.storage :分配給您在 PV 的spec.capacity.storage字段中指定的 GiB。
  1. 對每個要替換的現有 PVC 執行步驟 2-6; 例如,如果您的 Stateful Set 有 3 個 Pod,您應該為每個 Pod 的 PVC 執行 3 次。

  2. 為每個新的 PVC 創建一個 Ubuntu Pod,並將 PVC 掛載到 Pod。 (例如,如果您有 3 個 PVC,則您應該有 3 個 Ubuntu pod,每個 pod 一個)。

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-0
  namespace: my-namespace
spec:
  containers:
   - name: ubuntu-0
     image: ubuntu
     command:
      - "sleep"
      - "604800"
     volumeMounts:
       - mountPath: /mnt/snapshot-data-0
         name: snapshot-data-0
  volumes:
   - name: snapshot-data-0
     persistentVolumeClaim:
       claimName: pvc-from-azure-0

確保編輯以下字段:

  • metadata.namespace :到您擁有舊資源的命名空間。
  • spec.volumes.persistentVolumeClaim.claimName :您創建的新 PVC 的名稱。
  1. 執行每個 Ubuntu Pod 並驗證您的所有數據都在其中。

  2. 如果所有數據都在那里,您可以刪除 Ubuntu Pod。

  3. 現在是非常關鍵的部分,您需要刪除舊的原始 PVC 和 Stateful Set,但在此之前,請確保您擁有 Stateful Set 的原始 yaml 文件或用於創建 Stateful Set 的任何其他文件,確保您知道如何重新創建 Stateful Set ,然后才繼續刪除舊的原始 PVC 和 Stateful Set。

  4. 刪除有狀態集和舊 PVC 完成后,在您的有狀態集 yaml 或配置中,將volumeClaimTemplates塊中的storageClassName值替換為您要使用的新存儲 Class。

...

volumeClaimTemplate:
  accessModes: [ "ReadWriteOnce" ]
  storageClassName: "managed" # <--- Edit this field
  resources:
    requests:
      storage: "1064"
    limits:
      storage: "1064"
      
...      
  1. 現在使用新配置重新創建有狀態集。 這將重新創建有狀態集並創建新的空 PVC,這些 PVC 將使用存儲 Class 中新指定的 SKU。

  2. PVC 創建完成后,將新的 Stateful Set 縮放為 0。

  3. 現在重新創建 Ubuntu Pod,但這次同時掛載您在第一步中創建的 Azure 磁盤中的 PVC 和新狀態集的新空 PVC:

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-0
  namespace: my-namespace
spec:
  containers:
   - name: ubuntu-0
     image: ubuntu
     command:
      - "sleep"
      - "604800"
     volumeMounts:
       - mountPath: /mnt/snapshot-data-0
         name: snapshot-data-0
       - mountPath: /mnt/new-data-0
         name: new-data-0           
  volumes:
   - name: snapshot-data-0
     persistentVolumeClaim:
       claimName: pvc-from-azure-0
   - name: new-data-0
     persistentVolumeClaim:
       claimName: my-stateful-set-data-0

確保編輯以下字段:

  • metadata.namespace :到您擁有資源的名稱空間。
  • spec.volumes.persistentVolumeClaim :這個有兩個字段,一個是snapshot-data-0 ,一個是new-data-0 顧名思義,snapshot-data-0 應該包含我們在第一步中創建的 Azure 磁盤中的舊數據,而 new-data-0 應該是空的,因為它應該是從重新創建的新 PVC有狀態集的。 因此,snapshot-data-0 的spec.volumes.persistentVolumeClaim的值應該是您從 Azure 磁盤創建的新 PVC 的名稱。 new-data-0 的spec.volumes.persistentVolumeClaim的值應該是在重新創建 Stateful Set 之后創建的新 PVC 的名稱。
  1. 執行到 Ubuntu Pod 並執行以下命令:
apt update && apt install rsync -y
nohup rsync -avz /mnt/snapshot-data-0/ /mnt/new-data-0 --log-file=$HOME/.rsyncd.log &

第一個命令是安裝rsync ,第二個命令是將所有舊數據復制到新的空 PVC 中,並將命令日志保存在/root/.rsyncd.log以供您檢查進度參考。 請注意,根據您存儲的數據量,此命令可能需要一些時間。 就我個人而言,大約需要 1 小時才能完成。

  1. 對每個備份的和舊的 PVC 對執行步驟 15-16。

  2. 完成所有 PVC 對后,刪除 Ubuntu Pod。

  3. 擴展新的有狀態集備份。

  4. 利潤。 您現在擁有具有相同數據但具有不同存儲類的相同狀態集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM