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

[bugfix] fix transport race conditions in yurthub #683

Merged
merged 1 commit into from
Dec 16, 2021

Conversation

rambohe-ch
Copy link
Member

What type of PR is this?

Uncomment only one /kind <> line, hit enter to put that in a new line, and remove leading whitespace from that line:
/kind bug
/kind documentation
/kind enhancement
/kind good-first-issue
/kind feature
/kind question
/kind design
/sig ai
/sig iot
/sig network
/sig storage
/sig storage

/kind bug

What this PR does / why we need it:

reconstruct transport setting in RemoteProxy of yurthub component for preventing race conditions.

  1. add bearerUpgradeHandler and existing upgradeHandler for Connection: Upgrade request.
  2. add RoundTrip() func for RemoteProxy to group transport handler.

Which issue(s) this PR fixes:

Fixes #674

Special notes for your reviewer:

/assign @DrmagicE

Does this PR introduce a user-facing change?


other Note

@openyurt-bot
Copy link
Collaborator

@rambohe-ch: GitHub didn't allow me to assign the following users: your_reviewer.

Note that only openyurtio members, repo collaborators and people who have commented on this issue/PR can be assigned. Additionally, issues/PRs can only have 10 assignees at the same time.
For more information please see the contributor guide

In response to this:

What type of PR is this?

Uncomment only one /kind <> line, hit enter to put that in a new line, and remove leading whitespace from that line:
/kind bug
/kind documentation
/kind enhancement
/kind good-first-issue
/kind feature
/kind question
/kind design
/sig ai
/sig iot
/sig network
/sig storage
/sig storage

/kind bug

What this PR does / why we need it:

reconstruct transport setting in RemoteProxy of yurthub component for preventing race conditions.

  1. add bearerUpgradeHandler and existing upgradeHandler for Connection: Upgrade request.
  2. add RoundTrip() func for RemoteProxy to group transport handler.

Which issue(s) this PR fixes:

Fixes #674

Special notes for your reviewer:

/assign @DrmagicE

Does this PR introduce a user-facing change?


other Note

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.

@openyurt-bot openyurt-bot added do-not-merge/work-in-progress do-not-merge/work-in-progress kind/bug kind/bug labels Dec 14, 2021
@openyurt-bot openyurt-bot requested a review from qclc December 14, 2021 12:38
@openyurt-bot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: rambohe-ch

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

@openyurt-bot openyurt-bot requested a review from SataQiu December 14, 2021 12:38
@openyurt-bot openyurt-bot added approved approved size/M size/M: 30-99 labels Dec 14, 2021
upgradeAwareHandler.UseRequestLocation = true
bearerUpgradeAwareHandler := proxy.NewUpgradeAwareHandler(remoteServer, bearerTransport, false, true, &responder{})
Copy link
Member

Choose a reason for hiding this comment

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

The transport passed to NewUpgradeAwareHandler is assigned to UpgradeAwareHandler.Transport. It's used to handle non-upgrade request. So, it doesn't matter here. I think we should assign currentTransport and bearerTransport to UpgradeAwareHandler.UpgradeTransport.

Copy link
Member Author

Choose a reason for hiding this comment

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

@Congrool From the code: https://github.com/kubernetes/apimachinery/blob/v0.18.8/pkg/util/proxy/upgradeaware.go#L398-L400

when UpgradeTransport is nil, UpgradeAwareHandler will use Transport to handle upgrade request.

Copy link
Member

Choose a reason for hiding this comment

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

I think we can group upgradeAwareHandler and bearerUpgradeAwareHandler into one.

upgradeAwareHandler and bearerUpgradeAwareHandler here are used to distinguish bearer and non-bearer requests and use different transport for them. The RemoteProxy is exactly what we need:

func (rp *RemoteProxy) RoundTrip(req *http.Request) (*http.Response, error) {
	// when edge client(like kube-proxy, flannel, etc) use service account(default InClusterConfig) to access yurthub,
	// Authorization header will be set in request. and when edge client(like kubelet) use x509 certificate to access
	// yurthub, Authorization header in request will be empty.
	if isBearerRequest(req) {
		return rp.bearerTransport.RoundTrip(req)
	}

	return rp.currentTransport.RoundTrip(req)
}

