I'm new to kubernetes and am wondering if there's a way for me to see a list of all currently configured port forwards using
kubectl ?
I see there's a
kubectl port-forward command, but it doesn't seem to list them, just set one up.In addition to Dylan's answer, small adjustment to use with jq.
kubectl get svc -o json | jq '.items[] | {name:.metadata.name, p:.spec.ports[] } | select( .p.nodePort != null ) | "\(.name): localhost:\(.p.nodePort) -> \(.p.port) -> \(.p.targetPort)"'
"web1: localhost:30329 -> 8080 -> 8080"
"web2: localhost:30253 -> 8080 -> 8080"
kubectl get svc --all-namespaces -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}{{end}}'
Port forwards are listed in the services the above command should loop through all of them and print them out
If the question is about listing which ports have been forwarded from a client host to a pod on a Kubernetes cluster...I am not aware of a
kubectl / kubectl port-forward command for that.
Ultimately, a
kubectl port-forward ends up calling the /api/v1/namespaces/{namespace}/pods/{name}/portforward endpoint and establishes a connection to one of the Kubernetes API servers over the SPDY protocol; the kube-apiserver then proxies the connection to a concrete pod. That seems to be the case for when forwarding port(s) with kubectl port-forward to a concrete pod, pod selected from a deployment, or pod for a particular Kubernetes service.
Given that the kube-apiserver proxies the connection, examining the network connections on the client or server side with something like
lsof only shows the port number of the proxy (say, 443 or 8443) for connections to it. On the client side then, using the PID, you can figure out on which port it is listening on - that is the local port that's forwarded.
Also on the client side, just listing all
kubectl processes using something like ps -f | grep 'kubectl' | grep 'port-forward' will list all current port forwards established with kubectl port-forwardA modification of Oleg Butuzov answer for all namespaces of your cluster.
kubectl get svc --all-namespaces -o json | jq '.items[] | {name:.metadata.name, ns:.metadata.namespace, p:.spec.ports[] } | select( .p.nodePort != null ) | "\(.ns)/\(.name): localhost:\(.p.nodePort) -> \(.p.port) -> \(.p.targetPort)"' # output "dbtest/mysql: localhost:31281 -> 3306 -> mysql"
If the question is about the port forwards established from the client to the cluster, this will do:
ps -f | grep 'kubectl' | grep 'port-forward' | awk '{print $10 " " $11}'
if anyone is interested - here is a PS script that will list the processID and the local port it's listening.
param (
[string]$processName="Kubectl",
[string]$commandLinePart
)
# Get the list of processes with the specified name
$processes = Get-Process -Name $processName -ErrorAction SilentlyContinue
if ($processes -eq $null) {
Write-Output "No process found with the name $processName"
exit
}
# Iterate through each process and check the command line
foreach ($process in $processes) {
try {
$cmdLine = (Get-WmiObject Win32_Process -Filter "ProcessId=$($process.Id)").CommandLine
if ($cmdLine -like "*$commandLinePart*") {
Write-Output "Process ID: $($process.Id)"
Write-Output "Command Line: $cmdLine"
# Get the TCP port number(s) that the process is listening on
$netTCPConnections = Get-NetTCPConnection -OwningProcess $process.Id -State Listen
foreach ($connection in $netTCPConnections) {
Write-Output "Listening on TCP port: $($connection.LocalPort)"
}
if ($netTCPConnections.Count -eq 0) {
Write-Output "The process is not listening on any TCP ports."
}
}
} catch {
Write-Output "Failed to retrieve command line or TCP port information for process ID $($process.Id)"
}
}
Process ID: 84668 Command Line: C:\Users<user>\AppData\Local\Programs\OpenLens\resources\x64\kubectl.exe --kubeconfig C:\Users<user>\AppData\Local\Temp\kubeconfig-7f11e7d63059b39f9 9c18986611c0feb port-forward -n development service/demosite01 0:8080 Listening on TCP port: 1580
Listening on TCP port: 1580
Modified version of Oleg Butuzov's answer, to workaround "Cannot iterate over null" error:
kubectl get svc --all-namespaces -o json | jq '.items[] | select(.spec.ports != null) | {name:.metadata.name, ns:.metadata.namespace, p:.spec.ports[]} | select(.p.nodePort != null) | "\(.ns)/\(.name): localhost:\(.p.nodePort) -> \(.p.port) -> \(.p.targetPort)"' | column -t
Also increased the readability with
column.