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

Add V2 frontend namer #892

Merged
merged 1 commit into from
Nov 16, 2019
Merged

Add V2 frontend namer #892

merged 1 commit into from
Nov 16, 2019

Conversation

skmatti
Copy link
Contributor

@skmatti skmatti commented Oct 15, 2019

This part4 of V2 Namer Migration: #858.
Fixes: #537

This PR introduces a new naming scheme for for the following frontend resources:

  • Forwarding Rule
  • Target Proxy
  • URL Map
  • SSL Certificates
  • Ingress managed Static IP

This should resolve frontend resource naming collision issues.

The changes made in v2 naming scheme:

  • New naming scheme:
    k8s{version-id}-{resource-prefix}-{8-char-hash-of-kube-system-uid}-{namespace}-{name}-{8-char-hash}
    Namespace and Name are truncated evenly until their combined length is 36 in case of overflows. The 8 character suffix hash is created from full namespace and name.

Example http target proxy: k8s2-tp-ksuid123-namespace-name-wddys49o

  • Resource names will include an 8 character kube-system uid instead of cluster uid. This makes the new naming policy immune to config map(which tracks cluster uid) changes.

Frontend GC workflow changes:

  • New GC workflow for v2 naming scheme
    • GC will be invoked only on the ingress being synced.
    • GC workflow will not leak any GCE resources.

GC workflow

  • If finalizer is disabled
    • GC workflow is untouched i.e, run GC for all ingresses
  • If finalizer is enabled
    • If ingress being synced needs cleanup
      • Frontend GC
        • if V1 naming scheme - run frontend GC for all v1 ingresses.
        • if V2 naming scheme - run frontend GC for ingress being synced.
      • Backend GC - run for all ingresses.
      • Ensure delete finalizers
        • if V1 naming scheme - remove finalizers for all v1 ingresses.
        • if V2 naming scheme - remove finalizer for ingress being synced.
    • If ingress being synced does not need cleanup
      • Backend GC - run for all ingresses.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Oct 15, 2019
@k8s-ci-robot
Copy link
Contributor

Hi @skmatti. 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.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

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.

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Oct 15, 2019
@skmatti
Copy link
Contributor Author

skmatti commented Oct 15, 2019

/assign @freehan

@skmatti
Copy link
Contributor Author

skmatti commented Oct 15, 2019

/assign @bowei

@freehan
Copy link
Contributor

freehan commented Oct 18, 2019

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Oct 18, 2019
@skmatti skmatti force-pushed the v2-namer branch 2 times, most recently from 9aac2ff to 1ae1340 Compare October 21, 2019 20:07
Copy link
Contributor

@freehan freehan left a comment

Choose a reason for hiding this comment

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

more to come

pkg/utils/common/common.go Show resolved Hide resolved
pkg/utils/common/common.go Show resolved Hide resolved
pkg/controller/controller.go Outdated Show resolved Hide resolved
pkg/utils/common/finalizer.go Outdated Show resolved Hide resolved
pkg/utils/common/finalizer.go Outdated Show resolved Hide resolved
pkg/loadbalancers/interfaces.go Outdated Show resolved Hide resolved
pkg/loadbalancers/l7s.go Outdated Show resolved Hide resolved
pkg/loadbalancers/l7s.go Outdated Show resolved Hide resolved
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 25, 2019
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 25, 2019
@skmatti skmatti force-pushed the v2-namer branch 3 times, most recently from aa060b9 to 74dad25 Compare October 29, 2019 23:59
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 29, 2019
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 30, 2019
pkg/controller/controller.go Show resolved Hide resolved
pkg/loadbalancers/interfaces.go Outdated Show resolved Hide resolved
pkg/sync/interfaces.go Outdated Show resolved Hide resolved
pkg/utils/utils.go Show resolved Hide resolved
pkg/utils/namer/frontendnamer.go Outdated Show resolved Hide resolved
}

