Migrera från lagringsklass i träd till CSI-drivrutiner i Azure Kubernetes Service (AKS)
Implementeringen av CSI-drivrutinen (Container Storage Interface) introducerades i Azure Kubernetes Service (AKS) från och med version 1.21. Genom att införa och använda CSI som standard bör dina befintliga tillståndskänsliga arbetsbelastningar med hjälp av beständiga volymer (PV) i träd migreras eller uppgraderas för att använda CSI-drivrutinen.
För att göra den här processen så enkel som möjligt och för att säkerställa att inga data går förlorade innehåller den här artikeln olika migreringsalternativ. De här alternativen omfattar skript för att säkerställa en smidig migrering från träd till Azure Disks och Azure Files CSI-drivrutiner.
Innan du börjar
- Azure CLI version 2.37.0 eller senare. Kör
az --version
för att hitta versionen och köraz upgrade
för att uppgradera versionen. Om du behöver installera eller uppgradera kan du läsa Installera Azure CLI. - Kubectl- och klusteradministratörer har åtkomst till att skapa, hämta, lista, ta bort åtkomst till en PVC- eller PV-fil, volymögonblicksbild eller volymögonblicksbildinnehåll. För ett Microsoft Entra RBAC-aktiverat kluster är du medlem i AZURE Kubernetes Service RBAC-klusteradministratörsrollen.
Migrera diskvolymer
Kommentar
Etiketterna failure-domain.beta.kubernetes.io/zone
och failure-domain.beta.kubernetes.io/region
har blivit inaktuella i AKS 1.24 och tagits bort i 1.28. Om dina befintliga beständiga volymer fortfarande använder nodeAffinity som matchar dessa två etiketter måste du ändra dem till topology.kubernetes.io/zone
och topology.kubernetes.io/region
etiketter i den nya beständiga volyminställningen.
Migrering från träd till CSI stöds med två migreringsalternativ:
- Skapa en statisk volym
- Skapa en dynamisk volym
Skapa en statisk volym
Med det här alternativet skapar du en PV genom att statiskt tilldela claimRef
till en ny PVC som du skapar senare och ange volumeName
för PersistentVolumeClaim.
Fördelarna med den här metoden är:
- Det är enkelt och kan automatiseras.
- Du behöver inte rensa den ursprungliga konfigurationen med in-tree-lagringsklass.
- Låg risk eftersom du bara utför en logisk borttagning av Kubernetes-PV/-PVC. Faktiska fysiska data tas inte bort.
- Ingen extra kostnad tillkommer på grund av att du inte behöver skapa ytterligare Azure-objekt, till exempel diskar, ögonblicksbilder osv.
Följande är viktiga överväganden att utvärdera:
- Övergången till statiska volymer från ursprungliga dynamiska volymer kräver manuell konstruktion och hantering av PV-objekt för alla alternativ.
- Potentiellt programavbrott vid omdistribution av det nya programmet med referens till det nya PVC-objektet.
Migrering
Uppdatera den befintliga PV
ReclaimPolicy
:en från Ta bort till Behåll genom att köra följande kommando:kubectl patch pv pvName -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
Ersätt pvName med namnet på din valda PersistentVolume. Om du vill uppdatera reclaimPolicy för flera datorer kan du också skapa en fil med namnet patchReclaimPVs.sh och kopiera i följande kod.
#!/bin/bash # Patch the Persistent Volume in case ReclaimPolicy is Delete NAMESPACE=$1 i=1 for PVC in $(kubectl get pvc -n $NAMESPACE | awk '{ print $1}'); do # Ignore first record as it contains header if [ $i -eq 1 ]; then i=$((i + 1)) else PV="$(kubectl get pvc $PVC -n $NAMESPACE -o jsonpath='{.spec.volumeName}')" RECLAIMPOLICY="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.persistentVolumeReclaimPolicy}')" echo "Reclaim Policy for Persistent Volume $PV is $RECLAIMPOLICY" if [[ $RECLAIMPOLICY == "Delete" ]]; then echo "Updating ReclaimPolicy for $pv to Retain" kubectl patch pv $PV -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' fi fi done
Kör skriptet med parametern
namespace
för att ange klusternamnområdet./PatchReclaimPolicy.sh <namespace>
.Hämta en lista över alla datorer i namnområdet sorterade efter creationTimestamp genom att köra följande kommando. Ange namnområdet med argumentet
--namespace
tillsammans med det faktiska klusternamnområdet.kubectl get pvc -n <namespace> --sort-by=.metadata.creationTimestamp -o custom-columns=NAME:.metadata.name,CreationTime:.metadata.creationTimestamp,StorageClass:.spec.storageClassName,Size:.spec.resources.requests.storage
Det här steget är användbart om du har ett stort antal datorer som måste migreras och du vill migrera några i taget. Genom att köra det här kommandot kan du identifiera vilka datorer som skapades inom en viss tidsram. När du kör skriptet CreatePV.sh är två av parametrarna starttid och sluttid som gör att du bara kan migrera datorerna under den tidsperioden.
Skapa en fil med namnet CreatePV.sh och kopiera i följande kod. Skriptet gör följande:
- Skapar en ny PersistentVolume med namnet
existing-pv-csi
på alla PersistentVolumes i namnrymder för lagringsklassenstorageClassName
. - Konfigurera nytt PVC-namn som
existing-pvc-csi
. - Skapar en ny PVC med det PV-namn som du anger.
#!/bin/bash #kubectl get pvc -n <namespace> --sort-by=.metadata.creationTimestamp -o custom-columns=NAME:.metadata.name,CreationTime:.metadata.creationTimestamp,StorageClass:.spec.storageClassName,Size:.spec.resources.requests.storage # TimeFormat 2022-04-20T13:19:56Z NAMESPACE=$1 FILENAME=$(date +%Y%m%d%H%M)-$NAMESPACE EXISTING_STORAGE_CLASS=$2 STORAGE_CLASS_NEW=$3 STARTTIMESTAMP=$4 ENDTIMESTAMP=$5 i=1 for PVC in $(kubectl get pvc -n $NAMESPACE | awk '{ print $1}'); do # Ignore first record as it contains header if [ $i -eq 1 ]; then i=$((i + 1)) else PVC_CREATION_TIME=$(kubectl get pvc $PVC -n $NAMESPACE -o jsonpath='{.metadata.creationTimestamp}') if [[ $PVC_CREATION_TIME >= $STARTTIMESTAMP ]]; then if [[ $ENDTIMESTAMP > $PVC_CREATION_TIME ]]; then PV="$(kubectl get pvc $PVC -n $NAMESPACE -o jsonpath='{.spec.volumeName}')" RECLAIM_POLICY="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.persistentVolumeReclaimPolicy}')" STORAGECLASS="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.storageClassName}')" echo $PVC RECLAIM_POLICY="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.persistentVolumeReclaimPolicy}')" if [[ $RECLAIM_POLICY == "Retain" ]]; then if [[ $STORAGECLASS == $EXISTING_STORAGE_CLASS ]]; then STORAGE_SIZE="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.capacity.storage}')" SKU_NAME="$(kubectl get storageClass $STORAGE_CLASS_NEW -o jsonpath='{.parameters.skuname}')" DISK_URI="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.azureDisk.diskURI}')" PERSISTENT_VOLUME_RECLAIM_POLICY="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.persistentVolumeReclaimPolicy}')" cat >$PVC-csi.yaml <<EOF apiVersion: v1 kind: PersistentVolume metadata: annotations: pv.kubernetes.io/provisioned-by: disk.csi.azure.com name: $PV-csi spec: accessModes: - ReadWriteOnce capacity: storage: $STORAGE_SIZE claimRef: apiVersion: v1 kind: PersistentVolumeClaim name: $PVC-csi namespace: $NAMESPACE csi: driver: disk.csi.azure.com volumeAttributes: csi.storage.k8s.io/pv/name: $PV-csi csi.storage.k8s.io/pvc/name: $PVC-csi csi.storage.k8s.io/pvc/namespace: $NAMESPACE requestedsizegib: "$STORAGE_SIZE" skuname: $SKU_NAME volumeHandle: $DISK_URI persistentVolumeReclaimPolicy: $PERSISTENT_VOLUME_RECLAIM_POLICY storageClassName: $STORAGE_CLASS_NEW --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: $PVC-csi namespace: $NAMESPACE spec: accessModes: - ReadWriteOnce storageClassName: $STORAGE_CLASS_NEW resources: requests: storage: $STORAGE_SIZE volumeName: $PV-csi EOF kubectl apply -f $PVC-csi.yaml LINE="PVC:$PVC,PV:$PV,StorageClassTarget:$STORAGE_CLASS_NEW" printf '%s\n' "$LINE" >>$FILENAME fi fi fi fi fi done
- Skapar en ny PersistentVolume med namnet
Om du vill skapa en ny PersistentVolume för alla PersistentVolumes i namnområdet kör du skriptet CreatePV.sh med följande parametrar:
namespace
– KlusternamnområdetsourceStorageClass
– Lagringsdrivrutinsbaserad lagringsdrivrutinsbaserad lagringsklass i trädtargetCSIStorageClass
– CSI-lagringsdrivrutinsbaserad StorageClass, som antingen kan vara en av standardlagringsklasserna som har provisioner inställd på disk.csi.azure.com eller file.csi.azure.com. Eller så kan du skapa en anpassad lagringsklass så länge den är inställd på någon av dessa två etablerare.startTimeStamp
– Ange en starttid före PVC-skapandetiden i formatet yyyy-mm-ddthh:mm:sszendTimeStamp
– Ange en sluttid i formatet åååå-mm-ddthh:mm:ssz.
./CreatePV.sh <namespace> <sourceIntreeStorageClass> <targetCSIStorageClass> <startTimestamp> <endTimestamp>
Uppdatera programmet så att det använder den nya PVC-koden.
Skapa en dynamisk volym
Med det här alternativet skapar du dynamiskt en beständig volym från ett beständiga volymanspråk.
Fördelarna med den här metoden är:
Det är mindre riskabelt eftersom alla nya objekt skapas medan andra kopior bevaras med ögonblicksbilder.
Du behöver inte konstruera PV separat och lägga till volymnamn i PVC-manifestet.
Följande är viktiga överväganden att utvärdera:
Den här metoden är mindre riskabel, men den skapar flera objekt som ökar dina lagringskostnader.
När de nya volymerna skapas är programmet inte tillgängligt.
Borttagningsstegen bör utföras med försiktighet. Tillfälliga resurslås kan tillämpas på resursgruppen tills migreringen har slutförts och programmet har verifierats.
Utför dataverifiering/verifiering när nya diskar skapas från ögonblicksbilder.
Migrering
Kontrollera följande innan du fortsätter:
För specifika arbetsbelastningar där data skrivs till minnet innan de skrivs till disken ska programmet stoppas och tillåta att minnesinterna data rensas till disk.
VolumeSnapshot
-klassen bör finnas som i följande exempel YAML:apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: custom-disk-snapshot-sc driver: disk.csi.azure.com deletionPolicy: Delete parameters: incremental: "false"
Hämta en lista över alla datorer i ett angivet namnområde sorterat efter creationTimestamp genom att köra följande kommando. Ange namnområdet med argumentet
--namespace
tillsammans med det faktiska klusternamnområdet.kubectl get pvc --namespace <namespace> --sort-by=.metadata.creationTimestamp -o custom-columns=NAME:.metadata.name,CreationTime:.metadata.creationTimestamp,StorageClass:.spec.storageClassName,Size:.spec.resources.requests.storage
Det här steget är användbart om du har ett stort antal datorer som måste migreras och du vill migrera några i taget. Genom att köra det här kommandot kan du identifiera vilka datorer som skapades inom en viss tidsram. När du kör skriptet MigrateCSI.sh är två av parametrarna starttid och sluttid som gör att du bara kan migrera datorerna under den tidsperioden.
Skapa en fil med namnet MigrateToCSI.sh och kopiera i följande kod. Skriptet gör följande:
- Skapar en fullständig diskögonblicksbild med hjälp av Azure CLI
- Skapar
VolumesnapshotContent
- Skapar
VolumeSnapshot
- Skapar en ny PVC från
VolumeSnapshot
- Skapar en ny fil med filnamnet
<namespace>-timestamp
, som innehåller en lista över alla gamla resurser som måste rensas.
#!/bin/bash #kubectl get pvc -n <namespace> --sort-by=.metadata.creationTimestamp -o custom-columns=NAME:.metadata.name,CreationTime:.metadata.creationTimestamp,StorageClass:.spec.storageClassName,Size:.spec.resources.requests.storage # TimeFormat 2022-04-20T13:19:56Z NAMESPACE=$1 FILENAME=$NAMESPACE-$(date +%Y%m%d%H%M) EXISTING_STORAGE_CLASS=$2 STORAGE_CLASS_NEW=$3 VOLUME_STORAGE_CLASS=$4 START_TIME_STAMP=$5 END_TIME_STAMP=$6 i=1 for PVC in $(kubectl get pvc -n $NAMESPACE | awk '{ print $1}'); do # Ignore first record as it contains header if [ $i -eq 1 ]; then i=$((i + 1)) else PVC_CREATION_TIME=$(kubectl get pvc $PVC -n $NAMESPACE -o jsonpath='{.metadata.creationTimestamp}') if [[ $PVC_CREATION_TIME > $START_TIME_STAMP ]]; then if [[ $END_TIME_STAMP > $PVC_CREATION_TIME ]]; then PV="$(kubectl get pvc $PVC -n $NAMESPACE -o jsonpath='{.spec.volumeName}')" RECLAIM_POLICY="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.persistentVolumeReclaimPolicy}')" STORAGE_CLASS="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.storageClassName}')" echo $PVC RECLAIM_POLICY="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.persistentVolumeReclaimPolicy}')" if [[ $STORAGE_CLASS == $EXISTING_STORAGE_CLASS ]]; then STORAGE_SIZE="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.capacity.storage}')" SKU_NAME="$(kubectl get storageClass $STORAGE_CLASS_NEW -o jsonpath='{.parameters.skuname}')" DISK_URI="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.azureDisk.diskURI}')" TARGET_RESOURCE_GROUP="$(cut -d'/' -f5 <<<"$DISK_URI")" echo $DISK_URI SUBSCRIPTION_ID="$(echo $DISK_URI | grep -o 'subscriptions/[^/]*' | sed 's#subscriptions/##g')" echo $TARGET_RESOURCE_GROUP PERSISTENT_VOLUME_RECLAIM_POLICY="$(kubectl get pv $PV -n $NAMESPACE -o jsonpath='{.spec.persistentVolumeReclaimPolicy}')" az snapshot create --resource-group $TARGET_RESOURCE_GROUP --name $PVC-$FILENAME --source "$DISK_URI" --subscription ${SUBSCRIPTION_ID} SNAPSHOT_PATH=$(az snapshot list --resource-group $TARGET_RESOURCE_GROUP --query "[?name == '$PVC-$FILENAME'].id | [0]" --subscription ${SUBSCRIPTION_ID}) SNAPSHOT_HANDLE=$(echo "$SNAPSHOT_PATH" | tr -d '"') echo $SNAPSHOT_HANDLE sleep 10 # Create Restore File cat <<EOF >$PVC-csi.yml apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotContent metadata: name: $PVC-$FILENAME spec: deletionPolicy: 'Delete' driver: 'disk.csi.azure.com' volumeSnapshotClassName: $VOLUME_STORAGE_CLASS source: snapshotHandle: $SNAPSHOT_HANDLE volumeSnapshotRef: apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot name: $PVC-$FILENAME namespace: $1 --- apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: $PVC-$FILENAME namespace: $1 spec: volumeSnapshotClassName: $VOLUME_STORAGE_CLASS source: volumeSnapshotContentName: $PVC-$FILENAME --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: csi-$PVC namespace: $1 spec: accessModes: - ReadWriteOnce storageClassName: $STORAGE_CLASS_NEW resources: requests: storage: $STORAGE_SIZE dataSource: name: $PVC-$FILENAME kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io EOF kubectl create -f $PVC-csi.yml LINE="OLDPVC:$PVC,OLDPV:$PV,VolumeSnapshotContent:volumeSnapshotContent-$FILENAME,VolumeSnapshot:volumesnapshot$FILENAME,OLDdisk:$DISK_URI" printf '%s\n' "$LINE" >>$FILENAME fi fi fi fi done
Om du vill migrera diskvolymerna kör du skriptet MigrateToCSI.sh med följande parametrar:
namespace
– KlusternamnområdetsourceStorageClass
– Lagringsdrivrutinsbaserad lagringsdrivrutinsbaserad lagringsklass i trädtargetCSIStorageClass
– CSI-lagringsdrivrutinsbaserad StorageClassvolumeSnapshotClass
– Namnet på volymens ögonblicksbildklass. Exempel:custom-disk-snapshot-sc
startTimeStamp
– Ange en starttid i formatet yyyy-mm-ddthh:mm:ssz.endTimeStamp
– Ange en sluttid i formatet åååå-mm-ddthh:mm:ssz.
./MigrateToCSI.sh <namespace> <sourceStorageClass> <TargetCSIstorageClass> <VolumeSnapshotClass> <startTimestamp> <endTimestamp>
Uppdatera programmet så att det använder den nya PVC-koden.
Ta bort de äldre resurserna manuellt, inklusive PVC/PV i träd, VolumeSnapshot och VolumeSnapshotContent. Annars genererar underhållet av in-tree-PVC/PC och ögonblicksbilder mer kostnader.
Migrera filresursvolymer
Migrering från träd till CSI stöds genom att skapa en statisk volym:
- Du behöver inte rensa den ursprungliga konfigurationen med in-tree-lagringsklass.
- Låg risk eftersom du bara utför en logisk borttagning av Kubernetes-PV/-PVC. Faktiska fysiska data tas inte bort.
- Ingen extra kostnad tillkommer på grund av att du inte behöver skapa ytterligare Azure-objekt, till exempel filresurser osv.
Migrering
Uppdatera den befintliga PV
ReclaimPolicy
:en från Ta bort till Behåll genom att köra följande kommando:kubectl patch pv pvName -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
Ersätt pvName med namnet på din valda PersistentVolume. Om du vill uppdatera reclaimPolicy för flera datorer kan du också skapa en fil med namnet patchReclaimPVs.sh och kopiera i följande kod.
#!/bin/bash # Patch the Persistent Volume in case ReclaimPolicy is Delete namespace=$1 i=1 for pvc in $(kubectl get pvc -n $namespace | awk '{ print $1}'); do # Ignore first record as it contains header if [ $i -eq 1 ]; then i=$((i + 1)) else pv="$(kubectl get pvc $pvc -n $namespace -o jsonpath='{.spec.volumeName}')" reclaimPolicy="$(kubectl get pv $pv -n $namespace -o jsonpath='{.spec.persistentVolumeReclaimPolicy}')" echo "Reclaim Policy for Persistent Volume $pv is $reclaimPolicy" if [[ $reclaimPolicy == "Delete" ]]; then echo "Updating ReclaimPolicy for $pv to Retain" kubectl patch pv $pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' fi fi done
Kör skriptet med parametern
namespace
för att ange klusternamnområdet./PatchReclaimPolicy.sh <namespace>
.Skapa en ny lagringsklass med provisioner inställd på
file.csi.azure.com
, eller så kan du använda någon av standardlagringsklasserna med CSI-filetableren.secretName
Hämta ochshareName
från befintliga PersistentVolumes genom att köra följande kommando:kubectl describe pv pvName
Skapa en ny PV med hjälp av den nya StorageClass och
shareName
ochsecretName
från den trädbaserade PV:n. Skapa en fil med namnet azurefile-mount-pv.yaml och kopiera i följande kod. Undercsi
, uppdateraresourceGroup
,volumeHandle
ochshareName
. För monteringsalternativ är standardvärdet för fileMode och dirMode 0777.Standardvärdet för
fileMode
ochdirMode
är 0777.apiVersion: v1 kind: PersistentVolume metadata: annotations: pv.kubernetes.io/provisioned-by: file.csi.azure.com name: azurefile spec: capacity: storage: 5Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: azurefile-csi csi: driver: file.csi.azure.com readOnly: false volumeHandle: unique-volumeid # make sure volumeid is unique for every identical share in the cluster volumeAttributes: resourceGroup: EXISTING_RESOURCE_GROUP_NAME # optional, only set this when storage account is not in the same resource group as the cluster nodes shareName: aksshare nodeStageSecretRef: name: azure-secret namespace: default mountOptions: - dir_mode=0777 - file_mode=0777 - uid=0 - gid=0 - mfsymlinks - cache=strict - nosharesock - nobrl # disable sending byte range lock requests to the server and for applications which have challenges with posix locks
Skapa en fil med namnet azurefile-mount-pvc.yaml med en PersistentVolumeClaim som använder PersistentVolume med hjälp av följande kod.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: azurefile spec: accessModes: - ReadWriteMany storageClassName: azurefile-csi volumeName: azurefile resources: requests: storage: 5Gi
kubectl
Använd kommandot för att skapa PersistentVolume.kubectl apply -f azurefile-mount-pv.yaml
kubectl
Använd kommandot för att skapa PersistentVolumeClaim.kubectl apply -f azurefile-mount-pvc.yaml
Kontrollera att PersistentVolumeClaim har skapats och bundits till PersistentVolume genom att köra följande kommando.
kubectl get pvc azurefile
Utdata liknar följande:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE azurefile Bound azurefile 5Gi RWX azurefile 5s
Uppdatera containerspecifikationen så att den refererar till PersistentVolumeClaim och uppdaterar podden. Kopiera till exempel följande kod och skapa en fil med namnet azure-files-pod.yaml.
... volumes: - name: azure persistentVolumeClaim: claimName: azurefile
Poddspecifikationen kan inte uppdateras på plats. Använd följande
kubectl
kommandon för att ta bort och sedan återskapa podden.kubectl delete pod mypod
kubectl apply -f azure-files-pod.yaml
Nästa steg
- Mer information om metodtips för lagring finns i Metodtips för lagring och säkerhetskopior i Azure Kubernetes Service.
- Skydda dina nyligen migrerade CSI-drivrutinsbaserade PV:er genom att säkerhetskopiera dem med Hjälp av Azure Backup för AKS.
Azure Kubernetes Service