Skip to content

Conversation

@willianpaixao
Copy link

What type of PR is this?
/kind kep

What this PR does / why we need it:
Adds KEP for reverse port-forwarding in kubectl, addressing long-standing issue kubernetes/kubernetes#20227.

Which issue(s) this PR fixes:
Fixes #5695
Addresses kubernetes/kubernetes#20227

Special notes for your reviewer:
This KEP proposes adding `--reverse` flag to `kubectl port-forward` to enable
reverse tunneling (pod → local machine), similar to SSH's `-R` flag.

This has been a requested feature since 2016 and received a PoC implementation
in 2017 (PR kubernetes/kubernetes#57320) that was deferred pending SPDY deprecation.

/sig cli
/sig node

Add reverse port-forwarding capability to kubectl, enabling pods to
connect to services running on the developer's local machine.

This addresses kubernetes/kubernetes#20227
which has been open since 2016 with significant community interest.

Signed-off-by: Willian Paixao <[email protected]>
Copilot AI review requested due to automatic review settings November 18, 2025 19:14
@k8s-ci-robot k8s-ci-robot added kind/kep Categorizes KEP tracking issues and PRs modifying the KEP directory sig/cli Categorizes an issue or PR as relevant to SIG CLI. sig/node Categorizes an issue or PR as relevant to SIG Node. labels Nov 18, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in SIG CLI Nov 18, 2025
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Nov 18, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: willianpaixao
Once this PR has been reviewed and has the lgtm label, please assign soltysh for approval. For more information see the Code Review Process.

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Nov 18, 2025
@k8s-ci-robot
Copy link
Contributor

Welcome @willianpaixao!

It looks like this is your first PR to kubernetes/enhancements 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/enhancements has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot
Copy link
Contributor

Hi @willianpaixao. Thanks for your PR.

I'm waiting for a github.com 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-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. label Nov 18, 2025
@k8s-ci-robot k8s-ci-robot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Nov 18, 2025
Copilot finished reviewing on behalf of willianpaixao November 18, 2025 19:16
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces KEP-5695, which proposes adding reverse port-forwarding capability to kubectl port-forward. This feature would enable containers in Kubernetes pods to connect back to services running on a developer's local machine, similar to SSH's -R flag. This addresses a long-standing feature request from 2016 (issue #20227).

  • Adds a new --reverse flag to kubectl port-forward for reverse tunneling
  • Introduces protocol extensions to support bidirectional streaming between pods and local machines
  • Includes comprehensive graduation criteria from alpha (v1.34) through GA (v1.36)

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
keps/sig-cli/5695-kubectl-reverse-port-forward/kep.yaml Defines KEP metadata including feature gates (KubectlReversePortForward), milestones, and basic metrics configuration
keps/sig-cli/5695-kubectl-reverse-port-forward/README.md Comprehensive KEP documentation covering motivation, design details, test plans, graduation criteria, and production readiness considerations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Nov 18, 2025
- Detail required unit tests and existing test infrastructure.
- Update E2E test requirements.
- Update Graduation Criteria to include enabling existing test stubs.
- Update Implementation History with test infrastructure preparation.

Signed-off-by: Willian Paixao <[email protected]>
@willianpaixao
Copy link
Author

@aojea all your comments, as well as Copilot's, were addressed. Thank you for the review, happy to keep the discussion open.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Detection: New connection attempts fail with error: `reverse port-forward connection limit reached`
- Mitigations: This is intentional rate limiting to prevent resource exhaustion. User can
wait for existing connections to close, or adjust the limit if appropriate for their use case.
- Diagnostics: Metric `kubectl_portforward_reverse_connections_rejected_total{reason="limit"}` will increment.
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

The metric name referenced here (kubectl_portforward_reverse_connections_rejected_total) is not defined in the metrics list in kep.yaml (lines 44-49) or in the SLI section (lines 526-530). If this metric will be collected, it should be added to the metrics list in kep.yaml.

Copilot uses AI. Check for mistakes.
Comment on lines +199 to +212
kubectl port-forward pod-name 8080:80

# New reverse port-forward syntax
kubectl port-forward --reverse pod-name 8080:80
# or
kubectl port-forward -R pod-name 8080:80

# Multiple ports (both forward and reverse)
kubectl port-forward --reverse pod-name 8080:80 9090:9000
```

**Port Specification Semantics:**
- Forward mode (existing): `LOCAL_PORT:REMOTE_PORT` - local port forwards to remote port
- Reverse mode (new): `REMOTE_PORT:LOCAL_PORT` - remote port forwards to local port
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Potential confusion in port specification semantics: The documentation states that in reverse mode REMOTE_PORT:LOCAL_PORT means "remote port forwards to local port", but this contradicts the user story examples where 8080:8080 is used symmetrically.

For example, line 132 shows kubectl port-forward --reverse mypod 8080:8080 with the comment "Those connections get tunneled back to your local machine's port 8080", which suggests the format is still LOCAL:REMOTE or at least ambiguous.

Please clarify the port specification format consistently throughout the document. If it truly reverses to REMOTE:LOCAL (like SSH -R), make this very clear in all examples and add a warning about the semantic change.

Suggested change
kubectl port-forward pod-name 8080:80
# New reverse port-forward syntax
kubectl port-forward --reverse pod-name 8080:80
# or
kubectl port-forward -R pod-name 8080:80
# Multiple ports (both forward and reverse)
kubectl port-forward --reverse pod-name 8080:80 9090:9000
```
**Port Specification Semantics:**
- Forward mode (existing): `LOCAL_PORT:REMOTE_PORT` - local port forwards to remote port
- Reverse mode (new): `REMOTE_PORT:LOCAL_PORT` - remote port forwards to local port
# Format: LOCAL_PORT:REMOTE_PORT (local port forwards to remote port in the pod)
kubectl port-forward pod-name 8080:80
# New reverse port-forward syntax
# Format: REMOTE_PORT:LOCAL_PORT (remote port in the pod forwards to local port on your machine)
kubectl port-forward --reverse pod-name 8080:80
# or
kubectl port-forward -R pod-name 8080:80
# Multiple ports (reverse mode)
# Format: REMOTE_PORT1:LOCAL_PORT1 REMOTE_PORT2:LOCAL_PORT2 ...
kubectl port-forward --reverse pod-name 8080:80 9090:9000

⚠️ WARNING:
In reverse mode (--reverse or -R), the port specification format is reversed compared to forward mode.

  • Forward mode: LOCAL_PORT:REMOTE_PORT (local → pod)
  • Reverse mode: REMOTE_PORT:LOCAL_PORT (pod → local)
    This is similar to SSH's -R flag, but can be confusing if you are used to the default kubectl port-forward syntax.
    Double-check your port order when using reverse mode to avoid unexpected behavior!

Port Specification Semantics:

  • Forward mode (existing): LOCAL_PORT:REMOTE_PORT — local port forwards to remote port in the pod
  • Reverse mode (new): REMOTE_PORT:LOCAL_PORT — remote port in the pod forwards to local port on your machine

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

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

To be very honest I went back-and-forth with that in my mind while writing that, so it might be inconsistent.
What would be a good pattern?

Comment on lines +240 to +256
**4. Container Runtime Changes** (External repositories):

Changes required in container runtimes to support reverse port-forwarding:

**containerd** (`containerd/containerd`):
- Modify streaming server ([`internal/cri/streamingserver/server.go`](https://github.com/containerd/containerd/blob/main/internal/cri/streamingserver/server.go))
- Add reverse port-forward handler endpoint
- Implement network namespace listener creation
- Handle bidirectional streaming for reverse connections

**cri-o** (`cri-o/cri-o`):
- Modify port forward implementation ([`server/container_portforward.go`](https://github.com/cri-o/cri-o/blob/main/server/container_portforward.go))
- Add reverse mode support to port forward handler
- Implement listener in container network namespace
- Stream reverse connections back to kubelet

**Note**: This KEP requires coordinated changes across multiple projects (kubernetes, containerd, cri-o). Implementation will need agreement and collaboration from runtime maintainers.
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Inconsistency: The flow diagram shows that kubelet creates the listener in the pod's network namespace (line 272), but the Implementation Overview section states this will be done using "native Go listeners" in the kubelet (line 230). However, the container runtime changes section (lines 240-256) indicates that containerd and cri-o need to implement this functionality. Please clarify which component is actually responsible for creating the listener in the pod's network namespace - is it kubelet or the container runtime?

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

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

Opsie, yeah, it makes sense, I'll take a closer look at it later.


#### Story 3: Database Migration from Local Tools

As a database administrator, I want to run database migration tools from my local machine against a database pod without exposing the database outside the cluster, using a secure reverse tunnel.
Copy link
Member

Choose a reason for hiding this comment

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

nit: clarify that this is a schema update, not a data move


1. **Security Consideration**: Reverse port-forwarding exposes local services to remote pods. Users must understand the security implications and only use this feature in development/debugging scenarios.

2. **Network Namespace**: The listening port is created in the pod's network namespace, accessible only to processes within that pod (not to other pods in the cluster).
Copy link
Member

Choose a reason for hiding this comment

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

Are we assuming that the Pod is running on a Linux node? Windows doesn't have network namespaces.

Copy link
Author

Choose a reason for hiding this comment

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

I personally have zero knowledge on Windows implementation, would need help on that to expand the KEP.

- Handle incoming pod connections and stream them to kubectl
- Clean up listeners when kubectl disconnects

**3. Protocol Changes** (`pkg/kubelet/cri/streaming/portforward/`):
Copy link
Member

Choose a reason for hiding this comment

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

If I want to deny reverse proxy and allow forward proxy, will I be able to write a policy (eg Rego) to enforce this?

The answer should be Yes.

Copy link
Author

Choose a reason for hiding this comment

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

Also good point, I should clarify that. Thanks.

- Connection refused on local port
- Network namespace access failures
- Stream protocol errors

Copy link
Member

Choose a reason for hiding this comment

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

What if the container runtime doesn't support this kind of proxying?

Copy link
Author

Choose a reason for hiding this comment

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

@aojea raised this point so I've started to dig and create issues in the respective projects.

# The following PRR answers are required at alpha release
# List the feature gate name and the components for which it must be enabled
feature-gates:
- name: KubectlReversePortForward
Copy link
Member

Choose a reason for hiding this comment

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

This name implies that the client is kubectl. It can be but doesn't have to be. I would rename the feature gate.

Copy link
Author

Choose a reason for hiding this comment

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

Good point, I didn't consider other clients. Before renaming, do you think this KEP belongs to SIG-CLI or SIG-NODE?


- **Step 8**: Verify pod and network connectivity:

```bash
Copy link
Member

Choose a reason for hiding this comment

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

nit: the script is not valid bash

- **Step 9**: If all else fails, disable the feature and use forward port-forward
to verify base functionality:

```bash
Copy link
Member

Choose a reason for hiding this comment

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

nit: the script is not valid bash

Copy link
Author

Choose a reason for hiding this comment

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

I'm sorry, can you be more specific? The syntax is valid.
Is it because I've omitted the launch of the nginx container?

Extend API server to proxy connections between pods and external endpoints.

**Rejected because**: API server should not be in the data path for debugging tools. This is a kubectl/kubelet concern.

Copy link
Member

Choose a reason for hiding this comment

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

You could also launch an ephemeral container to achieve this aim.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/kep Categorizes KEP tracking issues and PRs modifying the KEP directory needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. sig/cli Categorizes an issue or PR as relevant to SIG CLI. sig/node Categorizes an issue or PR as relevant to SIG Node. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

kubectl reverse port-forward

4 participants