Skip to content
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 cloud provider: expose services on non-default subnets #51757

Merged

Conversation

itowlson
Copy link
Contributor

@itowlson itowlson commented Sep 1, 2017

What this PR does / why we need it: The Azure cloud provider allows users to specify that a service should be exposed on an internal load balancer instead of the default external load balancer. However, in a VNet environment, such services are currently always exposed on the master subnet. Where there are multiple subnets in the VNet, it's desirable to be able to expose an internal service on any subnet. This PR allows this via a new annotation, service.beta.kubernetes.io/azure-load-balancer-internal-subnet.

Which issue this PR fixes: fixes Azure/acs-engine#1296 (no corresponding issue has been raised in the k8s core repo)

Special notes for your reviewer: None

Release note:

A new service annotation has been added for services of type LoadBalancer on Azure, 
to specify the subnet on which the service's front end IP should be provisioned. The 
annotation is service.beta.kubernetes.io/azure-load-balancer-internal-subnet and its 
value is the subnet name (not the subnet ARM ID).  If omitted, the default is the 
master subnet.  It is ignored if the service is not on Azure, if the type is not 
LoadBalancer, or if the load balancer is not internal.

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Sep 1, 2017
@k8s-ci-robot
Copy link
Contributor

Hi @itowlson. 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 /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

I understand the commands that are listed here.

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.

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Sep 1, 2017
@k8s-github-robot k8s-github-robot added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Sep 1, 2017
@itowlson
Copy link
Contributor Author

itowlson commented Sep 1, 2017

/assign jdumars

@jdumars jdumars added the do-not-merge DEPRECATED. Indicates that a PR should not merge. Label can only be manually applied/removed. label Sep 1, 2017
@jdumars
Copy link
Member

jdumars commented Sep 1, 2017

/ok-to-test

@k8s-ci-robot k8s-ci-robot removed the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Sep 1, 2017
@itowlson
Copy link
Contributor Author

itowlson commented Sep 2, 2017

/retest

3 similar comments
@itowlson
Copy link
Contributor Author

itowlson commented Sep 2, 2017

/retest

@itowlson
Copy link
Contributor Author

itowlson commented Sep 2, 2017

/retest

@itowlson
Copy link
Contributor Author

itowlson commented Sep 2, 2017

/retest

@jdumars
Copy link
Member

jdumars commented Sep 2, 2017

/test pull-kubernetes-kubemark-e2e-gce

1 similar comment
@itowlson
Copy link
Contributor Author

itowlson commented Sep 3, 2017

/test pull-kubernetes-kubemark-e2e-gce

