-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Add a shim API for port forwarding. #4814
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
Conversation
|
Hi @ianlewis. Thanks for your PR. I'm waiting for a containerd member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions 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. |
|
Build succeeded.
|
1203211 to
92dfc8d
Compare
|
/cc @mikebrow |
|
Build succeeded.
|
|
Build succeeded.
|
|
Build succeeded.
|
|
Build succeeded.
|
This allows shims to implement an optional port forwarding service. This is useful for runtimes that remove the IP address from the veth for a user space network stack and can't support port forwarding via the network namespace.
|
Build succeeded.
|
|
Build succeeded.
|
mikebrow
left a comment
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.
some comments.. request to get engagement with some more core runtime maintainers
| "github.com/containerd/containerd/runtime" | ||
| client "github.com/containerd/containerd/runtime/v2/shim" | ||
| "github.com/containerd/containerd/runtime/v2/task" | ||
| shimapi "github.com/containerd/containerd/runtime/v2/task" |
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.
maybe taskAPI
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 started doing this partly because it was given this name in runtime/v2/shim/shim.go and it seems like this package name is becoming dated given that we may be adding more optional services to the shim.
| if err != nil { | ||
| return nil, errors.Wrap(err, "failed to create containerd client") | ||
| } | ||
| pf, err := getPortForwardService(ic) |
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.
Did we need to figure out a way to make this per runtime?
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.
My intention was to allow shims to implement port forward. I don't think we had a need to implement it per "runtime" (i.e. v1, v2, v2/shim). My intention was for 'pf' to return an error in cases where it wasn't supported and fall back to the previous logic. I do that around line 75 in sandbox_portforward_linux.go.
I'm open to thinking about it but I can't really imagine how it would work unless we push the code in localPortForward in sandbox_portforward_linux.go into runtime/v2 somewhere. I don't think we really want to do that.
| } | ||
| pf, err := getPortForwardService(ic) | ||
| if err != nil { | ||
| return nil, errors.Wrap(err, "failed to get port forward service") |
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.
should we ignore if there is no port forward service to fall back to the prior behavior..
@dmcgowan @crosbymichael we should do a call I think with Ian to go over 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.
Yeah, I think it might be good to meet again. I can probably speak more intelligently now that I've taken a stab at implementing 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.
I sent an invite for Wed. Hopefully that works.
| } | ||
|
|
||
| logrus.Debug("registering ttrpc server") | ||
| logrus.Debug("registering task service") |
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.
maybe registering task service via ttrpc
| func (c *criService) portForward(ctx context.Context, id string, port int32, stream io.ReadWriteCloser) error { | ||
| s, err := c.sandboxStore.Get(id) | ||
| // Attempt to start port forwarding via the port forwarding client. | ||
| // NOTE: Do not use volitile root dir as it amy exceed max length for UDS addr. |
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.
"may exceed"
| rtTasks: rt, | ||
| client: client, | ||
| task: shimapi.NewTaskClient(client), | ||
| portforward: shimapi.NewPortForwardClient(client), |
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 the shim could just return the client here, then the port forward client could be completely separated here
| } | ||
|
|
||
| message PortForwardRequest { | ||
| // The container id. |
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.
| // The container id. | |
| // ID is the container id. |
| message PortForwardRequest { | ||
| // The container id. | ||
| string id = 1; | ||
| // The port to be forwarded inside the container. |
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.
| // The port to be forwarded inside the container. | |
| // Port sets the port to be forward inside the container. |
| string id = 1; | ||
| // The port to be forwarded inside the container. | ||
| int32 port = 2; | ||
| // A Unix domain socket address |
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.
| // A Unix domain socket address | |
| // Addr is the unix domain socket address. |
| rpc PortForward(PortForwardRequest) returns (google.protobuf.Empty); | ||
| } | ||
|
|
||
| message PortForwardRequest { |
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.
Also, make sure to add some documentation to the message type.
|
Needs rebase |
|
Closing this. @zkoopmans can create a new PR using this as a reference. |
This allows shims to implement an optional port forwarding service. This
is useful for runtimes that remove the IP address from the veth for a
user space network stack and can't support port forwarding via the
network namespace.
This implements Option 1b described here: kubernetes/enhancements#1846
Summary:
This PR adds a new optional
PortForwardgrpc service that shims can implement. The service has a singlePortForwardrpc endpoint that accepts a port number and UDS address. Containerd will attempt to use thePortForwardendpoint to initiate port forwarding and fall back to existing logic on the container's network namespace if unsuccessful. Containerd will listen on the UDS address and shims/runtimes are expected to establish a single connection on this address to establish bi-directional communication, forwarding data to/from the container's port to the UDS connection.As networking is out of scope of containerd itself, a new
PortForwardplugin is introduced to allow the CRI plugin to make calls to task implementations directly. The CRI plugin uses this plugin to call runtime/v2 implementations directly and returns an error if the task is not a runtime/v2 implementation that implements port forwarding. Only runtime/v2 implementations that are shims are expected to implement this interface.