We can use kubectl to set up a proxy that will forward all traffic from a local port we specify to a port associated with the Pod we determine. This can be performed using kubectl port-forward
command. 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. We use this command to access container content by forwarding one (or more) local ports to a pod. This command is very useful mostly when you would want to troubleshoot a misbehaving pod.
kubectl port-forward syntax
The general syntax to forward ports using kubectl
would be as shown below but we will explore all possible options:
kubectl port-forward <resource-type/resource-name> [local_port]:<pod_port>
Sample command to perform port forwarding on pod:
kubectl port-forward pods/my-pod 8080:80
Sample command to perform port forwarding on deployment:
kubectl port-forward deployment/my-deployment 8080:80
Sample command to perform port forwarding on replicaset:
kubectl port-forward replicaset/my-replicaset 8080:80
Sample command to perform port forwarding on service:
kubectl port-forward service/my-service 8080:80
Note that you will not have a Command Prompt back after executing these commands, which is because the command is actively running to keep this particular tunnel we've requested alive. If we cancel or quit the kubectl
command, typically by pressing Ctrl + C
, then port forwarding will immediately end.
Perform kubectl port-forward in background
To perform kubectl port-forward
in background you can append the command with &
as shown below
kubectl port-forward pods/my-pod 8080:80 &
This will print the PID of the process and then send the command to background and you will be able to use the terminal. Once your work is done, you can go ahead and kill the PID of the background process to close the tunnel.
Perform port-forwarding on Pods
Here I will create a simple pod with nginx server running on port 80:
Use kubectl create
command to create the pod using the provided YAML file.
[root@controller ~]# kubectl create -f nginx.yaml
pod/nginx created
List the available pods:
[root@controller ~]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 2m37s
To get more details such IP address of the pod,worker node on which the respective pod is running etc, we will combine the above command with -o wide
:
[root@controller ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 3m 10.44.0.1 worker-2.example.com <none> <none>
Access nginx server without port forwarding
Now we know that our nginx container is running on worker-2
with an IP address of 10.44.0.1
. But is this IP reachable from the controller node? We are using weave-net CNI and with this network plugin by default the internal network of worker nodes are not accessible by the controller node so we can't connect to the container directly.
But the same IP is reachable from the worker-2
node so we can access our nginx server container directly from worker-2
without performing any port forwarding:
But our requirement is to access this nginx web server from the container on the container node so we can use kubectl port-forward
command.
Access nginx server with port forwarding
Method-1: Listen on port 8080 locally, forwarding to port 80 in the pod
In this method we will forward the traffic to port 8080 on localhost (on controller) to port 80 on worker-2
based nginx
container. This is forwarding any and all traffic that gets created on your local machine at TCP port 8080 to TCP port 80 on the Pod nginx
:
[root@controller ~]# kubectl port-forward pod/nginx 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Now we attempt to access our nginx server using a different terminal:
Once done you can either kill the PID of the port-forward command or press ctrl+c
on the terminal where kubectl port-forward
is running.
Method-2: Listen on port 8080 on all addresses, forwarding to 80 in the pod
In this method we will perform port forwarding to all addresses on the controller node from port 8080 to port 80 in the pod. So you can use any IP address from the controller node with port 8080 to access the nginx container.
[root@controller ~]# kubectl port-forward --address 0.0.0.0 pod/nginx 8080:80
Forwarding from 0.0.0.0:8080 -> 80
Since we are trying to access a new port, so we will need to enable this port in the firewall if we want to access this on external network:
[root@controller ~]# firewall-cmd --add-port 8080/tcp --permanent success [root@controller ~]# firewall-cmd --reload success
Now we can access our nginx container on external network (here 192.168.0.150 is the IP of my controller node):
Once done you can either kill the PID of the port-forward command or press ctrl+c
on the terminal where kubectl port-forward
is running.
Method-3: Listen on a random port locally, forwarding to 80 in the pod
If you don't specify a local port then kubectl will randomly select a port for forwarding. For example, here I have not specified any local port so kubectl has randomly selected port 40159 for the forwarding.
[root@controller ~]# kubectl port-forward pod/nginx :80
Forwarding from 127.0.0.1:40159 -> 80
Forwarding from [::1]:40159 -> 80
So we can use this port to access the nginx container:
[root@controller ~]# curl 127.0.0.1:40159
Once done you can either kill the PID of the port-forward command or press ctrl+c
on the terminal where kubectl port-forward
is running.
Perform port-forwarding on Kubernetes Deployment Pods
Kubernetes services can be used to expose pods to external network. There are different Service Types available but to perform port forwarding we will use NodePort
.
Here I have created a deployment using the following YAML file:
and we will also create a service to expose the deployment pods:
Let us create the deployment and the service:
[root@controller ~]# kubectl create -f nginx-deploy.yaml deployment.apps/nginx-deploy created [root@controller ~]# kubectl create -f nginx-service.yaml service/nginx-deploy created
List the available pods and services:
[root@controller ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d
nginx-deploy NodePort 10.102.65.90 <none> 80:31957/TCP 6s
[root@controller ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-58f9bf94f7-4hngf 1/1 Running 0 7s 10.44.0.2 worker-2.example.com <none> <none>
nginx-deploy-58f9bf94f7-dmtfq 1/1 Running 0 2m40s 10.44.0.1 worker-2.example.com <none> <none>
As you can see under available services, our deployment is accessible over port 31957
so we can use the IP address of the respective worker node i.e. worker-2
where our pod is running along with port 31957
to access the nginx container:
But if you want to perform port forwarding on this pod then you can use service/<service-name>
as it would be hard to get the pod name as it is not static and contains variables:
[root@controller ~]# kubectl port-forward service/nginx-deploy 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Here since it would be hard to get the pod name as it is not static and contains variables, n you can access the nginx deployment pod using following address from the container:
[root@controller ~]# curl 127.0.0.1:8080
Summary
In this tutorial we learned how to access container in an external network by performing port forwarding using kubectl. The port-forward utility is often used to create a tunnel to a pod inside the cluster. This utility creates a TCP stream to a specific port on your pod, making it accessible to your local host (or more if you wanted). This method is mostly used by developers for easy troubleshooting purpose to access the pod container. It also has some drawbacks as kubectl port-forward
will open your cluster up to attacks from any script running locally so you must use this cautiously.
References
Forward a local port to a port on the Pod
Related Searches: kubectl port-forward in background. kubectl port-forward --address. kubectl port-forward options. run kubectl port-forward in background.