diff --git a/pkg/volume/azure_dd/azure_provision.go b/pkg/volume/azure_dd/azure_provision.go index 4d7153b94fe..fd16b985561 100644 --- a/pkg/volume/azure_dd/azure_provision.go +++ b/pkg/volume/azure_dd/azure_provision.go @@ -130,6 +130,7 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie availabilityZone string availabilityZones sets.String selectedAvailabilityZone string + writeAcceleratorEnabled string diskIopsReadWrite string diskMbpsReadWrite string @@ -178,6 +179,8 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie diskMbpsReadWrite = v case "diskencryptionsetid": diskEncryptionSetID = v + case azure.WriteAcceleratorEnabled: + writeAcceleratorEnabled = v default: return nil, fmt.Errorf("AzureDisk - invalid option %s in storage class", k) } @@ -245,6 +248,9 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie if p.options.CloudTags != nil { tags = *(p.options.CloudTags) } + if strings.EqualFold(writeAcceleratorEnabled, "true") { + tags[azure.WriteAcceleratorEnabled] = "true" + } volumeOptions := &azure.ManagedDiskOptions{ DiskName: name, diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_common.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_common.go index e693e99df41..513c63ba289 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_common.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_common.go @@ -51,6 +51,10 @@ const ( sourceSnapshot = "snapshot" sourceVolume = "volume" + // WriteAcceleratorEnabled support for Azure Write Accelerator on Azure Disks + // https://docs.microsoft.com/azure/virtual-machines/windows/how-to-enable-write-accelerator + WriteAcceleratorEnabled = "writeacceleratorenabled" + // see https://docs.microsoft.com/en-us/rest/api/compute/disks/createorupdate#create-a-managed-disk-by-copying-a-snapshot. diskSnapshotPath = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/snapshots/%s" @@ -113,6 +117,8 @@ func (c *controllerCommon) getNodeVMSet(nodeName types.NodeName, crt cacheReadTy // return (lun, error) func (c *controllerCommon) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, cachingMode compute.CachingTypes) (int32, error) { diskEncryptionSetID := "" + writeAcceleratorEnabled := false + if isManagedDisk { diskName := path.Base(diskURI) resourceGroup, err := getResourceGroupFromDiskURI(diskURI) @@ -142,6 +148,11 @@ func (c *controllerCommon) AttachDisk(isManagedDisk bool, diskName, diskURI stri disk.DiskProperties.Encryption.DiskEncryptionSetID != nil { diskEncryptionSetID = *disk.DiskProperties.Encryption.DiskEncryptionSetID } + if v, ok := disk.Tags[WriteAcceleratorEnabled]; ok { + if v != nil && strings.EqualFold(*v, "true") { + writeAcceleratorEnabled = true + } + } } vmset, err := c.getNodeVMSet(nodeName, cacheReadTypeUnsafe) @@ -167,7 +178,7 @@ func (c *controllerCommon) AttachDisk(isManagedDisk bool, diskName, diskURI stri klog.V(2).Infof("Trying to attach volume %q lun %d to node %q.", diskURI, lun, nodeName) c.diskAttachDetachMap.Store(strings.ToLower(diskURI), "attaching") defer c.diskAttachDetachMap.Delete(strings.ToLower(diskURI)) - return lun, vmset.AttachDisk(isManagedDisk, diskName, diskURI, nodeName, lun, cachingMode, diskEncryptionSetID) + return lun, vmset.AttachDisk(isManagedDisk, diskName, diskURI, nodeName, lun, cachingMode, diskEncryptionSetID, writeAcceleratorEnabled) } // DetachDisk detaches a disk from host. The vhd can be identified by diskName or diskURI. diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_standard.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_standard.go index ed6b5c6d6e7..da7969dbc2b 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_standard.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_standard.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" + "github.com/Azure/go-autorest/autorest/to" "k8s.io/apimachinery/pkg/types" "k8s.io/klog" @@ -29,7 +30,7 @@ import ( // AttachDisk attaches a vhd to vm // the vhd must exist, can be identified by diskName, diskURI, and lun. -func (as *availabilitySet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes, diskEncryptionSetID string) error { +func (as *availabilitySet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes, diskEncryptionSetID string, writeAcceleratorEnabled bool) error { vm, err := as.getVirtualMachine(nodeName, cacheReadTypeDefault) if err != nil { return err @@ -59,11 +60,12 @@ func (as *availabilitySet) AttachDisk(isManagedDisk bool, diskName, diskURI stri } disks = append(disks, compute.DataDisk{ - Name: &diskName, - Lun: &lun, - Caching: cachingMode, - CreateOption: "attach", - ManagedDisk: managedDisk, + Name: &diskName, + Lun: &lun, + Caching: cachingMode, + CreateOption: "attach", + ManagedDisk: managedDisk, + WriteAcceleratorEnabled: to.BoolPtr(writeAcceleratorEnabled), }) } else { disks = append(disks, diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_standard_test.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_standard_test.go index d70c5f6ebd7..f2de5cb774c 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_standard_test.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_standard_test.go @@ -53,7 +53,7 @@ func TestStandardAttachDisk(t *testing.T) { setTestVirtualMachines(testCloud, map[string]string{"vm1": "PowerState/Running"}, false) err := vmSet.AttachDisk(true, "", - "uri", test.nodeName, 0, compute.CachingTypesReadOnly, "") + "uri", test.nodeName, 0, compute.CachingTypesReadOnly, "", false) assert.Equal(t, test.expectedErr, err != nil, "TestCase[%d]: %s, err: %v", i, test.desc, err) } } diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_vmss.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_vmss.go index f5ee5b58b20..d325e3fc473 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_vmss.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_vmss.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" + "github.com/Azure/go-autorest/autorest/to" "k8s.io/apimachinery/pkg/types" "k8s.io/klog" @@ -29,7 +30,7 @@ import ( // AttachDisk attaches a vhd to vm // the vhd must exist, can be identified by diskName, diskURI, and lun. -func (ss *scaleSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes, diskEncryptionSetID string) error { +func (ss *scaleSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes, diskEncryptionSetID string, writeAcceleratorEnabled bool) error { vmName := mapNodeNameToVMName(nodeName) ssName, instanceID, vm, err := ss.getVmssVM(vmName, cacheReadTypeDefault) if err != nil { @@ -61,11 +62,12 @@ func (ss *scaleSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nod } disks = append(disks, compute.DataDisk{ - Name: &diskName, - Lun: &lun, - Caching: compute.CachingTypes(cachingMode), - CreateOption: "attach", - ManagedDisk: managedDisk, + Name: &diskName, + Lun: &lun, + Caching: compute.CachingTypes(cachingMode), + CreateOption: "attach", + ManagedDisk: managedDisk, + WriteAcceleratorEnabled: to.BoolPtr(writeAcceleratorEnabled), }) } else { disks = append(disks, diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_fakes.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_fakes.go index 7464d20408c..27965b4972a 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_fakes.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_fakes.go @@ -963,7 +963,7 @@ func (f *fakeVMSet) EnsureBackendPoolDeleted(service *v1.Service, backendPoolID, return fmt.Errorf("unimplemented") } -func (f *fakeVMSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes, diskEncryptionSetID string) error { +func (f *fakeVMSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes, diskEncryptionSetID string, writeAcceleratorEnabled bool) error { return fmt.Errorf("unimplemented") } diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmsets.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmsets.go index 0087fd56c82..2eb4e18da3a 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmsets.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_vmsets.go @@ -64,7 +64,7 @@ type VMSet interface { EnsureBackendPoolDeleted(service *v1.Service, backendPoolID, vmSetName string, backendAddressPools *[]network.BackendAddressPool) error // AttachDisk attaches a vhd to vm. The vhd must exist, can be identified by diskName, diskURI, and lun. - AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes, diskEncryptionSetID string) error + AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes, diskEncryptionSetID string, writeAcceleratorEnabled bool) error // DetachDisk detaches a vhd from host. The vhd can be identified by diskName or diskURI. DetachDisk(diskName, diskURI string, nodeName types.NodeName) error // GetDataDisks gets a list of data disks attached to the node.