Change:
Currently there is no way to run without any identity (be it service principal or E/MSI). In reality code running on a worker node can use via - and only via - without the need to access ARM. Here is the proposed change a new mode authN = this mode, is basically telling the cloud provider to work any identity, this means only IMDS calls is allowed. This mode can be detected from if no SPN set and both MSI settings are set to . to use a config map within the cluster. This config map can be loaded on the cluster statically. or created - if not existent - in that then only is used in The net new result of the above is users bootstrapping clusters can configure the worker node to use without any identity on said worker nodes.
/sig azure These SIGs are my best guesses for this issue. Please comment if I am incorrect about one. I am a bot run by ‍
In-tree AzureDisk volume plugin is also depending on Azure credential to fetch lun id. we should figure out how to solve it without credential
fetch disk lun id is also a dependency in kubelet code now, after my investigation, it could be removed on Linux node, while it cannot be removed on Windows node, need to change the k/k upstream code, there is a discussion on going here: , let' wait for the discussion result.
For Linux: 1- use IMDS my understanding is new api versions will have the disk/lun pairs. 2- don't use arm for the return of is the second parameter passed to . For Windows: I don't understand the dep on ARM for this. The above still apply, we just need to find a way to encode the value as ut return from that allow us to find the disk by on a windows machine. might be a good source for this. Ideally speaking. The value should be the same. But i will leave it for you to decide.
could be a good idea since currently it's a LUN num returned by Attach() and then it could be changed to the windows disk num, I will make the code change on v1.15 later, thanks for discussion.
Update: PR would remove the VM API calls when getting the LUN number for AzureDisk.

