mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 02:09:56 +00:00
Merge pull request #54687 from andyzhangx/createvolume-fix
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. fix CreateVolume func: use search mode instead **What this PR does / why we need it**: This is a little fall back for CreateVolume func: use search mode for Dedicated kind as @rootfs suggested. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #52396 **Special notes for your reviewer**: I reference the implmentation of v1.6 in the same CreateVolume func https://github.com/kubernetes/kubernetes/blob/release-1.6/pkg/cloudprovider/providers/azure/azure_storage.go#L213-L247 **Release note**: ``` fix azure storage account exhausting issue by using azure disk mount ``` /sig azure @rootfs @feiskyer @karataliu
This commit is contained in:
commit
3904cc7803
@ -59,11 +59,12 @@ type BlobDiskController struct {
|
|||||||
accounts map[string]*storageAccountState
|
accounts map[string]*storageAccountState
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultContainerName = ""
|
var (
|
||||||
var storageAccountNamePrefix = ""
|
defaultContainerName = ""
|
||||||
var storageAccountNameMatch = ""
|
storageAccountNamePrefix = ""
|
||||||
|
storageAccountNameMatch = ""
|
||||||
var accountsLock = &sync.Mutex{}
|
accountsLock = &sync.Mutex{}
|
||||||
|
)
|
||||||
|
|
||||||
func newBlobDiskController(common *controllerCommon) (*BlobDiskController, error) {
|
func newBlobDiskController(common *controllerCommon) (*BlobDiskController, error) {
|
||||||
c := BlobDiskController{common: common}
|
c := BlobDiskController{common: common}
|
||||||
@ -80,52 +81,49 @@ func newBlobDiskController(common *controllerCommon) (*BlobDiskController, error
|
|||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateVolume creates a VHD blob in a given storage account, will create the given storage account if it does not exist in current resource group
|
// CreateVolume creates a VHD blob in a storage account that has storageType and location using the given storage account.
|
||||||
func (c *BlobDiskController) CreateVolume(name, storageAccount string, storageAccountType storage.SkuName, location string, requestGB int) (string, string, int, error) {
|
// If no storage account is given, search all the storage accounts associated with the resource group and pick one that
|
||||||
key, err := c.common.cloud.getStorageAccesskey(storageAccount)
|
// fits storage type and location.
|
||||||
if err != nil {
|
func (c *BlobDiskController) CreateVolume(name, storageAccount, storageAccountType, location string, requestGB int) (string, string, int, error) {
|
||||||
glog.V(2).Infof("azureDisk - no key found for storage account %s in resource group %s, begin to create a new storage account", storageAccount, c.common.resourceGroup)
|
var err error
|
||||||
|
accounts := []accountWithLocation{}
|
||||||
cp := storage.AccountCreateParameters{
|
if len(storageAccount) > 0 {
|
||||||
Sku: &storage.Sku{Name: storageAccountType},
|
accounts = append(accounts, accountWithLocation{Name: storageAccount})
|
||||||
Tags: &map[string]*string{"created-by": to.StringPtr("azure-dd")},
|
} else {
|
||||||
Location: &location}
|
// find a storage account
|
||||||
cancel := make(chan struct{})
|
accounts, err = c.common.cloud.getStorageAccounts()
|
||||||
|
|
||||||
_, errchan := c.common.cloud.StorageAccountClient.Create(c.common.resourceGroup, storageAccount, cp, cancel)
|
|
||||||
err = <-errchan
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", 0, fmt.Errorf(fmt.Sprintf("Create Storage Account %s, error: %s", storageAccount, err))
|
// TODO: create a storage account and container
|
||||||
|
return "", "", 0, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for _, account := range accounts {
|
||||||
|
glog.V(4).Infof("account %s type %s location %s", account.Name, account.StorageType, account.Location)
|
||||||
|
if (storageAccountType == "" || account.StorageType == storageAccountType) && (location == "" || account.Location == location) || len(storageAccount) > 0 {
|
||||||
|
// find the access key with this account
|
||||||
|
key, err := c.common.cloud.getStorageAccesskey(account.Name)
|
||||||
|
if err != nil {
|
||||||
|
glog.V(2).Infof("no key found for storage account %s", account.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
key, err = c.common.cloud.getStorageAccesskey(storageAccount)
|
client, err := azstorage.NewBasicClientOnSovereignCloud(account.Name, key, c.common.cloud.Environment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", 0, fmt.Errorf("no key found for storage account %s even after creating a new storage account", storageAccount)
|
return "", "", 0, err
|
||||||
|
}
|
||||||
|
blobClient := client.GetBlobService()
|
||||||
|
|
||||||
|
// create a page blob in this account's vhd container
|
||||||
|
diskName, diskURI, err := c.createVHDBlobDisk(blobClient, account.Name, name, vhdContainerName, int64(requestGB))
|
||||||
|
if err != nil {
|
||||||
|
return "", "", 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
glog.V(4).Infof("azureDisk - created vhd blob uri: %s", diskURI)
|
||||||
|
return diskName, diskURI, requestGB, err
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.Errorf("no key found for storage account %s in resource group %s", storageAccount, c.common.resourceGroup)
|
|
||||||
return "", "", 0, err
|
|
||||||
}
|
}
|
||||||
|
return "", "", 0, fmt.Errorf("failed to find a matching storage account")
|
||||||
client, err := azstorage.NewBasicClientOnSovereignCloud(storageAccount, key, c.common.cloud.Environment)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", 0, err
|
|
||||||
}
|
|
||||||
blobClient := client.GetBlobService()
|
|
||||||
|
|
||||||
container := blobClient.GetContainerReference(vhdContainerName)
|
|
||||||
_, err = container.CreateIfNotExists(&azstorage.CreateContainerOptions{Access: azstorage.ContainerAccessTypePrivate})
|
|
||||||
if err != nil {
|
|
||||||
return "", "", 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
diskName, diskURI, err := c.createVHDBlobDisk(blobClient, storageAccount, name, vhdContainerName, int64(requestGB))
|
|
||||||
if err != nil {
|
|
||||||
return "", "", 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
glog.V(4).Infof("azureDisk - created vhd blob uri: %s", diskURI)
|
|
||||||
return diskName, diskURI, requestGB, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteVolume deletes a VHD blob
|
// DeleteVolume deletes a VHD blob
|
||||||
@ -173,11 +171,6 @@ func (c *BlobDiskController) getBlobNameAndAccountFromURI(diskURI string) (strin
|
|||||||
|
|
||||||
func (c *BlobDiskController) createVHDBlobDisk(blobClient azstorage.BlobStorageClient, accountName, vhdName, containerName string, sizeGB int64) (string, string, error) {
|
func (c *BlobDiskController) createVHDBlobDisk(blobClient azstorage.BlobStorageClient, accountName, vhdName, containerName string, sizeGB int64) (string, string, error) {
|
||||||
container := blobClient.GetContainerReference(containerName)
|
container := blobClient.GetContainerReference(containerName)
|
||||||
_, err := container.CreateIfNotExists(&azstorage.CreateContainerOptions{Access: azstorage.ContainerAccessTypePrivate})
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
size := 1024 * 1024 * 1024 * sizeGB
|
size := 1024 * 1024 * 1024 * sizeGB
|
||||||
vhdSize := size + vhd.VHD_HEADER_SIZE /* header size */
|
vhdSize := size + vhd.VHD_HEADER_SIZE /* header size */
|
||||||
// Blob name in URL must end with '.vhd' extension.
|
// Blob name in URL must end with '.vhd' extension.
|
||||||
@ -190,7 +183,17 @@ func (c *BlobDiskController) createVHDBlobDisk(blobClient azstorage.BlobStorageC
|
|||||||
blob := container.GetBlobReference(vhdName)
|
blob := container.GetBlobReference(vhdName)
|
||||||
blob.Properties.ContentLength = vhdSize
|
blob.Properties.ContentLength = vhdSize
|
||||||
blob.Metadata = tags
|
blob.Metadata = tags
|
||||||
err = blob.PutPageBlob(nil)
|
err := blob.PutPageBlob(nil)
|
||||||
|
if err != nil {
|
||||||
|
// if container doesn't exist, create one and retry PutPageBlob
|
||||||
|
detail := err.Error()
|
||||||
|
if strings.Contains(detail, errContainerNotFound) {
|
||||||
|
err = container.Create(&azstorage.CreateContainerOptions{Access: azstorage.ContainerAccessTypePrivate})
|
||||||
|
if err == nil {
|
||||||
|
err = blob.PutPageBlob(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("failed to put page blob %s in container %s: %v", vhdName, containerName, err)
|
return "", "", fmt.Errorf("failed to put page blob %s in container %s: %v", vhdName, containerName, err)
|
||||||
}
|
}
|
||||||
@ -236,24 +239,12 @@ func (c *BlobDiskController) deleteVhdBlob(accountName, accountKey, blobName str
|
|||||||
}
|
}
|
||||||
|
|
||||||
//CreateBlobDisk : create a blob disk in a node
|
//CreateBlobDisk : create a blob disk in a node
|
||||||
func (c *BlobDiskController) CreateBlobDisk(dataDiskName string, storageAccountType storage.SkuName, sizeGB int, forceStandAlone bool) (string, error) {
|
func (c *BlobDiskController) CreateBlobDisk(dataDiskName string, storageAccountType storage.SkuName, sizeGB int) (string, error) {
|
||||||
glog.V(4).Infof("azureDisk - creating blob data disk named:%s on StorageAccountType:%s StandAlone:%v", dataDiskName, storageAccountType, forceStandAlone)
|
glog.V(4).Infof("azureDisk - creating blob data disk named:%s on StorageAccountType:%s", dataDiskName, storageAccountType)
|
||||||
|
|
||||||
var storageAccountName = ""
|
storageAccountName, err := c.findSANameForDisk(storageAccountType)
|
||||||
var err error
|
if err != nil {
|
||||||
|
return "", err
|
||||||
if forceStandAlone {
|
|
||||||
// we have to wait until the storage account is is created
|
|
||||||
storageAccountName = "p" + MakeCRC32(c.common.subscriptionID+c.common.resourceGroup+dataDiskName)
|
|
||||||
err = c.createStorageAccount(storageAccountName, storageAccountType, c.common.location, false)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
storageAccountName, err = c.findSANameForDisk(storageAccountType)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blobClient, err := c.getBlobSvcClient(storageAccountName)
|
blobClient, err := c.getBlobSvcClient(storageAccountName)
|
||||||
@ -266,15 +257,13 @@ func (c *BlobDiskController) CreateBlobDisk(dataDiskName string, storageAccountT
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !forceStandAlone {
|
atomic.AddInt32(&c.accounts[storageAccountName].diskCount, 1)
|
||||||
atomic.AddInt32(&c.accounts[storageAccountName].diskCount, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return diskURI, nil
|
return diskURI, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//DeleteBlobDisk : delete a blob disk from a node
|
//DeleteBlobDisk : delete a blob disk from a node
|
||||||
func (c *BlobDiskController) DeleteBlobDisk(diskURI string, wasForced bool) error {
|
func (c *BlobDiskController) DeleteBlobDisk(diskURI string) error {
|
||||||
storageAccountName, vhdName, err := diskNameandSANameFromURI(diskURI)
|
storageAccountName, vhdName, err := diskNameandSANameFromURI(diskURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -286,11 +275,6 @@ func (c *BlobDiskController) DeleteBlobDisk(diskURI string, wasForced bool) erro
|
|||||||
glog.V(4).Infof("azureDisk - deleting volume %s", diskURI)
|
glog.V(4).Infof("azureDisk - deleting volume %s", diskURI)
|
||||||
return c.DeleteVolume(diskURI)
|
return c.DeleteVolume(diskURI)
|
||||||
}
|
}
|
||||||
// if forced (as in one disk = one storage account)
|
|
||||||
// delete the account completely
|
|
||||||
if wasForced {
|
|
||||||
return c.deleteStorageAccount(storageAccountName)
|
|
||||||
}
|
|
||||||
|
|
||||||
blobSvc, err := c.getBlobSvcClient(storageAccountName)
|
blobSvc, err := c.getBlobSvcClient(storageAccountName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -28,8 +28,8 @@ import (
|
|||||||
|
|
||||||
// interface exposed by the cloud provider implementing Disk functionlity
|
// interface exposed by the cloud provider implementing Disk functionlity
|
||||||
type DiskController interface {
|
type DiskController interface {
|
||||||
CreateBlobDisk(dataDiskName string, storageAccountType storage.SkuName, sizeGB int, forceStandAlone bool) (string, error)
|
CreateBlobDisk(dataDiskName string, storageAccountType storage.SkuName, sizeGB int) (string, error)
|
||||||
DeleteBlobDisk(diskUri string, wasForced bool) error
|
DeleteBlobDisk(diskUri string) error
|
||||||
|
|
||||||
CreateManagedDisk(diskName string, storageAccountType storage.SkuName, sizeGB int, tags map[string]string) (string, error)
|
CreateManagedDisk(diskName string, storageAccountType storage.SkuName, sizeGB int, tags map[string]string) (string, error)
|
||||||
DeleteManagedDisk(diskURI string) error
|
DeleteManagedDisk(diskURI string) error
|
||||||
@ -48,7 +48,7 @@ type DiskController interface {
|
|||||||
GetNextDiskLun(nodeName types.NodeName) (int32, error)
|
GetNextDiskLun(nodeName types.NodeName) (int32, error)
|
||||||
|
|
||||||
// Create a VHD blob
|
// Create a VHD blob
|
||||||
CreateVolume(name, storageAccount string, storageAccountType storage.SkuName, location string, requestGB int) (string, string, int, error)
|
CreateVolume(name, storageAccount, storageAccountType, location string, requestGB int) (string, string, int, error)
|
||||||
// Delete a VHD blob
|
// Delete a VHD blob
|
||||||
DeleteVolume(diskURI string) error
|
DeleteVolume(diskURI string) error
|
||||||
}
|
}
|
||||||
|
@ -55,14 +55,13 @@ func (d *azureDiskDeleter) Delete() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wasStandAlone := (*volumeSource.Kind != v1.AzureSharedBlobDisk)
|
|
||||||
managed := (*volumeSource.Kind == v1.AzureManagedDisk)
|
managed := (*volumeSource.Kind == v1.AzureManagedDisk)
|
||||||
|
|
||||||
if managed {
|
if managed {
|
||||||
return diskController.DeleteManagedDisk(volumeSource.DataDiskURI)
|
return diskController.DeleteManagedDisk(volumeSource.DataDiskURI)
|
||||||
}
|
}
|
||||||
|
|
||||||
return diskController.DeleteBlobDisk(volumeSource.DataDiskURI, wasStandAlone)
|
return diskController.DeleteBlobDisk(volumeSource.DataDiskURI)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *azureDiskProvisioner) Provision() (*v1.PersistentVolume, error) {
|
func (p *azureDiskProvisioner) Provision() (*v1.PersistentVolume, error) {
|
||||||
@ -149,26 +148,13 @@ func (p *azureDiskProvisioner) Provision() (*v1.PersistentVolume, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
forceStandAlone := (kind == v1.AzureDedicatedBlobDisk)
|
|
||||||
if kind == v1.AzureDedicatedBlobDisk {
|
if kind == v1.AzureDedicatedBlobDisk {
|
||||||
if location != "" && account != "" {
|
_, diskURI, _, err = diskController.CreateVolume(name, account, storageAccountType, location, requestGB)
|
||||||
// use dedicated kind (by default) for compatibility
|
if err != nil {
|
||||||
_, diskURI, _, err = diskController.CreateVolume(name, account, skuName, location, requestGB)
|
return nil, err
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if location != "" || account != "" {
|
|
||||||
return nil, fmt.Errorf("AzureDisk - location(%s) and account(%s) must be both empty or specified for dedicated kind, only one value specified is not allowed",
|
|
||||||
location, account)
|
|
||||||
}
|
|
||||||
diskURI, err = diskController.CreateBlobDisk(name, skuName, requestGB, forceStandAlone)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
diskURI, err = diskController.CreateBlobDisk(name, skuName, requestGB, forceStandAlone)
|
diskURI, err = diskController.CreateBlobDisk(name, skuName, requestGB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -718,16 +718,11 @@ func createPD(zone string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if azureCloud.BlobDiskController == nil {
|
_, diskURI, _, err := azureCloud.CreateVolume(pdName, "" /* account */, "" /* sku */, "" /* location */, 1 /* sizeGb */)
|
||||||
return "", fmt.Errorf("BlobDiskController is nil, it's not expected.")
|
|
||||||
}
|
|
||||||
|
|
||||||
diskUri, err := azureCloud.BlobDiskController.CreateBlobDisk(pdName, "standard_lrs", 1, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
return diskURI, nil
|
||||||
return diskUri, nil
|
|
||||||
} else {
|
} else {
|
||||||
return "", fmt.Errorf("provider does not support volume creation")
|
return "", fmt.Errorf("provider does not support volume creation")
|
||||||
}
|
}
|
||||||
@ -772,11 +767,7 @@ func deletePD(pdName string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if azureCloud.BlobDiskController == nil {
|
err = azureCloud.DeleteVolume(pdName)
|
||||||
return fmt.Errorf("BlobDiskController is nil, it's not expected.")
|
|
||||||
}
|
|
||||||
diskName := pdName[(strings.LastIndex(pdName, "/") + 1):]
|
|
||||||
err = azureCloud.BlobDiskController.DeleteBlobDisk(diskName, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logf("failed to delete Azure volume %q: %v", pdName, err)
|
Logf("failed to delete Azure volume %q: %v", pdName, err)
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user