有没有办法获取kubernetes集群的外部端口?

52
我已经在kubernetes集群的所有节点上暴露了一个外部端口的服务,命令如下: kubectl create -f nginx-service.yaml 您已将服务暴露在kubernetes集群的所有节点上的外部端口。如果您想将此服务暴露给外部互联网,则需要为服务端口(tcp: 30002)设置防火墙规则以提供流量服务。
更多详情请参见http://releases.k8s.io/release-1.2/docs/user-guide/services-firewalls.md。已创建服务“nginx-service”。
是否有方法获取kubernetes集群的外部端口?

你是使用谷歌云、亚马逊 Web 服务(AWS)或本地 Docker 作为你的 Kubernetes 供应商吗?虽然 Kubernetes 应该是不可知的,但在 AWS 上却有点风险。 - Scott Stensland
8个回答

76

kubectl get svc --all-namespaces -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}{{end}}'

这个命令获取所有命名空间中的服务,并执行以下操作:“对于每个服务,对于每个端口,如果已定义nodePort,则打印nodePort”。


1
你能在回答中加入一些解释吗?这将有助于原帖作者理解你所发布的内容。 - Guillaume Racicot
14
这条命令会列出每个 NodePort 的更多信息。命令为:kubectl get svc --all-namespaces -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{.}}{{"\n"}}{{end}}{{end}}{{end}}' - Anum Sheraz
有没有针对特定命名空间(不使用范围)的相同命令? - Akito
kubectl get svc -n <namespace> -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}{{end}}' - Tim Hockin
1
kubectl get svc --all-namespaces -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\t"}}{{.name}}{{"\n"}}{{end}}{{end}}{{end}}' | sort,如果您想要识别与每个nodePort相关联的服务(按nodePort升序排列) - Shondeslitch

30

我希望这个答案简短易懂:

kubectl describe service --all-namespaces | grep -i nodeport

但是,使用 Go 模板是理想的选项,可以用于提取更多细节。


15
kubectl get svc --all-namespaces -o go-template='{{range .items}}{{ $save := . }}{{range.spec.ports}}{{if .nodePort}}{{$save.metadata.namespace}}{{"/"}}{{$save.metadata.name}}{{" - "}}{{.name}}{{": "}}{{.nodePort}}{{"\n"}}{{end}}{{end}}{{end}}'

这不仅获取使用的节点端口,还以以下格式获取节点端口的名称、服务的名称和命名空间:

<namespace>/<service name> - <nodeport name>: <nodeport>

2
这是我认为输出最有用信息的内容。 - Clark Updike
这就是方法。 - Hethcox

13
如果您使用kubectl describe service NAME查看您的服务(点击此处),它应该会显示指定的端口(在NodePort字段中)。

是的,我知道。有没有一种方法可以通过一个命令或其他方式获取所有外部端口? - kevin
你是指集群中所有服务的节点端口吗? - Robert Bailey
是的,就像命令:kubectl get endpoints一样。 root@jya-SBCR:/home/jya/work# kubectl get endpoints 名称 端点 年龄 ebaserdb-ommp-service 172.16.43.6:3306 10天 ebaserdb-service 172.16.43.8:3306 11天 ivlm2-service 172.16.43.4:8080 11天 kubernetes 10.46.178.197:6443 26天我可以获取一个集群中所有服务的节点端口吗? - kevin
我所知道的唯一方法是编写一个简短的脚本,迭代 kubectl get services 返回的服务并将每个服务运行通过 kubectl describe service - Robert Bailey

12

获取有关服务端口的扩展信息:

kubectl describe service -A

仅获取服务终端点:

kubectl get endpoints -A

要按节点IP限制输出,可以通过网络掩码进行grep,或使用更复杂的脚本。


error: a resource cannot be retrieved by name across all namespaces - The Onin

9

...而您也可以使用JsonPath来替代执行同样的解决方案...

  • get the external Port (the "nodePort") of myservice corresponding to the internal port 1234

     kubectl get svc myservice -o=jsonpath='{.spec.ports[?(@.port==1234)].nodePort}'
    
  • get a list of all IPs of the Nodes underlying your cluster, in one line

     kubectl get node -o=jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
    
显然,这些信息可以轻松地结合成一个方便的bash脚本,以适应任何特定的需求...
#!/bin/bash
#
# discoverService - extract the externally visible Node-IP and port for a specific Service in Kubernetes
#
KUBECTL=kubectl
#
if [[ $# < 2 || "$1" == "-h" ]]
    then
    echo discoverService SERVICENAME INTERNALPORT
    exit -1
fi
SERVICENAME=$1
INTERNALPORT=$2

EXTPORT=`${KUBECTL} get svc $SERVICENAME -o=jsonpath="{.spec.ports[?(@.port==${INTERNALPORT})].nodePort}"`

EXTIP=`${KUBECTL} get node -o=jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}'`


if [[ -z $EXTPORT ]]
    then
    echo -e "ERROR: service=$SERVICENAME internal-port=$INTERNALPORT not found.\n"
    exit -2
elif [[ -z $EXTIP ]]
    then
    echo -e "ERROR: could not retrieve underlying node IPs.\n"
    exit -2
fi
# Success...
echo $EXTIP:$EXTPORT

“nodePort”示例中有一个小错误 - 应该改为:kubectl get svc myservice -o=jsonpath='{.items[*].spec.ports[?(@.port==1234)].nodePort} - Carsten

0

对于那些想要获取主机IP的人,这里有一个命令:

  • 使用特定的NAMESPACE(默认为当前上下文)
  • 获取HostIP
  • 获取NodePort
# if want to explicit choose a NAMESPACE uncomment the line bellow and change the value
# NAMESPACE=default && \
if [[ -z $NAMESPACE ]]; then NAMESPACE="$(kubectl config view --minify -o jsonpath='{..namespace}')"; fi && \
kubectl get pod -o=custom-columns=POD_NAME:.metadata.name,IP:.status.hostIP --namespace=${NAMESPACE} && \
kubectl get svc -o=custom-columns=SVC_NAME:.metadata.name,PORT:.spec.ports[0].nodePort --namespace=${NAMESPACE}

0

我缺失的部分是minikube的实际IP地址。

---->$:kubectl describe service --all-namespaces | grep -i nodeport
Name:                     my-nodeport-service
Type:                     NodePort
NodePort:                 <unset>  30007/TCP
---->$:curl $(minikube ip):30007

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接