Discussion:
"k8s.io/klog" ) <ins> var ( // ErrorNoAuth indicates that no credentials are provided. ErrorNoAuth = fmt.Errorf("no credentials provided for Azure cloud provider") ) </ins> // AzureAuthConfig holds auth related part of cloud config type AzureAuthConfig struct { // The cloud environment identifier. Takes values from https://github.com/Azure/go-autorest/blob/ec5f4903f77ed9927ac95b19ab8e44ada64c1356/autorest/azure/environments.go#L13

env.ServiceManagementEndpoint) } <del> return nil, fmt.Errorf("No credentials provided for AAD application %s", config.AADClientID) </del> <ins> return nil, ErrorNoAuth </ins> } // ParseAzureEnvironment returns azure environment by name

} servicePrincipalToken, err := auth.GetServicePrincipalToken(&config.AzureAuthConfig, env) <del> if err != nil { </del> <ins> if err == auth.ErrorNoAuth { if !config.UseInstanceMetadata { // No credentials provided, useInstanceMetadata should be enabled. return nil, fmt.Errorf("useInstanceMetadata must be enabled without Azure credentials") } klog.V(2).Infof("Azure cloud provider is starting without credentials") } else if err != nil { </ins> return nil, err }

} } <del> azClientConfig := &azClientConfig{ subscriptionID:                 config.SubscriptionID, resourceManagerEndpoint:        env.ResourceManagerEndpoint, servicePrincipalToken:          servicePrincipalToken, rateLimiterReader:              operationPollRateLimiter, rateLimiterWriter:              operationPollRateLimiterWrite, CloudProviderBackoffRetries:    config.CloudProviderBackoffRetries, CloudProviderBackoffDuration:   config.CloudProviderBackoffDuration, ShouldOmitCloudProviderBackoff: config.shouldOmitCloudProviderBackoff(), } </del> az := Cloud{ Config:                 *config, Environment:            *env,

unmanagedNodes:         sets.NewString(), routeCIDRs:             map[string]string{}, resourceRequestBackoff: resourceRequestBackoff, <del> DisksClient:                     newAzDisksClient(azClientConfig), SnapshotsClient:                 newSnapshotsClient(azClientConfig), RoutesClient:                    newAzRoutesClient(azClientConfig), SubnetsClient:                   newAzSubnetsClient(azClientConfig), InterfacesClient:                newAzInterfacesClient(azClientConfig), RouteTablesClient:               newAzRouteTablesClient(azClientConfig), LoadBalancerClient:              newAzLoadBalancersClient(azClientConfig), SecurityGroupsClient:            newAzSecurityGroupsClient(azClientConfig), StorageAccountClient:            newAzStorageAccountClient(azClientConfig), VirtualMachinesClient:           newAzVirtualMachinesClient(azClientConfig), PublicIPAddressesClient:         newAzPublicIPAddressesClient(azClientConfig), VirtualMachineSizesClient:       newAzVirtualMachineSizesClient(azClientConfig), VirtualMachineScaleSetsClient:   newAzVirtualMachineScaleSetsClient(azClientConfig), VirtualMachineScaleSetVMsClient: newAzVirtualMachineScaleSetVMsClient(azClientConfig), FileClient:                      &azureFileClient{env: *env}, </del> } az.metadata, err = NewInstanceMetadataService(metadataURL) if err != nil { return nil, err } <ins> // No credentials provided, InstanceMetadataService would be used for getting Azure resources. // Note that this only applies to Kubelet, controller-manager should configure credentials for managing Azure resources. if servicePrincipalToken == nil { return &az, nil } // Initialize Azure clients. azClientConfig := &azClientConfig{ subscriptionID:                 config.SubscriptionID, resourceManagerEndpoint:        env.ResourceManagerEndpoint, servicePrincipalToken:          servicePrincipalToken, rateLimiterReader:              operationPollRateLimiter, rateLimiterWriter:              operationPollRateLimiterWrite, CloudProviderBackoffRetries:    config.CloudProviderBackoffRetries, CloudProviderBackoffDuration:   config.CloudProviderBackoffDuration, ShouldOmitCloudProviderBackoff: config.shouldOmitCloudProviderBackoff(), } az.DisksClient = newAzDisksClient(azClientConfig) az.SnapshotsClient = newSnapshotsClient(azClientConfig) az.RoutesClient = newAzRoutesClient(azClientConfig) az.SubnetsClient = newAzSubnetsClient(azClientConfig) az.InterfacesClient = newAzInterfacesClient(azClientConfig) az.RouteTablesClient = newAzRouteTablesClient(azClientConfig) az.LoadBalancerClient = newAzLoadBalancersClient(azClientConfig) az.SecurityGroupsClient = newAzSecurityGroupsClient(azClientConfig) az.StorageAccountClient = newAzStorageAccountClient(azClientConfig) az.VirtualMachinesClient = newAzVirtualMachinesClient(azClientConfig) az.PublicIPAddressesClient = newAzPublicIPAddressesClient(azClientConfig) az.VirtualMachineSizesClient = newAzVirtualMachineSizesClient(azClientConfig) az.VirtualMachineScaleSetsClient = newAzVirtualMachineScaleSetsClient(azClientConfig) az.VirtualMachineScaleSetVMsClient = newAzVirtualMachineScaleSetVMsClient(azClientConfig) az.FileClient = &azureFileClient{env: *env} </ins> if az.MaximumLoadBalancerRuleCount == 0 { az.MaximumLoadBalancerRuleCount = maximumLoadBalancerRuleCount }

// Not local instance, get addresses from Azure ARM API. if !isLocalInstance { <del> return addressGetter(name) </del> <ins> if az.vmSet != nil { return addressGetter(name) } // vmSet == nil indicates credentials are not provided. return nil, fmt.Errorf("no credentials provided for Azure cloud provider") </ins> } if len(metadata.Network.Interface) == 0 {

// Not local instance, get instanceID from Azure ARM API. if !isLocalInstance { <del> return az.vmSet.GetInstanceIDByNodeName(nodeName) </del> <ins> if az.vmSet != nil { return az.vmSet.GetInstanceIDByNodeName(nodeName) } // vmSet == nil indicates credentials are not provided. return "", fmt.Errorf("no credentials provided for Azure cloud provider") </ins> } // Get resource group name.

if err != nil { return "", err } <del> if isLocalInstance { if metadata.Compute.VMSize != "" { return metadata.Compute.VMSize, nil </del> <ins> if !isLocalInstance { if az.vmSet != nil { return az.vmSet.GetInstanceTypeByNodeName(string(name)) </ins> } <ins> // vmSet == nil indicates credentials are not provided. return "", fmt.Errorf("no credentials provided for Azure cloud provider") } if metadata.Compute.VMSize != "" { return metadata.Compute.VMSize, nil </ins> } }