@piosz piosz assigned bowei and brendandburns and unassigned brendandburns and piosz Sep 5, 2017
@@ -366,7 +374,7 @@ func (az *Cloud) cleanupLoadBalancer(clusterName string, service *v1.Service, is

if !isInternalLb {
// Find public ip resource to clean up from IP configuration
lbFrontendIPConfigName := getFrontendIPConfigName(service)
lbFrontendIPConfigName := getFrontendIPConfigName(service, subnet(service))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use nil for subnet name.

Consider the case user switching from 'external loadbalancer (no subnet)' to 'internal loadbalancer with specified subnet'.
During external loadbalancer creating, it uses name where subnet is empty.

When switching to 'internal loadbalancer', it will first clean corresponding entry on the external loadblancer. But this time 'subnet' value is not empty.

The 'subnet-unset' value is compared with 'subnet-set' value, resulting a unmatch. Thus later the public IP for external loadbalancer will remain undeleted.

@@ -523,7 +531,7 @@ func (az *Cloud) reconcileLoadBalancer(lb network.LoadBalancer, fipConfiguration
isInternal := requiresInternalLoadBalancer(service)
lbName := getLoadBalancerName(clusterName, isInternal)
serviceName := getServiceName(service)
lbFrontendIPConfigName := getFrontendIPConfigName(service)
lbFrontendIPConfigName := getFrontendIPConfigName(service, subnet(service))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should only make use of 'ServiceAnnotationLoadBalancerInternalSubnet, when isInternal is true?

If user expects external loadbalancer, but also specifies ServiceAnnotationLoadBalancerInternalSubnet, we should ignore the annotation since it does not make sense, or just leave a warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by making subnet check that the Internal annotation is also present.

@@ -575,6 +583,14 @@ func (az *Cloud) reconcileLoadBalancer(lb network.LoadBalancer, fipConfiguration
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for 'if !wantLb {' section in 'https://github.com/kubernetes/kubernetes/pull/51757/files#diff-c901394068476b4ccb003a6c6efad57cR579', since github doesn't allow comment on unmodified code.

strings.EqualFold(*config.Name, lbFrontendIPConfigName) also needs update to 'serviceOwnsFrontEndIP'.

For a corner case:
Switching from 'internal LB with subnetA' to 'external LB with subnetB', the frontendIP won't get deleted.

Though this does not sound a good user input, but we need to ensure previous created frontendIP entry get deleted.

@@ -575,6 +583,14 @@ func (az *Cloud) reconcileLoadBalancer(lb network.LoadBalancer, fipConfiguration
}
}
} else {
for i := len(newConfigs) - 1; i >= 0; i-- {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should only do this for internal LB

}

func getSecurityRuleName(service *v1.Service, port v1.ServicePort, sourceAddrPrefix string) string {
func getSecurityRuleName(service *v1.Service, port v1.ServicePort, subnetName *string, sourceAddrPrefix string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to update this?

securityRuleName embeds information for service id, port, sourceAddrePrefix, which is part of security group rule. subnetName does not play a role here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, this isn't needed. I thought it was needed so that old security rules got replaced with new ones during an edit that changed the subnet, but looking at the properties, you're correct that we can just keep the existing rule. Thanks!

lb := getTestLoadBalancer()
nodes := []*v1.Node{}

svc.Spec.Ports = append(svc.Spec.Ports, v1.ServicePort{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add port here?

@@ -887,3 +985,8 @@ func TestMetadataParsing(t *testing.T) {
t.Errorf("Unexpected inequality:\n%#v\nvs\n%#v", network, networkJSON)
}
}

func addTestSubnet(svc *v1.Service) {
svc.Annotations[ServiceAnnotationLoadBalancerInternal] = "true"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider make use of getInternalTestService, and leave this func add subnet only.

@@ -224,8 +230,17 @@ func serviceOwnsRule(service *v1.Service, rule string) bool {
return strings.HasPrefix(strings.ToUpper(rule), strings.ToUpper(prefix))
}

func getFrontendIPConfigName(service *v1.Service) string {
return cloudprovider.GetLoadBalancerName(service)
func serviceOwnsFrontEndIP(fip network.FrontendIPConfiguration, service *v1.Service) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frontend

if err != nil {
t.Errorf("Unexpected error reconciling initial svc: %q", err)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also validate FrontendIPConfigurations before editing subnet

az := getTestCloud()
svc := getTestService("servicea", v1.ProtocolTCP, 80)
addTestSubnet(&svc)
configProperties := getTestPublicFipConfigurationProperties()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is logically incorrect, the property is for public IP case, though not validated in reconcileLoadBalancer.

@itowlson itowlson force-pushed the azure-load-balancer-subnet-redux branch from d0f3d04 to 55d4299 Compare September 7, 2017 03:06
@itowlson
Copy link
Contributor Author

itowlson commented Sep 7, 2017

@karataliu Thanks for the detailed review - I appreciate your time. I think I've addressed the issues you've identified; please let me know if there are still outstanding problems.

@itowlson
Copy link
Contributor Author

itowlson commented Sep 7, 2017

/retest

Copy link
Contributor

@karataliu karataliu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -67,6 +67,101 @@ func TestReconcileLoadBalancerAddPort(t *testing.T) {
validateLoadBalancer(t, lb, svc)
}

// Test additional of a new service/port on an internal LB with a subnet.
Copy link
Contributor

@karataliu karataliu Sep 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"a new service", since no 'adding port' operation now.

@karataliu
Copy link
Contributor

@itowlson Just added a note for one line in test comment. Others look good.

@itowlson itowlson force-pushed the azure-load-balancer-subnet-redux branch from 55d4299 to 125a054 Compare September 8, 2017 00:04
@itowlson
Copy link
Contributor Author

itowlson commented Sep 8, 2017

/retest

@brendandburns
Copy link
Contributor

/lgtm
/approve no-isssue

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 12, 2017
@brendandburns brendandburns added this to the v1.9 milestone Sep 12, 2017
@brendandburns brendandburns added approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed do-not-merge DEPRECATED. Indicates that a PR should not merge. Label can only be manually applied/removed. labels Sep 12, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: brendandburns, itowlson

No associated issue. Update pull-request body to add a reference to an issue, or get approval with /approve no-issue

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 /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

5 similar comments
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 50294, 50422, 51757, 52379, 52014). If you want to cherry-pick this change to another branch, please follow the instructions here..

@k8s-github-robot k8s-github-robot merged commit 8a638c6 into kubernetes:master Sep 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

kubernetes/azure-cloud-provider: Enable annotation to specify subnet to create Azure load-balancer
9 participants