Allow Kubelet to run with no Azure identity

useInstanceMetadata should be enabled and Kubelet would use IMDS to get
node's information.
This commit is contained in:
Pengfei Ni 2019-05-15 14:24:43 +08:00
parent b066e0d783
commit b13d80a59a
3 changed files with 72 additions and 37 deletions

View File

@ -28,6 +28,11 @@ import (
"k8s.io/klog" "k8s.io/klog"
) )
var (
// ErrorNoAuth indicates that no credentials are provided.
ErrorNoAuth = fmt.Errorf("no credentials provided for Azure cloud provider")
)
// AzureAuthConfig holds auth related part of cloud config // AzureAuthConfig holds auth related part of cloud config
type AzureAuthConfig struct { type AzureAuthConfig struct {
// The cloud environment identifier. Takes values from https://github.com/Azure/go-autorest/blob/ec5f4903f77ed9927ac95b19ab8e44ada64c1356/autorest/azure/environments.go#L13 // The cloud environment identifier. Takes values from https://github.com/Azure/go-autorest/blob/ec5f4903f77ed9927ac95b19ab8e44ada64c1356/autorest/azure/environments.go#L13
@ -104,7 +109,7 @@ func GetServicePrincipalToken(config *AzureAuthConfig, env *azure.Environment) (
env.ServiceManagementEndpoint) env.ServiceManagementEndpoint)
} }
return nil, fmt.Errorf("No credentials provided for AAD application %s", config.AADClientID) return nil, ErrorNoAuth
} }
// ParseAzureEnvironment returns azure environment by name // ParseAzureEnvironment returns azure environment by name

View File

@ -248,7 +248,14 @@ func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) {
} }
servicePrincipalToken, err := auth.GetServicePrincipalToken(&config.AzureAuthConfig, env) servicePrincipalToken, err := auth.GetServicePrincipalToken(&config.AzureAuthConfig, env)
if err != nil { 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 {
return nil, err return nil, err
} }
@ -348,6 +355,27 @@ func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) {
} }
} }
az := Cloud{
Config: *config,
Environment: *env,
nodeZones: map[string]sets.String{},
nodeResourceGroups: map[string]string{},
unmanagedNodes: sets.NewString(),
routeCIDRs: map[string]string{},
resourceRequestBackoff: resourceRequestBackoff,
}
az.metadata, err = NewInstanceMetadataService(metadataURL)
if err != nil {
return nil, err
}
// 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{ azClientConfig := &azClientConfig{
subscriptionID: config.SubscriptionID, subscriptionID: config.SubscriptionID,
resourceManagerEndpoint: env.ResourceManagerEndpoint, resourceManagerEndpoint: env.ResourceManagerEndpoint,
@ -358,36 +386,21 @@ func NewCloud(configReader io.Reader) (cloudprovider.Interface, error) {
CloudProviderBackoffDuration: config.CloudProviderBackoffDuration, CloudProviderBackoffDuration: config.CloudProviderBackoffDuration,
ShouldOmitCloudProviderBackoff: config.shouldOmitCloudProviderBackoff(), ShouldOmitCloudProviderBackoff: config.shouldOmitCloudProviderBackoff(),
} }
az := Cloud{ az.DisksClient = newAzDisksClient(azClientConfig)
Config: *config, az.SnapshotsClient = newSnapshotsClient(azClientConfig)
Environment: *env, az.RoutesClient = newAzRoutesClient(azClientConfig)
nodeZones: map[string]sets.String{}, az.SubnetsClient = newAzSubnetsClient(azClientConfig)
nodeResourceGroups: map[string]string{}, az.InterfacesClient = newAzInterfacesClient(azClientConfig)
unmanagedNodes: sets.NewString(), az.RouteTablesClient = newAzRouteTablesClient(azClientConfig)
routeCIDRs: map[string]string{}, az.LoadBalancerClient = newAzLoadBalancersClient(azClientConfig)
resourceRequestBackoff: resourceRequestBackoff, az.SecurityGroupsClient = newAzSecurityGroupsClient(azClientConfig)
az.StorageAccountClient = newAzStorageAccountClient(azClientConfig)
DisksClient: newAzDisksClient(azClientConfig), az.VirtualMachinesClient = newAzVirtualMachinesClient(azClientConfig)
SnapshotsClient: newSnapshotsClient(azClientConfig), az.PublicIPAddressesClient = newAzPublicIPAddressesClient(azClientConfig)
RoutesClient: newAzRoutesClient(azClientConfig), az.VirtualMachineSizesClient = newAzVirtualMachineSizesClient(azClientConfig)
SubnetsClient: newAzSubnetsClient(azClientConfig), az.VirtualMachineScaleSetsClient = newAzVirtualMachineScaleSetsClient(azClientConfig)
InterfacesClient: newAzInterfacesClient(azClientConfig), az.VirtualMachineScaleSetVMsClient = newAzVirtualMachineScaleSetVMsClient(azClientConfig)
RouteTablesClient: newAzRouteTablesClient(azClientConfig), az.FileClient = &azureFileClient{env: *env}
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},
}
az.metadata, err = NewInstanceMetadataService(metadataURL)
if err != nil {
return nil, err
}
if az.MaximumLoadBalancerRuleCount == 0 { if az.MaximumLoadBalancerRuleCount == 0 {
az.MaximumLoadBalancerRuleCount = maximumLoadBalancerRuleCount az.MaximumLoadBalancerRuleCount = maximumLoadBalancerRuleCount

View File

@ -83,7 +83,12 @@ func (az *Cloud) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.N
// Not local instance, get addresses from Azure ARM API. // Not local instance, get addresses from Azure ARM API.
if !isLocalInstance { if !isLocalInstance {
return addressGetter(name) 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")
} }
if len(metadata.Network.Interface) == 0 { if len(metadata.Network.Interface) == 0 {
@ -242,7 +247,12 @@ func (az *Cloud) InstanceID(ctx context.Context, name types.NodeName) (string, e
// Not local instance, get instanceID from Azure ARM API. // Not local instance, get instanceID from Azure ARM API.
if !isLocalInstance { if !isLocalInstance {
return az.vmSet.GetInstanceIDByNodeName(nodeName) 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")
} }
// Get resource group name. // Get resource group name.
@ -316,10 +326,17 @@ func (az *Cloud) InstanceType(ctx context.Context, name types.NodeName) (string,
if err != nil { if err != nil {
return "", err return "", err
} }
if isLocalInstance { if !isLocalInstance {
if metadata.Compute.VMSize != "" { if az.vmSet != nil {
return metadata.Compute.VMSize, nil return az.vmSet.GetInstanceTypeByNodeName(string(name))
} }
// 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
} }
} }