// ForwardingRule returns the name of forwarding rule based on given protocol.
func (vn *V2IngressFrontendNamer) ForwardingRule(protocol NamerProtocol) string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please address this.

pkg/utils/namer/frontendnamer.go Show resolved Hide resolved
"%s2-um-ksuid123-012345678901234567-012345678901234567-4mwbp6m5",
},
}
for _, prefix := range []string{"k8s", "mci"} {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is "mci" 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.

Testing this with different prefixes, it could have been any random word.

Copy link
Member

Choose a reason for hiding this comment

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

I would change it to "arbitrary-prefix" to make that clear.

cmd/glbc/main.go Outdated Show resolved Hide resolved
cmd/glbc/main.go Outdated Show resolved Hide resolved
@@ -80,3 +86,27 @@ func DecodeIngress(data []byte) (*v1beta1.Ingress, error) {

return obj.(*v1beta1.Ingress), nil
}

// Flag is a type representing controller flag.
type Flag string
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this used for? I don't see it used anywhere in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is used for saving flags when overriding them in unit tests. This potentially other tests from using the value set by a test.
Made this variable private as all of its uses are within the file.

@skmatti skmatti force-pushed the v2-namer branch 2 times, most recently from efc27ee to a3d1201 Compare November 14, 2019 20:31

var syncErr error
// Perform GC as a deferred function.
defer func() {
Copy link
Member

@bowei bowei Nov 14, 2019

Choose a reason for hiding this comment

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

I very much dislike doing complex actions like this in a defer call as it is very hard to understand the code flow (almost like exception handling in C++/Java).

Can we make this a helper function and call it on the appropriate error paths?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We wanted to have a single function to handle all GC paths. But, I guess this makes it very hard to understand. Modified this back to the original workflow.

lbc.ctx.Recorder(ing.Namespace).Eventf(ing, apiv1.EventTypeWarning, "Translate", msg.Error())
return msg
err = fmt.Errorf("error while evaluating the ingress spec: %v", utils.JoinErrs(errs))
lbc.ctx.Recorder(ing.Namespace).Eventf(ing, apiv1.EventTypeWarning, "Translate", err.Error())
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why we don't always emit an event on all error paths?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add events for GC errors

// ensureFinalizer ensures that a finalizer is attached.
func (lbc *LoadBalancerController) ensureFinalizer(ing *v1beta1.Ingress) error {
if !flags.F.FinalizerAdd {
klog.V(4).Infof("Adding finalizers not enabled")
Copy link
Member

Choose a reason for hiding this comment

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

Error log

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we need to error out if finalizer is not enabled. Moved this check outside so this function does what the name says.

@bowei
Copy link
Member

bowei commented Nov 14, 2019

Can we make sure that all major actions (deleting, adding finalizer) will result in a log line at V(2)?

return err
}
if err := common.EnsureFinalizer(ing, ingClient, finalizerKey); err != nil {
klog.Errorf("common.EnsureFinalizer(%q, _, %q) = %v, want nil", ingKey, finalizerKey, err)
Copy link
Member

Choose a reason for hiding this comment

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

leave out ", want nil", it's redundant

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Seems like underlying call should be a "PATCH" -- can fix this later, file a bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a TODO

// - Does not need cleanup
// - Finalizer enabled : all backends
// - Finalizer disabled : v1 frontends and all backends
func gcPath(ingExists bool, ing *v1beta1.Ingress) (namer.Scheme, bool) {
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't we call this gcNamingScheme?

Copy link
Member

Choose a reason for hiding this comment

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

Can we make the return value less error prone? I think you want to return one of three values, but it's being expressed as a pair ({v1|v2}, bool)

type gcAlgorithm int

const (
  noCleanupNeeded gcAlgorithm = iota
  cleanupV1FrontendResources
  cleanupV2FrontendResources
)

func gcAlgorithmForIngress(ingExists ...) gcAlgorithm {
  ...
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -46,7 +46,7 @@ func newFirewallController() *FirewallController {
DefaultBackendSvcPort: test.DefaultBeSvcPort,
}

ctx := context.NewControllerContext(nil, kubeClient, backendConfigClient, nil, fakeGCE, defaultNamer, ctxConfig)
ctx := context.NewControllerContext(nil, kubeClient, backendConfigClient, nil, fakeGCE, defaultNamer, "", ctxConfig)
Copy link
Member

Choose a reason for hiding this comment

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

for raw consts empty string, we usually put the name of the variable to aid the reader:
ctx := context.NewControllerContext(nil, kubeClient, backendConfigClient, nil, fakeGCE, defaultNamer, /*kubeSystemUID*/"", ctxConfig)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure if this needed for tests. gofmt changes this to,
"" /*kubeSystemUID*/
Added this anyway.

@bowei
Copy link
Member

bowei commented Nov 14, 2019

Looks pretty good, almost there

@skmatti skmatti force-pushed the v2-namer branch 9 times, most recently from b371731 to 86fe9a5 Compare November 15, 2019 04:53
return err
}
}
return nil
}

// EnsureDeleteV2Finalizer implements Controller.
func (lbc *LoadBalancerController) EnsureDeleteV2Finalizer(ing *v1beta1.Ingress) error {
Copy link
Member

Choose a reason for hiding this comment

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

This function never returns anything but nil for error.
Either remove the return value or figure out if the error needs to be propagated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should return error. Fixed

pkg/controller/controller.go Outdated Show resolved Hide resolved
pkg/controller/controller.go Show resolved Hide resolved
pkg/controller/controller.go Outdated Show resolved Hide resolved
@@ -70,8 +70,21 @@ const (
// ToBeDeletedTaint is the taint that the autoscaler adds when a node is scheduled to be deleted
// https://github.com/kubernetes/autoscaler/blob/cluster-autoscaler-0.5.2/cluster-autoscaler/utils/deletetaint/delete.go#L33
ToBeDeletedTaint = "ToBeDeletedByClusterAutoscaler"

// NoCleanUpNeeded, CleanupV1FrontendResources and CleanupV2FrontendResources
// are used to specify the frontend GC algorithm.
Copy link
Member

Choose a reason for hiding this comment

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

does this type have to be in util package (or exported)

put the constants with the type so the reader doesn't have to search around to find where they are defined.

type FrontendGCAlgorithm int
const (
  // NoCleanUpNeeded ...
  ...
)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, needs to used in both controller and sync packages.

return false
}

// LbName returns loadbalancer name.
Copy link
Member

Choose a reason for hiding this comment

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

You should document what LbName is used for. Is it the name of a GCP resource or something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is used for generating GCP resource names, added a comment.

pkg/utils/namer/frontendnamer.go Outdated Show resolved Hide resolved
pkg/utils/namer/frontendnamer.go Outdated Show resolved Hide resolved
pkg/utils/namer/frontendnamer.go Outdated Show resolved Hide resolved
pkg/utils/namer/utils.go Outdated Show resolved Hide resolved
@@ -65,7 +65,7 @@ func fakeTranslator() *Translator {
HealthCheckPath: "/",
DefaultBackendHealthCheckPath: "/healthz",
}
ctx := context.NewControllerContext(nil, client, backendConfigClient, nil, nil, defaultNamer, ctxConfig)
ctx := context.NewControllerContext(nil, client, backendConfigClient, nil, nil, defaultNamer, "" /*kubeSystemUID*/, ctxConfig)
Copy link
Member

Choose a reason for hiding this comment

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

the style is to put the comment in front of the value.
/*kubeSystemUID*/""

@bowei
Copy link
Member

bowei commented Nov 16, 2019

/lgtm
/approve

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 16, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: bowei, skmatti

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 16, 2019
@k8s-ci-robot k8s-ci-robot merged commit a254862 into kubernetes:master Nov 16, 2019
@Cyral Cyral mentioned this pull request Jun 18, 2021
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. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Long namespace/ingress names cause collisions with auto-created resources on GKE
5 participants