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
Bug 1858879: Change router's internal endpoint.ID to prevent HAProxy server line collisions #170
Conversation
3df7d52
to
e954d26
Compare
@sgreene570: This pull request references Bugzilla bug 1858879, which is valid. The bug has been moved to the POST state. The bug has been updated to refer to the pull request using the external bug tracker. 3 validation(s) were run on this bug
In response to this:
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. |
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.
Would you mind adding unit tests for calculateServiceWeights
and for processEndpointsForAlias
?
What if a route specifies two services that have an endpoint in common? (Maybe that is outside the scope of this fix.)
Sure, I will add unit tests for those 2 functions. Thanks for the suggestion!
Are you concerned about the endpoint weights being incorrect or HAProxy breaking in this situation? A route that specifies two services with a common endpoint will not break HAProxy with or without this change, since each service is given a separate backend stanza. This PR does not change how endpoints common across multiple services will be weighted, since duplicate endpoints are filtered on a per-service basis. Are you suggesting that we change how services with common endpoints weight each of their endpoints? If so, I think that is out of scope of this particular bugfix. |
I meant the latter (HAProxy's breaking if a route has two services with a common endpoint, same as it breaks if a route has one service with two identical endpoints).
Are you sure that each service is given a separate router/pkg/router/template/router.go Lines 854 to 856 in 4a6284e
router/pkg/router/template/router.go Lines 1171 to 1177 in 4a6284e
The template produces a backend stanza for each service unit alias: router/images/router/haproxy/conf/haproxy-config.template Lines 435 to 440 in 4a6284e
And under that backend stanza, the template produces a server stanza for each endpoint of each service unit associated with the service unit alias: router/images/router/haproxy/conf/haproxy-config.template Lines 559 to 563 in 4a6284e
Line 559 is iterating over the service unit, and line 562 is iterating over the endpoints of the service unit. So it looks like two services with the same endpoint would produce two server stanzas, right?
That said, in tracing through this code, I realized that router/pkg/router/template/plugin.go Line 325 in 4a6284e
So this last discovery means that having a route with two services that have a common endpoint should not break anything, as the server name (= endpoint id) will differ. However, this last discovery also raises a question: Would it be an alternative (and simpler) solution to change the endpoint id to include the port name ( |
Ah, there's the missing piece that tripped me up. Thanks for the detailed explanation! I will ear mark this PR for future reference 😄
Yes, absolutely. I prefer this approach more, since endpoints would not need to be filtered out at all, and weight calculation code does not need to be modified. Also, I'll go ahead and make the change to the ep.ID string format, along with add in the unit tests mentioned earlier (not as important with this new approach, but still should be covered from this point forward, so I'll take care of that!). |
fcf1e05
to
22d67c5
Compare
endpoint.ID
to prevent HAProxy server
line collisions
endpoint.ID
to prevent HAProxy server
line collisions
@Miciah commit |
/test e2e |
/retest |
/retest |
|
||
for _, tc := range testCases { | ||
alias.PreferPort = tc.preferPort | ||
router.AddEndpoints(suKey, tc.endpoints) |
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 makes me nervous because router.AddEndpoints
assigns the slice to the service unit's endpoints table, and processEndpointsForAlias
can mutate the service unit's endpoints table, meaning it can mutate tc.endpoints
. This does not break the test now (processEndpointsForAlias
does not mutate the endpoints when PreferPort
is set or action
is empty), but it would be safer to copy the endpoints table to avoid the test data from being modified under us:
router.AddEndpoints(suKey, tc.endpoints) | |
endpointsCopy := make([]Endpoint, len(tc.endpoints)) | |
for i := range tc.endpoints { | |
endpointsCopy[i] = tc.endpoints[i] | |
} | |
router.AddEndpoints(suKey, endpointsCopy) |
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.
Ah, yea, definitely makes sense to copy the endpoints table first. Thanks for catching this!!
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.
Fixed.
/retest Please review the full test history for this PR and help us cut down flakes. |
16 similar comments
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
/hold |
/hold cancel |
|
/retest Please review the full test history for this PR and help us cut down flakes. |
2 similar comments
/retest Please review the full test history for this PR and help us cut down flakes. |
/retest Please review the full test history for this PR and help us cut down flakes. |
@sgreene570: All pull requests linked via external trackers have merged: Bugzilla bug 1858879 has been moved to the MODIFIED state. In response to this:
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. |
/cherry-pick release-4.5 |
@sgreene570: #170 failed to apply on top of branch "release-4.5":
In response to this:
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. |
HAProxy backend stanzas cannot have duplicate
server
lines. Services with multiple port specs that reference the same target port break this rule when a route is created with an integer target port that matches the (duplicate) service target port. Services that meet this criteria should also be counted as 1 (one) endpoint when calculating service endpoint weights and when determining if an HAProxy backend health probe is applicable.