How kubectl port-forward works?

KubernetesPortforwardingKubectl

Kubernetes Problem Overview


kubectl exposes commands that can be used to create a Service for an application and assigns an IP address to access it from internet.

As far as I understand, to access any application within Kubernetes cluster there should be a Service resource created and that should have an IP address which is accessible from an external network.

But in case of port-forward how does kubectl create a connection to the application without an IP address which is accessible externally?

Kubernetes Solutions


Solution 1 - Kubernetes

To start, it's useful to note and remember that in Kubernetes, every pod gets its own ip address from 10.*, that is usable only within the cluster. Now, the port-forward feature of kubectl simply tunnels the traffic from a specified port at your local host machine to the specified port on the specified pod. API server then becomes, in a sense, a temporary gateway between your local port and the Kubernetes cluster.

kubectl port-forward forwards connections to a local port to a port on a pod. Compared to kubectl proxy, kubectl port-forward is more generic as it can forward TCP traffic while kubectl proxy can only forward HTTP traffic.

kubectl port-forward is useful for testing/debugging purposes so you can access your service locally without exposing it.

Below is the name of the pod and it will forward it's port 6379 to localhost:6379.

kubectl port-forward redis-master-765d459796-258hz 6379:6379 

which is the same as

kubectl port-forward pods/redis-master-765d459796-258hz 6379:6379

or

kubectl port-forward deployment/redis-master 6379:6379 

or

kubectl port-forward rs/redis-master 6379:6379 

or

kubectl port-forward svc/redis-master 6379:6379

Solution 2 - Kubernetes

kubectl port-forward makes a specific Kubernetes API request. That means the system running it needs access to the API server, and any traffic will get tunneled over a single HTTP connection.

Having this is really useful for debugging (if one specific pod is acting up you can connect to it directly; in a microservice environment you can talk to a back-end service you wouldn't otherwise expose) but it's not an alternative to setting up service objects. When I've worked with kubectl port-forward it's been visibly slower than connecting to a pod via a service, and I've found seen the command just stop after a couple of minutes. Again these aren't big problems for debugging, but they're not what I'd want for a production system.

Solution 3 - Kubernetes

If you want to forward to a different port in localhost. Try this

kubectl port-forward <pod-name> <locahost-port>:<pod-port>
kubectl port-forward sample-pod-sadasds-sxawdd 8090:6379

The above command forwards to localhost 8090 from pod 6379

Solution 4 - Kubernetes

The port-forward command, Forwards one (or more) local ports to a pod.

This command is very useful for example in blue/green deployments where you would want to troubleshoot a misbehaving pod.

To take things even further, you could even execute some preliminary tests to the pods you feel could be more error-prone right inside your CI/CD pipeline in Jenkins by using multiple conditions, declarative pipeline.

Usage examples:

Listen on port 8888 locally, forwarding to 5000 in the pod

kubectl port-forward pod/mypod 8888:5000

Listen on port 8888 on all addresses, forwarding to 5000 in the pod

kubectl port-forward --address 0.0.0.0 pod/mypod 8888:5000

Listen on a random port locally, forwarding to 5000 in the pod

kubectl port-forward pod/mypod :5000

Listen on port 8888 on localhost and selected IP, forwarding to 5000 in the pod

kubectl port-forward --address localhost,10.19.21.23 pod/mypod 8888:5000

Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod

kubectl port-forward pod/mypod 5000 6000

Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in a pod selected by the deployment

kubectl port-forward deployment/mydeployment 5000 6000

Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in a pod selected by the service

kubectl port-forward service/myservice 5000 6000

Solution 5 - Kubernetes

To access something inside the cluster, there ae a couple of different options available to,

  1. Cluster IP service with Ingress-Nginx
  2. NodePort Service to expose the pod directly to the outside world.

Above both approach will require to write config file, In case if you want to access a pod without writing a config file then it comes to third option.

  1. Port Forward: We can run a command at our terminal that tells our kubernets cluster to port-forward a port off a very specific pod inside of our cluster when we use this port forwarding thing that's going to cause our cluster to essentially behaves as though it has a node port service running inside it. It's going to expose this pod or a very specific port on it to the outside world and allow us to connect to it directly from our local machine.

Let's go by an example:

const stan = nats.connect('ticketing', 'abc', {
  url: 'http://localhost:5000',
});

Our goal is to establish a connection between stan and a pod inside a kubernets cluster.

first we will need the pod name, you can get the name by command kubectl get pods

kubectl get pods

I am assuming my pod name is nats-depl-855d477f4d-xgbd7, and it is accessiable via a cluster IP service

apiVersion: v1
kind: Service
metadata:
  name: nats-srv
spec:
  selector:
    app: nats
  ports:
    - name: client
      protocol: TCP
      port: 4222
      targetPort: 4222

now to establish the connection run the below command:

kubectl port-forward nats-depl-855d477f4d-xgbd7 5000:4222

5000: is the port of my local machine

4222 : is the port of the pod I want to get access

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkarthikeayanView Question on Stackoverflow
Solution 1 - KuberneteslvthilloView Answer on Stackoverflow
Solution 2 - KubernetesDavid MazeView Answer on Stackoverflow
Solution 3 - KubernetesVihar ManchalaView Answer on Stackoverflow
Solution 4 - KubernetesSkepticView Answer on Stackoverflow
Solution 5 - KubernetesRafiqView Answer on Stackoverflow