https://spacelift.io/blog/kubectl-port-forward
In this article, we will look at how to use thekubectl port-forward
to setup port forwarding to your applications running on your Kubernetes (K8s) cluster. We will explain what port forwarding is, what it does, and why you would want to use the kubectl port-forward
command to achieve it! After running through the basic syntax and options available, we will describe the difference between kubectl port-forward
and similar option, kubectl proxy.
Next, we will delve into the use cases for port forwarding, how it works, and show some examples including how to port forward to a pod, service, and deployment. Lastly, you’ll want to know how to run port forwarding in the background, how to bind to 0.0.0.0, how to start and stop port forwarding, and some best practices you’ll want to follow when using kubectl port-forward.
And what about alternatives to kubectl port-forward
?
It’s everything you needed to know (and didn’t need to know!) about kubectl port-forward,
let’s dive in!
In a Kubernetes cluster, services are often deployed, each having its own IP address and port. Sometimes, you may want to access these services directly. This is where port forwarding comes in. Port forwarding in Kubernetes is a mechanism that allows you to access services running within a Kubernetes cluster from your local machine or another external system. It’s useful for debugging, testing, and accessing services during development.
K8s provides the kubectl port-forward
command to establish a secure tunnel between a local machine and a pod within the cluster.
Basic syntax
Below is the basic syntax of the kubectl port-forward
command:
kubectl port-forward TYPE/NAME [options] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]
You can check the available options by accessing the help option:
kubectl port-forward -h
What is the difference between kubectl proxy and kubectl port-forward?
kubectl proxy
and kubectl port-forward
are both kubectl
commands that enable access to Kubernetes services, but they serve slightly different purposes. kubectl port-forward
is used for forwarding traffic from a local port to a specific port on a pod within a service or deployment, enabling direct access to services running within the pod, while kubectl proxy
is used for accessing the K8s API server, allowing you to interact with various K8s resources.
kubectl proxy
creates a local HTTP proxy server that forwards your requests between your machine and the K8s control plane, allowing you to access the K8s API server without exposing it directly. It provides a convenient way to interact with the API and access services, endpoints, and other K8s resources.
To experiment with kubectl proxy
, simply run the command — by default, after running the command, you can access the K8s API server locally at http://localhost:8001
. For example, you can access the API endpoint for a service at http://localhost:8001/api/v1/namespaces/<namespace>/services/<service-name>/proxy/
.
Once you initiate port forwarding using kubectl port-forward
, Kubernetes sets up a secure tunnel between your local machine and the selected pod inside the cluster. This tunnel is established using the Kubernetes API server, which acts as an intermediary for the communication between your local machine and the pod.
The specified local port on your machine (<local-port>
) is bound to the selected pod’s port (<pod-port>
). All traffic sent to the specified local port on your machine is forwarded through the secure tunnel to the corresponding port on the selected pod.
Conversely, responses from the pod are sent back through the tunnel to your local machine. This process is known as ‘Traffic forwarding’. After port forwarding is established, you can access the services running inside the pod as if they were running on your local machine.
Let’s look at some of the use cases for this mechanism.
1. Debugging
Developers often use port forwarding to debug applications running inside a pod by accessing the services directly from their local machines such as inspecting traffic, logs, or use debugging tools directly from their local machines. Port forwarding is convenient for quickly verifying deployments without exposing services externally. It provides a way to interact with services before setting up more permanent access mechanisms.
2. Accessing web applications
If a pod is running a web application, port forwarding allows you to access that application through your local browser. This is useful for testing changes without deploying new versions.
3. Database access
You might want to access a database running in a pod for inspection or testing purposes. This is helpful for database administrators or developers who need to inspect or manipulate the database during development.
4. Accessing internal services
Some services within a K8s cluster may not be exposed externally, but you may need to access them for testing or development purposes.
5. Testing APIs
If your application communicates with external APIs, port forwarding allows you to test those interactions in a controlled environment by forwarding the necessary ports to your local machine.
6. Interacting with sidecar containers
A Kubernetes sidecar container is a design pattern in which an additional container is deployed alongside a primary container within the same pod in a K8s environment. The sidecar container extends or enhances the functionality of the main container, often by providing supporting features, utilities, or services. Where your Kubernetes pods can have multiple containers, port forwarding allows you to access these for tasks like log analysis, monitoring, or troubleshooting.
7. Testing load-balanced services
When testing load-balanced services, port forwarding allows you to target specific pods to observe how they behave under different conditions.
1. Kubect port-forward to a pod
To port forward to a pod, the basic syntax is:
kubectl port-forward pod/<pod-name> <local-port>:<pod-port>
For example, the command below forwards local port 8080 to port 80 on the pod named “mypod.”
kubectl port-forward pod/mypod 8080:80
2. Kubect port-forward to a service
To port forward to a Kubernetes service, the basic syntax is:
kubectl port-forward service/<service-name> <local-port>:<pod-port>
This command listens on port 8443 locally, forwarding to the targetPort of the service’s port named “https” in a pod selected by the service:
kubectl port-forward service/myservice 8443:https
3. Kubect port-forward to a deployment
To port forward to a deployment, the basic syntax is:
kubectl port-forward deployment/<deployment-name> <local-port>:<pod-port>
For example, this command listens 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
4. Run kubectl port-forward in the background
Running kubectl port-forward
in the background typically involves using terminal job control or backgrounding the process. kubectl port-forward
itself does not provide a built-in option to run in the background.
To achieve this using Terminal Job Control, start the port forwarding as usual using the syntax below:
kubectl port-forward <pod-name> <local-port>:<pod-port>
Suspend the process by pressing Ctrl + Z
. This will stop the process and put it in the background.
Use the bg
command to resume the process in the background
To bring the process back to the foreground later, you can use the fg
command.
5. Configure kubectl port-forward bind to 0.0.0.0
By default, when you use kubectl port-forward
, it binds to localhost
(127.0.0.1), making the service accessible only from the local machine. If you want to make the service available on all network interfaces, including external ones, you can use the --address
option.
Be aware that exposing services to all network interfaces might have security implications, so use this carefully, especially in production environments.
kubectl port-forward <pod-name> <local-port>:<pod-port> --address 0.0.0.0
The address option explained:
--address=[localhost]:
Addresses to listen on (comma separated). Only accepts IP addresses or localhost as a value. When localhost is
supplied, kubectl will try to bind on both 127.0.0.1 and ::1 and will fail if neither of these addresses are
available to bind.
6. Stop kubectl port-forward
If you started kubectl port-forward
in the foreground (i.e., it’s currently running in the terminal), you can stop it by pressing Ctrl + C
which sends an interrupt signal to the process.
If you used the bg
command to move the process to the background as described earlier, or the disown
command to detach it, you can bring it back to the foreground and stop it:
- Use the
jobs
command to see the list of background jobs. - Identify the job number of the
kubectl port-forward
process. - Bring the job to the foreground using
fg <job-number>
. - Press
Ctrl + C
to stop the foreground process.
Here are some best practices to keep in mind when using port-forwarding:
- Port forwarding should be used cautiously, especially in production environments, as it might expose services to unintended users. Only expose the necessary ports.
- Ensure that the necessary security measures are in place, such as strong authentication and proper authorization, before using port forwarding in a production setting.
- Consider specifying the address when running
kubectl port-forward
to avoid unintentionally exposing services to all network interfaces. Use--address 127.0.0.1
for local access only. - Educate development and operations teams about the risks associated with
kubectl port-forward
. Encourage the use of more secure and scalable alternatives for production environments.
While port forwarding is convenient for debugging and development, it’s common to expose services using K8s Services and Ingress controllers in a production environment, which provide more robust and scalable solutions for handling external traffic.
K8s Services of type ClusterIP, NodePort, and LoadBalancer can be used to expose applications within the cluster or externally.
Example Deployment YAML file web-app-deployment.yaml
that defines a set of pods running a web application.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app-container
image: nginx:latest
The below examples show how to create a YAML service file to expose the pods running in the above deployment using the different methods.
ClusterIP for internal services
ClusterIP service YAML file web-app-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
Apply the deployment and service and check the ClusterIP assigned to the service:
kubectl apply -f web-app-deployment.yaml
kubectl apply -f web-app-service.yaml
kubectl get services
NodePort for external access
This time, we create the Nodeport service file to expose the pods:
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
The output of kubectl get services
here will show the assigned nodeport.
LoadBalancer for cloud-provider-specific external load balancers
Finally we create the LoadBalancer service file to expose the pods:
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
The output of kubectl get services
here will show the assigned external IP, e.g:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web-app-service LoadBalancer 10.99.99.99 203.0.113.10 80:31234/TCP 2m
Tidak ada komentar:
Posting Komentar