Reputation: 5030
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?
Upvotes: 244
Views: 353882
Reputation: 159781
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.
Upvotes: 111
Reputation: 22198
I'll answer the question in the title:
How does kubectl port-forward create a connection?
In the past it seems that it was using socat and nsenter, but that was on older versions of K8S.
Under the hood it is using the net/http package of go.
Let's explore the 1.30v
branch (if the links will break in the future - replace the master
word in the url to release-1.30
):
In the kubectl repo under:
kubectl/pkg/cmd/portforward/portforward.go
We can see that the function is importing:
k8s.io/client-go/tools/portforward
That is calling:
k8s.io/apimachinery/pkg/util/httpstream
Which is calling net/http
under the hood.
Upvotes: 1
Reputation: 837
If you want to forward to a different port in localhost. Try this
kubectl port-forward <pod-name> <localhost-port>:<pod-port>
kubectl port-forward sample-pod-sadasds-sxawdd 8090:6379
The above command forwards to localhost's port 8090 from pod's 6379
Upvotes: 70
Reputation: 1909
kubectl port-forward
is the easiest communication method with the Pod, but under the hood, this method is much more complicated. The communication goes through several Kubernetes components, so if anything is broken in the communication path, you will not be able to talk to the pod, even if the pod itself is accessible via regular communication channels.
The server proxy runs via kubectl port-forward
command forwards the connection to the Kubernetes API Server living in Master node, then the API Server delivers the connection to the Kubelet on the node hosting your Pod, and then the Kubelet forwards the connection to the application running in the pod's container.
NOTE
The application in the container must be bound to a port on the loopback device for the Kubelet to reach it. If it listens only on the pod’s eth0 network interface, you won’t be able to reach it with the kubectl port-forward command.
Marko Lukša "Kubernetes in Action, Second Edition"
TIP
kubectl port-forward
allows you to forward communication also to Services and has several other useful features. Run kubectl port-forward --help
to learn more.
Upvotes: 10
Reputation: 30811
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
Upvotes: 242
Reputation: 11535
To access something inside the cluster, there ae a couple of different options available to,
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.
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
Upvotes: 5
Reputation: 1564
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
Upvotes: 45