-
Notifications
You must be signed in to change notification settings - Fork 39.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Azure PD (Managed/Blob) #46360
Azure PD (Managed/Blob) #46360
Conversation
Hi @khenidak. Thanks for your PR. I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've only reviewed the code in the cloudprovider directory. The majority of the changes are in the volume/azure_dd package, so I'll defer to @ brendandburns and @rootfs to review and approve those changes.
@@ -23,6 +23,10 @@ import ( | |||
azs "github.com/Azure/azure-sdk-for-go/storage" | |||
) | |||
|
|||
const ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please put this onto a single line instead of using a block since there is only one constant.
/approve |
@k8s-bot ok to test |
@khenidak This is a large refactoring, hard to review. Please reuse existing code and interface and not shuffle/copy them around. If there existing interface not working for you, address the limitation in the interface. |
/approve This is not a code review |
|
pkg/volume/azure_dd/common.go
Outdated
return "", err | ||
} | ||
|
||
func formatIfNotFormatted(disk string, fstype string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reuse method provided in mounter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
discussed above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IF that's the case, it should be addressed in pkg/util/mount
.
As mentioned, this format hang issue was root caused here
Submit an issue if you see other symptoms or root cause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd really rather not fix this problem in this PR. We can TODO it, but this PR has a bunch of fixes I'd like to see merged. Can we address the refactor/merge into pkg/util/mount in a separate PR?
@@ -0,0 +1,1036 @@ | |||
/* | |||
Copyright 2016 The Kubernetes Authors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2017 and for rest of the new files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually it is 2016 in all the files i have checked. Wouldn't that break Bazel if changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, 2017 for all new files should work.
pkg/volume/azure_dd/provisioner.go
Outdated
case "skuname": | ||
storageAccountType = strings.ToLower(v) | ||
case "location": | ||
return nil, fmt.Errorf("AzureDisk - location parameter is not supported anymore in PVC, use PV to use named storage accounts in different locations") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a regression. We use location to create a disk at the same Azure region with compute instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users does not need to provide location, location is picked up from the cloud provider and disks are created in the same resource group. The current implementation does validate location = current (AFAIK) hence is subject to situation where users create disks in different location than the cluster. PVCs and PVs provisioned already will have no impact with this change. only new PVC/PVs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address this.
pkg/volume/azure_dd/provisioner.go
Outdated
case "location": | ||
return nil, fmt.Errorf("AzureDisk - location parameter is not supported anymore in PVC, use PV to use named storage accounts in different locations") | ||
case "storageaccount": | ||
return nil, fmt.Errorf("AzureDisk - storage parameter is not suppoerted anymore in PVC, use PV to use named storage account") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this is not supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because the user has 2 options when doing blob disk, either PVC (dedicated or shared) using a set of storage accounts managed by the plugin or PV in this case the user provides diskuri which includes storage account
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use case for storage account is for a multi tenant setup, providing separate storage account for each tenant.
pkg/volume/azure_dd/provisioner.go
Outdated
for k, v := range p.options.Parameters { | ||
switch strings.ToLower(k) { | ||
case "skuname": | ||
storageAccountType = strings.ToLower(v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
storageAccountType
is assigned twice for skuname and storageaccounttype, what does it really mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because sku is "arm" label not end user label, all Azure documentation and portal refer to it "storage account type". Only when you interact with arm templates you deal with sku. Hence, This should use "storage account type" to avoid confusion, but since there is no risk (as described below) in leaving sku parameter it is left for this version until we remove it from all samples then retire it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not what I read from https://docs.microsoft.com/en-us/rest/api/storagerp/storageaccounts
"Note that in older versions, sku name was called accountType."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skuname and storageAccountType has same meaning here, it's an alias:
Note that in older versions, sku name was called accountType.
type SkuName { Standard_LRS, Standard_GRS, Standard_RAGRS, Standard_ZRS, Premium_LRS }
pkg/volume/azure_dd/common.go
Outdated
return "", err | ||
} | ||
|
||
func formatIfNotFormatted(disk string, fstype string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is mostly identical (except the order of command) with /pkg/util/mount
but bypass mounter and directly call exec.New
to obtain a runner. This is problematic as we are refactoring mounters.
If there is an issue with default mounter, refactor at /pkg/util/mount
, but don't bypass mounter interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as discussed, there is an issue that hangs the format/mount sequence as its is in K8s (it takes 4 mins+ to execute, which is basically a hang). It waits on IO (process in D sate) on Azure. Until we identify exactly what is wrong (either in k8s) & until a fix is applied and taste (either on Azure/k8s or both) we will have to go with this approach since this approach consistently works with predictable format/mount time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This issue is now discussed in #47158
pkg/volume/azure_dd/mounter.go
Outdated
@@ -0,0 +1,179 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
follow the file name convention: the file that implement the plugin is named with the plugin's name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the file is named azure_dd.go, as for mount and attacher i didn't find a consistent naming concision across the plugins. I can prefix all files with azure_dd if that will help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filename prefixed with azure_ for log parsing.
For new files, copyright year stay with 2017
@@ -1,145 +0,0 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep it as we are going to refactor disk utilities among plugins.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this has moved into the common file of the disk controllers. Since this only needed by Blob Disk + Managed Disk (and will always be, since any block device based disks will always use AzureDiskVolumeSource type with the addition of Kind parameter) also they have nothing to do with "vhd" per-se
pkg/volume/azure_dd/mounter.go
Outdated
var _ volume.Unmounter = &azureDiskUnmounter{} | ||
var _ volume.Mounter = &azureDiskMounter{} | ||
|
||
func (m *azureDiskMounter) GetAttributes() volume.Attributes { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed Managed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
pkg/volume/azure_dd/mounter.go
Outdated
} | ||
|
||
// we didn't fail | ||
//TODO: do we need to do this? the bind-mount performs ro mount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is for ownership change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the comment
@khenidak there are many regressions when you remove existing In existing azure_dd.go, you'll find newly added functions such as As we are approaching code freeze, extensive refactoring must be carefully evaluated. |
cc @jdumars |
Support bulk verification and support mount options are there in this PR for a while now including passing the mount options to the mounter during mount. as for signature change if you are referring to referring to UnixxxxID type defs then these have also been included. I went back and verified that this PR includes all the "bulk" changes that happened in volume. including one related to skipping TearDownAt call if the path does not exist (just updated the PR with it). |
pkg/volume/azure_dd/common.go
Outdated
"path" | ||
"regexp" | ||
"strconv" | ||
STRINGS "strings" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upper case words have their meanings in golang. Use other alias e.g. libstrings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pkg/volume/azure_dd/common.go
Outdated
return "", err | ||
} | ||
|
||
func formatIfNotFormatted(disk string, fstype string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IF that's the case, it should be addressed in pkg/util/mount
.
As mentioned, this format hang issue was root caused here
Submit an issue if you see other symptoms or root cause.
return attached, lun, err | ||
} | ||
|
||
fragment := vmData.(map[string]interface{}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not safe, it will panic on unexpected vm
stream. Run unit test below and you'll get a panic.
vm := []byte("foo")
if err := json.Unmarshal(vm, &vmData); err != nil {
return
}
// panic happens!
fragment := vmData.(map[string]interface{})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the check, I have used below code to avoid such conversion issue:
fragment, ok := vmData.(map[string]interface{})
if !ok {
return attached, lun, fmt.Errorf("convert vmData to map error")
}
Also do the checks for the proceeding code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have movoed all the error handling code of json format in func: ExtractVMData, ExtractDiskData in azure_util.go
diskIdTemplate string = "/subscriptions/%s/resourcegroups/%s/providers/microsoft.compute/disks/%s" | ||
defaultDataDiskCount int = 16 // which will allow you to work with most medium size VMs (if not found in map) | ||
|
||
vhdBlobUriTemplate = "https://%s.blob.core.windows.net/%s/%s" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not accurate. You have to choose among core.windows.net
, core.usgovcloudapi.net
, etc....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the hint, I have used az.Environment.StorageEndpointSuffix
|
||
const ( | ||
aadTokenEndPointPath string = "%s/oauth2/token/" | ||
apiversion string = "2016-04-30-preview" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This apiversion is not supported in every azure region
https://github.com/Azure/azure-xplat-cli/issues/3513
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For ARM, The supported api-versions are '2016-04-30-preview, 2017-03-30' in global azure. So for other regions, like azure china, just wait for the api version update or do customerization if want to use it ASAP.
pkg/volume/azure_dd/common.go
Outdated
return cachingMode, nil | ||
} | ||
|
||
type ioHandler interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep vhd_util.go file and its unit test.
@khenidak address these concerns and ping me or other members from @kubernetes/sig-storage-pr-reviews when you are done Make CI test pass.None of the CI tests have passed yet. Run Unit test new functionsEspecially those in raw HTTP, there are many uncaptured errors. Refactoring:
Compatibility
Raw HTTP:
Address review comments from @brendandburns in #41950cc @jdumars |
return err | ||
} | ||
|
||
func (c *blobDiskController) diskHasNoLease(diskUri string) (bool, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @colemickens
As advised by Joseph Romeo by email: "Avoid looking at VHD blob leases to decide a disk is attached or detached. This can lead you to unexpected failures or worse-case get into a bad state."
pkg/volume/azure_dd/attacher.go
Outdated
cachingMode := string(*volumeSource.CachingMode) | ||
managed := (*volumeSource.Kind == v1.AzureManagedDisk) | ||
if managed { | ||
lun, err = a.plugin.diskController.AttachManagedDisk(string(nodeName), volumeSource.DataDiskURI, cachingMode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nodeName != InstanceID
refer to https://github.com/kubernetes/kubernetes/blob/master/pkg/volume/azure_dd/attacher.go#L76
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi, we use nodeName to get the vm object, see in AttachManagedDisk func:
vm, err := c.common.getArmVM(nodeName)
} | ||
|
||
// finds an empty based on VM size and current attached disks | ||
func findEmptyLun(vmSize string, dataDisks []interface{}) (int, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How to deal with race condition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have used lock in this func
pkg/volume/azure_dd/provisioner.go
Outdated
kind = v1.AzureDataDiskKind(v) | ||
case "cachingmode": | ||
cachingMode = v1.AzureDataDiskCachingMode(v) | ||
case "fstype": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@khenidak: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
/retest |
@brendandburns Thanks for reviewing. I've got the test fix commit karataliu@3ed5502 verified, and it has been squashed into the final single commit 677e593 here. |
/lgtm |
/approve no-issue |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: brendandburns, khenidak, roberthbailey, thockin Associated issue requirement bypassed by: brendandburns The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
Automatic merge from submit-queue |
Removing label |
…ase-1.7' of https://github.com/seanknox/kubernetes into automated-cherry-pick-of-kubernetes#46360-upstream-release-1.7
Hi @nmakhotkin , the code is already in 1.7.2, let me know if you have any question. |
@andyzhangx thanks! I'll try it. |
Commit found in the "release-1.8" branch appears to be this PR. Removing the "cherrypick-candidate" label. If this is an error find help to get your PR picked. |
Release Note: Adds Kubernetes support for Azure Managed Disks, support for dedicated blob disks (1:1 to storage account) in addition to shared blob disks (n:1 to storage account), and automatically manages the underlying storage accounts. New storage accounts are created at 50% utilization. Max is 100 disks, 60 disks per storage account. Due to the change in mounting paths, existing PDs need to be recreated as either PV or PVCs with the new plugin. |
This is exactly the same code as this PR. It has a clean set of generated items. We created a separate PR to accelerate the accept/merge the PR
CC @colemickens
CC @brendandburns
What this PR does / why we need it:
..* Significantly faster attach process. Disks are now usually available for pods on nodes under 30 sec if formatted, under a min if not formatted.
..* Adds support to move disks between nodes.
..* Adds consistent attach/detach behavior, checks if the disk is leased/attached on a different node before attempting to attach to target nodes.
..* Fixes a random hang behavior on Azure VMs during mount/format (for both blob + managed disks).
..* Fixes a potential conflict by avoiding the use of disk names for mount paths. The new plugin uses hashed disk uri for mount path.
The existing AzureDisk is used as is. Additional "kind" property was added allowing the user to decide if the pd will be shared, dedicated or managed (Azure Managed Disks are used).
Due to the change in mounting paths, existing PDs need to be recreated as PV or PVCs on the new plugin.