kubectl - 确定在随机本地端口上进行端口转发时使用的本地端口?
kubectl - determine local port used when port-forwarding on random local port?
kubectl 让一个端口像这样转发到远程服务
$ kubectl port-forward service/my-service :12345
如何找出 kubectl 在此命令中选择并使用的本地端口?
其他详细信息:我希望能够从脚本中确定这一点,该脚本为服务寻找活动的端口转发。如果找不到端口转发,它会在一个空闲的本地端口上创建一个端口转发,并且 returns 端口号(这就是上面所做的)
当你使用$ kubectl port-forward service/my-service :12345
命令时,你必须得到这样的输出:
Forwarding from 127.0.0.1:XXXX -> YYYY
Forwarding from [::1]:XXXX -> YYYY
这是您必须识别本地所选端口的唯一方法,您可以在脚本中添加一条指令以从输出中读取该值。 XXXX 号是本地选择的端口号。我可以建议您使用 service type Nodeport instead of port-forward. Using NodePort, you are able to expose your app as a service and have access from outside the Kubernetes. Take a look into the following documentation 来获取更多示例。
This(bash
function) 可能不是更简洁的方法,但可以在 kubeadm
集群上运行。尝试同时多次转发不同 pods/svc.
get_local_port()
{
port=""
if [ -z "${port}" ];then
echo "[Error]: 1st argument should be the remote port number"
return 1
fi
netstat -plnt |\
awk -vpid="$(ps -eaf |awk -v port=${port} '{if(match([=10=],"port-forward.*"port)) printf "%s|", }'|sed -r 's/.$//g')" '{if(match($NF,"^"pid"/")) {split(,a,":");print a[2]}}'
}
用法:
get_local_port <remote-port-number>
解释:
此命令正在解析 ps -eaf
以获取 port-forwarding
命令的 PID,然后通过 netstat
对其进行解析以获取本地端口。
我找不到任何其他方法来工作,所以我结束了编写动态查找空闲端口的脚本,并设置转发,然后 returns 端口。如果匹配的端口转发已经存在,它可以 return 代替。下面的示例用法。请注意,目前我使用另一个脚本来确定一个可用的本地端口,然后使用该端口号来设置端口转发,并且可以改为解析我在问题中提到的通用 port-forward 命令的输出,但是这种方法不那么脆弱,而且 re-usable,我相信。
$ kpf help
kubernetes port forward helper
* helps you transparently ensure a port forward is setup for a service.
usage: kpf [require|get|create|remove|remove_all] {SERVICEI} {REMOTE_PORT} {EXTRA_ARGS}
e.g.
# get or create a port forward for your-service on remote port 8080
# returns the port if successful, or fails and shows an error message
kpf require service/your-service 8080
# return any existing port forwards for your-service on remote port 8080, or nothing
kpf get service/your-service 8080
# create a new local port forward for your-service on remote port 8080, returning port used
kpf create service/your-service 8080
# remove any port forwards found to your-service on remote port 8080
kpf remove service/your-service 8080
# remove ALL port forwards to any kubernetes remote ports
kpf remove_all
kpf
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; PATH="$DIR:$PATH"
ME=$(basename "[=11=]")
function show_help()
{
IT=$(cat <<EOF
kubernetes port forward helper
* helps you transparently ensure a port forward is setup for a service.
usage: $ME [require|get|create|remove|remove_all] {SERVICE} {REMOTE_PORT} {EXTRA_ARGS}
e.g.
# get or create a port forward for your-service on remote port 8080
# returns the port if successful, or fails and shows an error message
$ME require service/your-service 8080
# return any existing port forwards for your-service on remote port 8080, or nothing
$ME get service/your-service 8080
# create a new local port forward for your-service on remote port 8080, returning port used
$ME create service/your-service 8080
# remove any port forwards found to your-service on remote port 8080
$ME remove service/your-service 8080
# remove ALL port forwards to any kubernetes remote ports
$ME remove_all
# create a port forward on local port 4569, for localstack, in namespace localstack
$ME create svc/localstack 4569:4569 --namespace localstack
EOF
)
echo "$IT"
echo
exit
}
if [ -z "" ]
then
show_help
fi
if [ "" = "help" ] || [ "" = '?' ] || [ "" = "--help" ] || [ "" = "h" ]; then
show_help
fi
OP=
SERVICE=
REMOTE_PORT=
if [ -n "" ]
then
shift;
shift;
shift;
EXTRA_ARGS="$@"
fi
LOG_FILE_DIR="/tmp/__${ME}"
function getExistingPortForward(){
listPortForwards | grep "$SERVICE" | grep -e ":$REMOTE_PORT" | head -n1
}
function coln(){
COL=
DELIM=${2:-' '}
awk -F"$DELIM" -v col="$COL" '{print $col}' | sort | uniq
}
function err(){
echo "$@" >&2;
}
function isNumeric(){
INPUT=$*
case ${INPUT#[-+]} in
*[!0-9]* ) echo NO ;;
* ) echo YES ;;
esac
}
function getPid(){
local INFO=$(getExistingPortForward | awk '{print }')
if [ "$(isNumeric "$INFO")" == "YES" ]; then
echo "$INFO"
fi
}
function getLocalPort(){
local INFO=$(getExistingPortForward)
INFO=$(echo "$INFO" | awk -F ":$REMOTE_PORT" '{print }' | awk '{print $NF}')
if [ "$(isNumeric "$INFO")" == "YES" ]; then
echo "$INFO"
fi
}
function removePortForward(){
local PID=$(getPid)
if [ -z "$PID" ]
then
return;
fi
set -x
kill "$PID"
}
function portForward(){
local LOCAL_PORT=
local FILE=
kubectl port-forward "$SERVICE" "$LOCAL_PORT":"$REMOTE_PORT" $EXTRA_ARGS > $FILE 2>&1 &
}
function failIfFileContains(){
local FILE=
local SUBSTR=
local MSG=
if grep -iq "$SUBSTR" "$FILE"; then
cat "$FILE" >&2
err "Failed: $MSG"
err "Service:$SERVICE, $REMOTE_PORT $EXTRA_ARGS"
err
exit 1
fi
}
function getTargetLocalPort(){
local RESULT
if [[ $REMOTE_PORT == *":"* ]]; then
RESULT=$(echo $REMOTE_PORT | coln 1 ':')
REMOTE_PORT=$(echo $REMOTE_PORT | coln 2 ':')
else
RESULT=$(port_find_free_local_port)
fi
echo "$RESULT"
}
function createPortForward(){
local LOCAL_PORT=$(getTargetLocalPort)
local LOG_FILE="${LOG_FILE_DIR}/${LOCAL_PORT}_log.txt"
mkdir -p "$LOG_FILE_DIR"
rm -f "$LOG_FILE"
portForward "$LOCAL_PORT" "$LOG_FILE"
# wait for the log file to indicate success or failure
while true
do
sleep 0.5
failIfFileContains "$LOG_FILE" "address already" "Port $LOCAL_PORT already in use"
failIfFileContains "$LOG_FILE" "must be logged" "Please set some PCSK variables, and try again"
failIfFileContains "$LOG_FILE" "Failed" "Please review the above log, and try again"
failIfFileContains "$LOG_FILE" "Error" "Please review the above log, and try again"
if grep -q Forwarding "$LOG_FILE"; then
# port forward successful
echo "$LOCAL_PORT"
break
fi
done
}
function getOrCreatePortForward(){
local PORT=$(getLocalPort)
if [ -n "$PORT" ]
then
echo "$PORT"
exit;
fi
createPortForward
}
function listPortForwards(){
ps aux | grep kubectl | grep port-forward | sort
}
function removeAll(){
listPortForwards | awk '{print }' | xargs kill -9
rm -fr "$LOG_FILE_DIR"
}
function require3Args(){
if [ -z "$REMOTE_PORT" ]
then
show_help
fi
}
if [ "$OP" = "get" ]; then
require3Args
getLocalPort
elif [ "$OP" = "create" ]; then
require3Args
createPortForward
elif [ "$OP" = "require" ]; then
require3Args
getOrCreatePortForward
elif [ "$OP" = "remove" ]; then
require3Args
removePortForward
elif [ "$OP" = "list" ]; then
listPortForwards
elif [ "$OP" = "remove_all" ]; then
removeAll
else
show_help
fi
port_find_free_local_port
#!/usr/bin/env python
#
import socket
from contextlib import closing
def find_free_port():
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.bind(('', 0))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return s.getsockname()[1]
print(find_free_port())
kubectl 让一个端口像这样转发到远程服务
$ kubectl port-forward service/my-service :12345
如何找出 kubectl 在此命令中选择并使用的本地端口?
其他详细信息:我希望能够从脚本中确定这一点,该脚本为服务寻找活动的端口转发。如果找不到端口转发,它会在一个空闲的本地端口上创建一个端口转发,并且 returns 端口号(这就是上面所做的)
当你使用$ kubectl port-forward service/my-service :12345
命令时,你必须得到这样的输出:
Forwarding from 127.0.0.1:XXXX -> YYYY
Forwarding from [::1]:XXXX -> YYYY
这是您必须识别本地所选端口的唯一方法,您可以在脚本中添加一条指令以从输出中读取该值。 XXXX 号是本地选择的端口号。我可以建议您使用 service type Nodeport instead of port-forward. Using NodePort, you are able to expose your app as a service and have access from outside the Kubernetes. Take a look into the following documentation 来获取更多示例。
This(bash
function) 可能不是更简洁的方法,但可以在 kubeadm
集群上运行。尝试同时多次转发不同 pods/svc.
get_local_port()
{
port=""
if [ -z "${port}" ];then
echo "[Error]: 1st argument should be the remote port number"
return 1
fi
netstat -plnt |\
awk -vpid="$(ps -eaf |awk -v port=${port} '{if(match([=10=],"port-forward.*"port)) printf "%s|", }'|sed -r 's/.$//g')" '{if(match($NF,"^"pid"/")) {split(,a,":");print a[2]}}'
}
用法:
get_local_port <remote-port-number>
解释:
此命令正在解析 ps -eaf
以获取 port-forwarding
命令的 PID,然后通过 netstat
对其进行解析以获取本地端口。
我找不到任何其他方法来工作,所以我结束了编写动态查找空闲端口的脚本,并设置转发,然后 returns 端口。如果匹配的端口转发已经存在,它可以 return 代替。下面的示例用法。请注意,目前我使用另一个脚本来确定一个可用的本地端口,然后使用该端口号来设置端口转发,并且可以改为解析我在问题中提到的通用 port-forward 命令的输出,但是这种方法不那么脆弱,而且 re-usable,我相信。
$ kpf help
kubernetes port forward helper
* helps you transparently ensure a port forward is setup for a service.
usage: kpf [require|get|create|remove|remove_all] {SERVICEI} {REMOTE_PORT} {EXTRA_ARGS}
e.g.
# get or create a port forward for your-service on remote port 8080
# returns the port if successful, or fails and shows an error message
kpf require service/your-service 8080
# return any existing port forwards for your-service on remote port 8080, or nothing
kpf get service/your-service 8080
# create a new local port forward for your-service on remote port 8080, returning port used
kpf create service/your-service 8080
# remove any port forwards found to your-service on remote port 8080
kpf remove service/your-service 8080
# remove ALL port forwards to any kubernetes remote ports
kpf remove_all
kpf
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; PATH="$DIR:$PATH"
ME=$(basename "[=11=]")
function show_help()
{
IT=$(cat <<EOF
kubernetes port forward helper
* helps you transparently ensure a port forward is setup for a service.
usage: $ME [require|get|create|remove|remove_all] {SERVICE} {REMOTE_PORT} {EXTRA_ARGS}
e.g.
# get or create a port forward for your-service on remote port 8080
# returns the port if successful, or fails and shows an error message
$ME require service/your-service 8080
# return any existing port forwards for your-service on remote port 8080, or nothing
$ME get service/your-service 8080
# create a new local port forward for your-service on remote port 8080, returning port used
$ME create service/your-service 8080
# remove any port forwards found to your-service on remote port 8080
$ME remove service/your-service 8080
# remove ALL port forwards to any kubernetes remote ports
$ME remove_all
# create a port forward on local port 4569, for localstack, in namespace localstack
$ME create svc/localstack 4569:4569 --namespace localstack
EOF
)
echo "$IT"
echo
exit
}
if [ -z "" ]
then
show_help
fi
if [ "" = "help" ] || [ "" = '?' ] || [ "" = "--help" ] || [ "" = "h" ]; then
show_help
fi
OP=
SERVICE=
REMOTE_PORT=
if [ -n "" ]
then
shift;
shift;
shift;
EXTRA_ARGS="$@"
fi
LOG_FILE_DIR="/tmp/__${ME}"
function getExistingPortForward(){
listPortForwards | grep "$SERVICE" | grep -e ":$REMOTE_PORT" | head -n1
}
function coln(){
COL=
DELIM=${2:-' '}
awk -F"$DELIM" -v col="$COL" '{print $col}' | sort | uniq
}
function err(){
echo "$@" >&2;
}
function isNumeric(){
INPUT=$*
case ${INPUT#[-+]} in
*[!0-9]* ) echo NO ;;
* ) echo YES ;;
esac
}
function getPid(){
local INFO=$(getExistingPortForward | awk '{print }')
if [ "$(isNumeric "$INFO")" == "YES" ]; then
echo "$INFO"
fi
}
function getLocalPort(){
local INFO=$(getExistingPortForward)
INFO=$(echo "$INFO" | awk -F ":$REMOTE_PORT" '{print }' | awk '{print $NF}')
if [ "$(isNumeric "$INFO")" == "YES" ]; then
echo "$INFO"
fi
}
function removePortForward(){
local PID=$(getPid)
if [ -z "$PID" ]
then
return;
fi
set -x
kill "$PID"
}
function portForward(){
local LOCAL_PORT=
local FILE=
kubectl port-forward "$SERVICE" "$LOCAL_PORT":"$REMOTE_PORT" $EXTRA_ARGS > $FILE 2>&1 &
}
function failIfFileContains(){
local FILE=
local SUBSTR=
local MSG=
if grep -iq "$SUBSTR" "$FILE"; then
cat "$FILE" >&2
err "Failed: $MSG"
err "Service:$SERVICE, $REMOTE_PORT $EXTRA_ARGS"
err
exit 1
fi
}
function getTargetLocalPort(){
local RESULT
if [[ $REMOTE_PORT == *":"* ]]; then
RESULT=$(echo $REMOTE_PORT | coln 1 ':')
REMOTE_PORT=$(echo $REMOTE_PORT | coln 2 ':')
else
RESULT=$(port_find_free_local_port)
fi
echo "$RESULT"
}
function createPortForward(){
local LOCAL_PORT=$(getTargetLocalPort)
local LOG_FILE="${LOG_FILE_DIR}/${LOCAL_PORT}_log.txt"
mkdir -p "$LOG_FILE_DIR"
rm -f "$LOG_FILE"
portForward "$LOCAL_PORT" "$LOG_FILE"
# wait for the log file to indicate success or failure
while true
do
sleep 0.5
failIfFileContains "$LOG_FILE" "address already" "Port $LOCAL_PORT already in use"
failIfFileContains "$LOG_FILE" "must be logged" "Please set some PCSK variables, and try again"
failIfFileContains "$LOG_FILE" "Failed" "Please review the above log, and try again"
failIfFileContains "$LOG_FILE" "Error" "Please review the above log, and try again"
if grep -q Forwarding "$LOG_FILE"; then
# port forward successful
echo "$LOCAL_PORT"
break
fi
done
}
function getOrCreatePortForward(){
local PORT=$(getLocalPort)
if [ -n "$PORT" ]
then
echo "$PORT"
exit;
fi
createPortForward
}
function listPortForwards(){
ps aux | grep kubectl | grep port-forward | sort
}
function removeAll(){
listPortForwards | awk '{print }' | xargs kill -9
rm -fr "$LOG_FILE_DIR"
}
function require3Args(){
if [ -z "$REMOTE_PORT" ]
then
show_help
fi
}
if [ "$OP" = "get" ]; then
require3Args
getLocalPort
elif [ "$OP" = "create" ]; then
require3Args
createPortForward
elif [ "$OP" = "require" ]; then
require3Args
getOrCreatePortForward
elif [ "$OP" = "remove" ]; then
require3Args
removePortForward
elif [ "$OP" = "list" ]; then
listPortForwards
elif [ "$OP" = "remove_all" ]; then
removeAll
else
show_help
fi
port_find_free_local_port
#!/usr/bin/env python
#
import socket
from contextlib import closing
def find_free_port():
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.bind(('', 0))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return s.getsockname()[1]
print(find_free_port())