I think we can remove bearerUpgradeAwareHandler and use proxyBackend as the transport param in NewUpgradeAwareHandler.

The codes should look like:

	proxyBackend := &RemoteProxy{
		checker:          healthChecker,
		reverseProxy:     httputil.NewSingleHostReverseProxy(remoteServer),
		cacheMgr:         cacheMgr,
		remoteServer:     remoteServer,
		filterChain:      filterChain,
		currentTransport: currentTransport,
		bearerTransport:  bearerTransport,
		stopCh:           stopCh,
	}

	upgradeAwareHandler := proxy.NewUpgradeAwareHandler(remoteServer, proxyBackend, false, true, &responder{})
	upgradeAwareHandler.UseRequestLocation = true

	proxyBackend.reverseProxy.Transport = proxyBackend
	proxyBackend.reverseProxy.ModifyResponse = proxyBackend.modifyResponse
	proxyBackend.reverseProxy.FlushInterval = -1
	proxyBackend.reverseProxy.ErrorHandler = proxyBackend.errorHandler
	proxyBackend.upgradeHandler = upgradeAwareHandler

Copy link
Member Author

Choose a reason for hiding this comment

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

@DrmagicE A good idea, i will modify it.

Copy link
Member Author

@rambohe-ch rambohe-ch Dec 16, 2021

Choose a reason for hiding this comment

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

@DrmagicE I have checked the codes of NewUpgradeAwareHandler, and only *http.Transport as http. RoundTripper is supported, so use proxyBackend as http. RoundTripper can not work.
maybe we need to leave the current changed unchanged.

the code link is here: https://github.com/kubernetes/apimachinery/blob/master/pkg/util/net/http.go#L215-L239

Copy link
Member

Choose a reason for hiding this comment

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

@rambohe-ch Oh, what a pity. I got it.

} else {
rp.upgradeHandler.UpgradeTransport = proxy.NewUpgradeRequestRoundTripper(rp.currentTransport, proxy.MirrorRequest)
rp.upgradeHandler.ServeHTTP(rw, req)
Copy link
Member

Choose a reason for hiding this comment

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

As discussed above.

Copy link
Member Author

Choose a reason for hiding this comment

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

the same as above

@rambohe-ch rambohe-ch changed the title [WIP] [bugfix] fix transport race conditions in yurthub [bugfix] fix transport race conditions in yurthub Dec 15, 2021
@openyurt-bot openyurt-bot removed the do-not-merge/work-in-progress do-not-merge/work-in-progress label Dec 15, 2021
@@ -106,21 +110,13 @@ func (rp *RemoteProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if httpstream.IsUpgradeRequest(req) {
klog.V(5).Infof("get upgrade request %s", req.URL)
if isBearerRequest(req) {
Copy link
Member

Choose a reason for hiding this comment

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

As mentioned in https://github.com/openyurtio/openyurt/pull/683/files#r769771572, if we group upgradeAwareHandler and bearerUpgradeAwareHandler into one, the codes here can be simplified as follow:

	if httpstream.IsUpgradeRequest(req) {
		klog.V(5).Infof("get upgrade request %s", req.URL)
		rp.upgradeHandler.ServeHTTP(rw, req)
		return
	}

	rp.reverseProxy.ServeHTTP(rw, req)

Copy link
Member Author

Choose a reason for hiding this comment

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

As replied above

@DrmagicE
Copy link
Member

/lgtm

@openyurt-bot openyurt-bot added the lgtm lgtm label Dec 16, 2021
@openyurt-bot openyurt-bot merged commit 757b328 into openyurtio:master Dec 16, 2021
MrGirl pushed a commit to MrGirl/openyurt that referenced this pull request Mar 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved approved kind/bug kind/bug lgtm lgtm size/M size/M: 30-99
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Race conditions in yurthub
4 participants