-
Notifications
You must be signed in to change notification settings - Fork 460
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
support websocket for exec and attach #1305
Conversation
Welcome @duguhaotian! |
e047447
to
181cf6e
Compare
cmd/crictl/exec.go
Outdated
if err != nil { | ||
return err | ||
} | ||
executor, err = remoteclient.NewFallbackExecutor(websocketExecutor, executor, httpstream.IsUpgradeFailure) |
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.
is it the intention of the crictl? Should we just use websocket executor if requested without the fallback? It may be better for the end user to be able to explicitly ask for websocket.
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
cmd/crictl/attach.go
Outdated
id: id, | ||
tty: c.Bool("tty"), | ||
stdin: c.Bool("stdin"), | ||
websocket: c.Bool("websocket"), |
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 the name use-websocket
be better? Or maybe have something with three options: -- transport=spdy|websocket|default
where default will do websocket with the fallback to spdy?
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
i donot know why check of runc and cri-o critest failed? the report error is spdy upgrade failed? why? |
pkg/validate/streaming.go
Outdated
we, err := remoteclient.NewWebSocketExecutor(&rest.Config{TLSClientConfig: rest.TLSClientConfig{Insecure: true}}, "GET", url.String()) | ||
framework.ExpectNoError(err, "failed to create websocket executor for %q", execServerURL) | ||
|
||
e, err = remoteclient.NewFallbackExecutor(we, e, httpstream.IsUpgradeFailure) | ||
framework.ExpectNoError(err, "failed to create fallback executor for %q", execServerURL) | ||
|
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 is making the tests fail in the CI. Do runtimes have to support that?
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.
If websocket failed, will fallback to spdy that is same to before. Why make ci failed?
I think that IsUpgradeFailure will ignore error of websocket upgrade
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.
and error : unable to upgrade connection: 404 page not found
is reported by spdy(vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper.go#NewConnection)
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.
just remove this first, wait runtimes support it
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.
How can we test this? Using CRI-O main
always returns an error on exec:
sudo ./build/bin/linux/amd64/crictl exec -p websocket 20168cc1a0aefa251fed echo hi
FATA[0000] execing command in container: unable to upgrade streaming request: websocket: bad handshake
CRI-O logs:
ERRO[2023-12-08 09:28:57.322412994+01:00] unable to upgrade websocket connection: websocket server finished before becoming ready
The error is coming from:
We're vendoring Kubernetes v1.29.0-rc.1 right now, so I'm wondering which part is missing what 🤔
cmd/crictl/exec.go
Outdated
Usage: "transport protocol, One of: spdy|websocket|default", | ||
Value: "default", |
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.
I think we should keep spdy
as default value and remove default
.
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
I think CRI-O need update code of websocket, like support 'v5.channel.k8s.io' |
I may miss something here, but we use the code vendored from Kubernetes: https://github.com/cri-o/cri-o/blob/f40da54704c5c32fb24b2b0e204424afae5b0dc2/go.mod#L75-L80 |
can we get more logging of cri-o ? why http server failed? code: |
@duguhaotian it returns there: https://github.com/cri-o/cri-o/blob/f40da54704c5c32fb24b2b0e204424afae5b0dc2/vendor/golang.org/x/net/websocket/server.go#L84 With the error message:
@duguhaotian is it intentional that runtimes only support v1-v4? Ref: https://github.com/kubernetes/client-go/blob/84a6fe7e4032ae1b8bc03b5208e771c5f7103549/tools/remotecommand/websocket.go#L89-L92 |
|
cmd/crictl/exec.go
Outdated
case "spdy": | ||
exec, err = remoteclient.NewSPDYExecutor(config, "POST", url) | ||
case "websocket": | ||
exec, err = remoteclient.NewWebSocketExecutor(config, "GET", url.String()) |
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.
Can we use remoteclient.NewWebSocketExecutorForProtocols
and make the protocols CLI configurable?
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.
ofcourse, default use StreamProtocolV5Name?
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.
@duguhaotian yeah, this way we'll not require to flip the default again in the future once kubernetes/kubernetes#122263 got resolved.
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.
change option to crictl --websocket="x..channel.k8s.io"
,
- if not set
--websocket
, will use spdy; - if websocket failed, fallback to spdy;
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.
@duguhaotian yeah, this way we'll not require to flip the default again in the future once kubernetes/kubernetes#122263 got resolved.
fixed
There is a KEP and a plane to gradually move on to SPDY https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/4006-transition-spdy-to-websockets , we should coordinate, @seans3 is leading this effort and if we implement different bits at different times we'll risk to drift |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: duguhaotian The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
cmd/crictl/attach.go
Outdated
Usage: "protocol of transport, One of: spdy|websocket", | ||
Value: "spdy", | ||
}, | ||
&cli.BoolFlag{ |
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.
why a flag and not using fall back , as we are doing with kubectl and is defined in the KEP?
flags are hard to remove in the future and become APIs for users, I also prefer an environment variable instead
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.
thk you reply. fixed
I think this should follow the same flow that the kubectl implementation designed in the KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/4006-transition-spdy-to-websockets#proposal-kubectl-websocket-executor-and-fallback-executor use the legacy by default and have an environment variable to opt in to websockets by default but fallback to the legacy https://github.com/kubernetes/kubernetes/pull/119186/files#diff-62da7750fb41c9d53934dd9706ba719f0c0efdf931b6b36eb46498505e4d3520 |
Signed-off-by: haozi007 <duguhaotian@gmail.com>
I gree with you, my first version which use fallback executor. |
Please check more in detail how this is implemented in Kubernetes, I linked the corresponding code and KEP for context
|
The Kubernetes project currently lacks enough contributors to adequately respond to all PRs. This bot triages PRs according to the following rules:
You can:
Please send feedback to sig-contributor-experience at kubernetes/community. /lifecycle stale |
I think we could at least support the websocket executor in crictl for users to play around with the feature and runtimes. |
func IsEnabledWebsockets() bool { | ||
return strings.ToLower(os.Getenv("CRICTL_REMOTE_COMMAND_WEBSOCKETS")) == "true" | ||
} |
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.
Let's remove this
if !IsEnabledWebsockets() { | ||
return | ||
} |
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.
if !IsEnabledWebsockets() { | |
return | |
} |
@@ -163,8 +164,27 @@ func Exec(ctx context.Context, client internalapi.RuntimeService, opts execOptio | |||
return stream(ctx, opts.stdin, opts.tty, URL) | |||
} | |||
|
|||
func getExecutor(url *url.URL) (exec remoteclient.Executor, err error) { |
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.
I'd say we reintroduce the flag to select the executor.
This allows end users to choose the transport to be used as well as runtime developers to experiment on feature development. Supersedes: kubernetes-sigs#1305 Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
Thank you for the effort on this topic @duguhaotian, we really appreciate it. 🙏 |
What type of PR is this?
Add one of the following kinds:
/kind feature
Optionally add one or more of the following kinds if applicable:
/kind api-change
What this PR does / why we need it:
Which issue(s) this PR fixes:
#1296
Special notes for your reviewer:
Does this PR introduce a user-facing change?
add new option for
exec/attach
, manual is:crictl exec/attach -w -it ${container-id} ls
test
i use container engine is iSulad which implement stream server is websocket.