Skip to main content

Command Palette

Search for a command to run...

kubectl proxy vs kubectl port-forward: Access Your Kubernetes Cluster Securely

In-depth analysis of kubectl proxy and kubectl port-forward: Use scenarios, authentication methods, and cautions.

Updated
7 min read
kubectl proxy vs kubectl port-forward: Access Your Kubernetes Cluster Securely
A
A cloud-native DevOps Engineer focused on building reliable, efficient, and modern infrastructure using Kubernetes, Terraform, and automation. Certified in CKA, CKS, Terraform Associate, and Azure Administrator. Contributed to high-impact cloud deployments, CI/CD pipelines, infrastructure hardening, and microservices architectures across global tech environments. Creates technical content around Kubernetes, system design, and DevOps practices to help engineers develop the microservice mindset.

When working with Kubernetes, developers often need a way to access applications or services running inside the cluster — without exposing them to the public internet.

1. Why Do We Need Local Access to Cluster Resources?

In a secure Kubernetes architecture, most microservices run in an isolated internal network, meaning they are not directly exposed to the node's network or the public internet. This isolation is a fundamental layer of security and must be preserved, especially for high-security applications.

However, this strict isolation can make it difficult to troubleshoot internal connectivity and application behavior. The solution is to leverage Kubernetes-native tools to create secure, temporary tunnels that eliminate the need for external exposure.

The key advantage of using tools like kubectl port-forward and kubectl proxy is that they require no code modifications to the application container, preserving its immutability and reducing the risk of accidental exposure when debugging highly secure applications.

2. Prerequisite: Establishing Cluster Trust

First verifies that you have the necessary authentication (kubeconfig) and authorization (RBAC permissions) required for accessing the cluster. You must be able to successfully run a basic command (e.g., kubectl get nodes) from the machine where you intend to run kubectl port-forward or kubectl proxy.

3. What is kubectl proxy?

kubectl proxy acts as an HTTP reverse proxy between your local machine and the Kubernetes API server.
It enables you to access any Kubernetes resource exposed by the API server — including Pods, Services, and other API endpoints — directly from your local host.

kubectl proxy

How it works

