Skip to content

Commit

Permalink
add modify volume
Browse files Browse the repository at this point in the history
  • Loading branch information
umagnus committed Jul 16, 2024
1 parent d55e03f commit 005d0fc
Show file tree
Hide file tree
Showing 19 changed files with 645 additions and 14 deletions.
Binary file modified charts/latest/azuredisk-csi-driver-v1.30.1.tgz
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ rules:
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattachments/status"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattributesclasses"]
verbs: ["get"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "watch", "list", "delete", "update", "create", "patch"]
Expand Down Expand Up @@ -158,6 +161,9 @@ rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattributesclasses"]
verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
Expand Down
83 changes: 83 additions & 0 deletions deploy/example/modifyvolume/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Volume Modification
## Prerequisites
Volume modification only work on a cluster with the `VolumeAttributesClass` feature enabled. To use this feature, it should:
- `VolumeAttributesClass` feature gate on `kube-apiserver` (consult your Kubernetes distro's documentation)
- `storage.k8s.io/v1alpha1` enabled in `kube-apiserver` via [`runtime-config`](https://kubernetes.io/docs/tasks/administer-cluster/enable-disable-api/) (consult your Kubernetes distro's documentation)
- `VolumeAttributesClass` feature gate on `kube-controller-manager` (consult your Kubernetes distro's documentation)
- `VolumeAttributesClass` feature gate on `csi-provisioner` container in csi-azuredisk-controller
- `VolumeAttributesClass` feature gate on `csi-resizer` container in csi-azuredisk-controller

For more information, see the [Kubernetes documentation for the feature](https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/).

## Parameters
Users can specify the following modification parameters:
- `skuName`: to update the disk type(skuName is not allowed to change from or to UltraSSD_LRS or PremiumV2_LRS disk type, more details on [Change the disk type of an Azure managed disk](https://learn.microsoft.com/en-us/azure/virtual-machines/disks-convert-types?tabs=azure-powershell))
- `DiskIOPSReadWrite`: to update the IOPS
- `DiskMBpsReadWrite`: to update the throughput

## Usage

### Create an example Pod, PVC and StorageClass
```console
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/example/modifyvolume/storageclass-azuredisk-csi-premiumv2.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/example/pvc-azuredisk-csi.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/example/nginx-pod-azuredisk.yaml
```

### Wait for the PVC in Bound state and the pod in Running state
```console
kubectl get pvc pvc-azuredisk
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-azuredisk Bound pvc-e2a5c302-0b48-49a5-bde7-5c0528c7a06f 10Gi RWO managed-csi <unset> 17m

kubectl get pod nginx-azuredisk
NAME READY STATUS RESTARTS AGE
nginx-azuredisk 1/1 Running 0 20s
```

### Create VolumeAttributesClass
```console
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/azuredisk-csi-driver/master/deploy/example/modifyvolume/volumeattributesclass.yaml
kubectl get volumeattributesclass premium2-disk-class
NAME DRIVERNAME AGE
premium2-disk-class disk.csi.azure.com 4s
```

### Edit the PVC to point to the VolumeAttributesClass
```console
kubectl patch pvc pvc-azuredisk --patch '{"spec": {"volumeAttributesClassName": "premium2-disk-class"}}'
```

### Wait for the VolumeAttributesClass to apply to the volume
```console
kubectl get pvc pvc-azuredisk
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-azuredisk Bound pvc-e2a5c302-0b48-49a5-bde7-5c0528c7a06f 10Gi RWO managed-csi premium2-disk-class 20m

kubectl describe pvc pvc-azuredisk
Name: pvc-azuredisk
Namespace: default
StorageClass: managed-csi-prev2
Status: Bound
Volume: pvc-e2a5c302-0b48-49a5-bde7-5c0528c7a06f
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: disk.csi.azure.com
volume.kubernetes.io/selected-node: aks-agentpool-17390711-vmss000000
volume.kubernetes.io/storage-provisioner: disk.csi.azure.com
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 10Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: nginx-azuredisk
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal WaitForFirstConsumer 21m persistentvolume-controller waiting for first consumer to be created before binding
Normal Provisioning 21m disk.csi.azure.com_aks-agentpool-17390711-vmss000000_c36f4e97-171f-46c7-ba4a-c8567bb41452 External provisioner is provisioning volume for claim "default/pvc-azuredisk"
Normal ExternalProvisioning 21m (x2 over 21m) persistentvolume-controller Waiting for a volume to be created either by the external provisioner 'disk.csi.azure.com' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered.
Normal ProvisioningSucceeded 21m disk.csi.azure.com_aks-agentpool-17390711-vmss000000_c36f4e97-171f-46c7-ba4a-c8567bb41452 Successfully provisioned volume pvc-e2a5c302-0b48-49a5-bde7-5c0528c7a06f
Normal VolumeModify 18s external-resizer disk.csi.azure.com external resizer is modifying volume pvc-azuredisk with vac premium2-disk-class
Normal VolumeModifySuccessful 15s external-resizer disk.csi.azure.com external resizer modified volume pvc-azuredisk with vac premium2-disk-class successfully
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-csi
provisioner: disk.csi.azure.com
parameters:
cachingMode: None
skuName: PremiumV2_LRS
DiskIOPSReadWrite: "4000"
DiskMBpsReadWrite: "1000"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
9 changes: 9 additions & 0 deletions deploy/example/modifyvolume/volumeattributesclass.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
apiVersion: storage.k8s.io/v1alpha1
kind: VolumeAttributesClass
metadata:
name: premium2-disk-class
driverName: disk.csi.azure.com
parameters:
DiskIOPSReadWrite: "5000"
DiskMBpsReadWrite: "1200"
6 changes: 6 additions & 0 deletions deploy/rbac-csi-azuredisk-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ rules:
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattachments/status"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattributesclasses"]
verbs: ["get"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "watch", "list", "delete", "update", "create", "patch"]
Expand Down Expand Up @@ -157,6 +160,9 @@ rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattributesclasses"]
verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
Expand Down
2 changes: 1 addition & 1 deletion hack/verify-yamllint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ if [[ "${deployDirNum}" != "${helmDirNum}" ]]; then
exit 1
fi

for path in "deploy/*.yaml" "deploy/example/*.yaml" "deploy/example/metrics/*.yaml" "deploy/example/snapshot/*.yaml" "deploy/example/cloning/*.yaml" "deploy/example/rawblock/*.yaml" "deploy/example/windows/*.yaml" "deploy/example/sharedisk/*.yaml" "docs/known-issues/node-shutdown-recovery/*.yaml"
for path in "deploy/*.yaml" "deploy/example/*.yaml" "deploy/example/metrics/*.yaml" "deploy/example/snapshot/*.yaml" "deploy/example/cloning/*.yaml" "deploy/example/rawblock/*.yaml" "deploy/example/windows/*.yaml" "deploy/example/sharedisk/*.yaml" "deploy/example/modifyvolume/*.yaml" "docs/known-issues/node-shutdown-recovery/*.yaml"
do
echo "checking yamllint under path: $path ..."
yamllint -f parsable $path | grep -v "line too long" > $LOG
Expand Down
73 changes: 73 additions & 0 deletions pkg/azuredisk/azure_managedDiskController.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,79 @@ func (c *ManagedDiskController) ResizeDisk(ctx context.Context, diskURI string,
return newSizeQuant, nil
}

// ModifyDisk: modify disk
func (c *ManagedDiskController) ModifyDisk(ctx context.Context, options *ManagedDiskOptions) error {
klog.V(4).Infof("azureDisk - modifying managed Name:%s, StorageAccountType:%s, DiskIOPSReadWrite:%s, DiskMBpsReadWrite:%s", options.DiskName, options.StorageAccountType, options.DiskIOPSReadWrite, options.DiskMBpsReadWrite)

rg, subsID, err := getInfoFromDiskURI(options.SourceResourceID)
if err != nil {
return err
}

diskClient, err := c.clientFactory.GetDiskClientForSub(subsID)
if err != nil {
return err
}

model := armcompute.DiskUpdate{}
result, err := diskClient.Get(ctx, rg, options.DiskName)
if err != nil {
return err
}

if result.Properties == nil || result.SKU == nil || result.SKU.Name == nil {
return fmt.Errorf("DiskProperties or SKU of disk(%s) is nil", options.DiskName)
}

diskSku := *result.SKU.Name
if options.StorageAccountType != "" && options.StorageAccountType != diskSku {
diskSku = options.StorageAccountType
model.SKU = &armcompute.DiskSKU{
Name: to.Ptr(diskSku),
}
}

diskProperties := armcompute.DiskUpdateProperties{}

if diskSku == armcompute.DiskStorageAccountTypesUltraSSDLRS || diskSku == armcompute.DiskStorageAccountTypesPremiumV2LRS {
if options.DiskIOPSReadWrite != "" {
v, err := strconv.Atoi(options.DiskIOPSReadWrite)
if err != nil {
return fmt.Errorf("AzureDisk - failed to parse DiskIOPSReadWrite: %w", err)
}
diskIOPSReadWrite := int64(v)
diskProperties.DiskIOPSReadWrite = pointer.Int64(diskIOPSReadWrite)
}

if options.DiskMBpsReadWrite != "" {
v, err := strconv.Atoi(options.DiskMBpsReadWrite)
if err != nil {
return fmt.Errorf("AzureDisk - failed to parse DiskMBpsReadWrite: %w", err)
}
diskMBpsReadWrite := int64(v)
diskProperties.DiskMBpsReadWrite = pointer.Int64(diskMBpsReadWrite)
}

model.Properties = &diskProperties
} else {
if options.DiskIOPSReadWrite != "" {
return fmt.Errorf("AzureDisk - DiskIOPSReadWrite parameter is only applicable in UltraSSD_LRS or PremiumV2_LRS disk type")
}
if options.DiskMBpsReadWrite != "" {
return fmt.Errorf("AzureDisk - DiskMBpsReadWrite parameter is only applicable in UltraSSD_LRS or PremiumV2_LRS disk type")
}
}

if model.SKU != nil || model.Properties != nil {
if _, err := diskClient.Patch(ctx, rg, options.DiskName, model); err != nil {
return err
}
} else {
klog.V(4).Infof("azureDisk - no modification needed for disk(%s)", options.DiskName)
}
return nil
}

// get resource group name, subs id from a managed disk URI, e.g. return {group-name}, {sub-id} according to
// /subscriptions/{sub-id}/resourcegroups/{group-name}/providers/microsoft.compute/disks/{disk-id}
// according to https://docs.microsoft.com/en-us/rest/api/compute/disks/get
Expand Down
Loading

0 comments on commit 005d0fc

Please sign in to comment.