1. Local HTTP server startkubectl proxy starts a local HTTP server on your machine (by default at http://localhost:8001).

2. Authentication with API server – The proxy authenticates using your kubeconfig credentials, ensuring secure communication with the Kubernetes API server.

3. Request forwarding – When you make a local HTTP request (e.g., http://localhost:8001/api/...), the proxy securely forwards it to the Kubernetes API server over HTTPS.

4. API server processing – The API server receives the request, interacts with the appropriate Kubernetes resources (such as Pods, Services, Deployments or etc..), and prepares the response.

5. Response delivery – The proxy sends the API server’s response back to your local machine, making it appear as if you’re directly interacting with the cluster’s REST API from localhost.

6.Traffic flowLocal machine → kubectl proxy (HTTP server) → API server → Kubernetes resource → API server → kubectl proxy → Local machine

# You’ll see all the Pods in the default namespace directly fetched via the API server, not by connecting to the Pod network.
http://localhost:8001/api/v1/namespaces/default/pods

# To access a services
http://localhost:8001/api/v1/namespaces/<namespace>/services/<service-name>:<port-name>/proxy/
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
## Security aspects

# Most Explicit (Secure): Identical to the default behavior. Used to ensure the proxy is never accidentally exposed by other system configurations.
kubectl proxy --address=127.0.0.1 --accept-hosts='^127\.0\.0\.1$'

# Expose API to anyone who can reach your system.
kubectl proxy --address=0.0.0.0 --port=8001 

#Dangerous(Insecure): Binds to 0.0.0.0 (all network interfaces) and accepts requests from any host (^*\$).
kubectl proxy --address=0.0.0.0 --port=8001 --accept-hosts='^*$'

4. What is kubectl port-forward?

kubectl port-forward establishes a TCP tunnel that allows you to connect directly from your local machine to a Pod’s or Service’s port.This method provides application-specific access for debugging or testing purposes, without exposing the application externally through a LoadBalancer or Ingress.
You can perform port forwarding on Pods, Services, Deployments, StatefulSets, and ReplicaSets.

kubectl port-forward pod/<POD_NAME> <LOCAL_PORT>:<CONTAINER_PORT>
kubectl port-forward service/<SERVICE_NAME> <LOCAL_PORT>:<CONTAINER_PORT>
kubectl port-forward deployments/<DEPLOYMENT_NAME> <LOCAL_PORT>:<CONTAINER_PORT>
kubectl port-forward statefulsets/<STATEFULSET_NAME> <LOCAL_PORT>:<CONTAINER_PORT>

How it works

1. Connection to API server – kubectl connects securely to the Kubernetes API server using your kubeconfig credentials, similar to how kubectl proxy operates.

2. Data stream to kubelet – The API server identifies the node where the target Pod is running and securely streams the data to the kubelet on that node.

3. Pod connection and tunneling – The kubelet opens a connection to the Pod’s specified port and tunnels the traffic back through the same API server channel to your local machine.

4. Local access established – You can now access the Pod or Service locally through the forwarded port, without exposing it externally or modifying cluster networking.

5.Traffic flow – through this secure path: Local machine → API server → kubelet → Pod.

kubectl run flask-app --image=python:3.11 --port=5000
kubectl port-forward pod/flask-app 5000:5000
## Visit http://localhost:5000

# It takes random port on local machine
kubectl port-forward pod/my-pod :5000
kubectl port-forward --address 0.0.0.0 pod/my-pod 8888:5000

#To Run kubectl port forward command in background
kubectl port-forward pod/flask-app 5000:5000  &

5. Security Note — Binding to 0.0.0.0

By default, both kubectl proxy and kubectl port-forward bind to 127.0.0.1, making them accessible only from your local machine.

If you manually bind them to 0.0.0.0, they become accessible from any network interface — not just localhost.
While this can be helpful for remote debugging, it introduces a major security risk: Anyone on your network could potentially access your cluster through the open proxy or tunnel, especially if your kubeconfig remains active.

  • Best Practice:

    • Keep the binding to 127.0.0.1 (default).

    • Only bind to 0.0.0.0 if you have:

      • Strong network isolation (e.g., VPN or private subnet).

      • Proper authentication and authorization controls in place.

      • Strict firewall rules limiting who can connect.

6. Authentication & Authorization

Aspectkubectl proxykubectl port-forward
Authentication TypeEvery request goes through the API serverAuthenticated once when the tunnel is established
Credentials UsedKubeconfig (token / certificate / OIDC)Kubeconfig (token / certificate / OIDC)
RBAC EnforcementEnforced on each API callEnforced once at tunnel creation
Scope of AccessAll cluster API resourcesSpecific Pod or Service
Security StrengthStrong, per-request authenticationStrong, encrypted tunnel between local machine and Pod
Stability / ReliabilityVery stable, persistent accessCan break occasionally due to network issues or Pod restarts
Response DataReturns raw HTTP/API responses (JSON/YAML), e.g., resource lists, metrics, logs via APIReturns TCP stream or application data directly from the Pod (raw bytes, HTTP, database protocol, etc.)

7. When to Use Which

For Local Testing and Debugging – Use kubectl proxy or port-forward to test applications, APIs, or services running inside the cluster from your local machine without exposing them externally.

For Accessing Cluster APIs (HTTP Traffic) – Use kubectl proxy when you need HTTP-based access to Kubernetes resources, dashboards, or metrics APIs.

For Application-Specific Access (TCP Traffic) – Use kubectl port-forward to connect directly to a Pod or Service for TCP-based access, such as web apps, databases, or message queues like Kafka, in a development or testing environment.

For Short-Lived Connections – Ideal for temporary operations like inspecting logs, running queries, or testing functionality, where permanent exposure is not required.

For Secure Local Access – Both commands keep your traffic encrypted and access restricted to your kubeconfig permissions, making them safe for local development.

8. When not to Use

In Production – These are temporary connections that break when the command or terminal is closed. Use Ingress, LoadBalancer, or proper service exposure instead.

For Automation or CI/CD – Port-forwarding can hang or fail randomly. Use ClusterIP or internal services for reliable automation.

For Heavy Traffic – All traffic passes through the API server, which can cause latency and performance bottlenecks. Use proper network routing or service exposure instead.

For Long-Running Streams – Database or message queue connections, such as PostgreSQL or Kafka, can drop easily. Use a VPN, Bastion host, or persistent service exposure instead.

On Shared Machines – Anyone with access to the machine could reach your forwarded ports. Keep bindings local (127.0.0.1) and secure your environment.

Without Access Control – Running with admin kubeconfig may expose sensitive APIs. Enforce RBAC, limit privileges, and enable audit logging.

💡 Question of the Day:

If you had to securely expose a Kubernetes service for your team without using Ingress or LoadBalancer, what would be your preferred approach and why?

Secure, local, temporary – debug smart, expose smart.

Kubernetes for DevOps & SRE

Part 1 of 3

A practical series exploring Kubernetes, DevOps, and SRE fundamentals to advanced concepts. Learn deployments, automation, reliability practices, troubleshooting, and real-world cloud-native engineering workflows.

Up next

Distroless Containers: Why They Are a Game-Changer for DevOps Security

The Great Race to a Smaller Attack Surface: A Practical Guide to Distroless Containers

More from this blog