如何在Kubernetes中找到服务的URL?

101

我在本地的docker桌面上拥有一个本地的Kubernetes集群。

当我执行kubectl describe service命令时,我的Kubernetes服务看起来是这样的:

Name:              helloworldsvc
Namespace:         test
Labels:            app=helloworldsvc
Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"helloworldsvc"},"name":"helloworldsvc","namespace":"test...
Selector:          app=helloworldapp
Type:              ClusterIP
IP:                10.108.182.240
Port:              http  9111/TCP
TargetPort:        80/TCP
Endpoints:         10.1.0.28:80
Session Affinity:  None
Events:            <none>

这个服务指向一个带有Web应用程序的部署。

我的问题是,我该如何找到此服务的URL? 我已经尝试过http://localhost:9111/ ,但并没有起作用。

我验证了此服务指向的Pod正在运行中。

7个回答

168

服务的URL格式如下:

<service-name>.<namespace>.svc.cluster.local:<service-port>
在您的情况下,它是:
helloworldsvc.test.svc.cluster.local:9111

10
如果两个服务在同一个命名空间中,那么只需使用服务名称,其余内容可以忽略。 - P Ekambaram
我在一些地方看到过这种格式 <pod-name>.<service-name>.<namespace>.svc.cluster.local:<service-port> 的使用。这是不正确的吗?如果是正确的,那么我们什么时候会使用它呢? - Ram Patra
@RamPatra 你可以在 Kubernetes 文档的这个部分中找到有关 Pod 名称的 DNS 查询详细信息。https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods - redzack
只需要 helloworldsvc.test 就可以了吗? - tanteng
that is also correct - P Ekambaram
显示剩余2条评论

27

获取服务名称:kubectl get service -n test

Kubernetes服务的URL是service-name.namespace.svc.cluster.local:service-port,其中cluster.local是Kubernetes集群的名称。

要获取集群名称:kubectl config get-contexts | awk {'print $2'}

在你的情况下,服务的URL将会是 helloworldsvc.test.svc.cluster.local:9111

你尝试的方法行不通,因为如果要在本地主机上访问该服务,你需要使用NodePort,使用端口转发或使用kubectl 代理来使服务可用。

然而,如果你不想使用NodePort并且想要检查容器内部是否正常工作,请遵循以下步骤进入容器(如果它有shell)。

kubectl exec -it container-name -n its-namespace-name sh

然后执行:

curl localhost:80 或者 curl helloworldsvc.test.svc.cluster.local:9111 或者 curl 10.1.0.28:80

但是这两个curl命令只能在Kubernetes pod内部工作,不能在本地主机上运行。

要在主机上访问,请使用命令kubectl port-forward svc/helloworldsvc 80:9111 -n test


13
您创建的服务属于类型ClusterIP,只能从集群内部访问。您有两种方法可以从桌面访问它:
  1. 创建nodeport类型的服务,然后通过 nodeip:nodeport 访问它。
  2. 使用 Kubectl port forward,然后通过 localhost:forwardedport 访问它。

除非你确切知道自己在做什么,否则请尽量使用DNS而不是IP。 - Alexey Vazhnov

9

在同一集群和相同命名空间(命名空间:default;尽管所有变化均可在服务位于不同命名空间时使用)时,以下url变体对我有效:

http://helloworldsvc
http://helloworldsvc.default
http://helloworldsvc.default.svc
http://helloworldsvc.default.svc.cluster.local
http://helloworldsvc.default.svc.cluster.local:80

//

using HttpClient client = new();
string result = await client.GetStringAsync(url);

注:

  • 我恰好在使用 HttpClient 调用 ASP.NET 6 应用程序的往来通信
  • 该客户端默认将端口设置为 80,因此无需显式设置 80 端口即可正常工作。但我验证了所有这些情况都可以从 URL 中添加或删除它
  • 仅支持 http(除非你特别配置了 https
  • 在第一种情况下(即域名/“authority”只是服务名称本身时),才能省略命名空间。 因此,helloworldsvc.svc.cluster.local:80 失败,并抛出异常 "Name or service not known (helloworldsvc.svc.cluster.local:80)"

5

如果您正在使用minikube,您可以运行以下代码:

minikube service --all

在这里输入图片描述

针对特定服务


minikube service service-name --url

enter image description here


3

还有另一种获取服务URL的方法

通过kubectl exec进入pod执行

kubectl exec -it podName -n namespace -- /bin/sh

然后在 pod 中执行 nslookup 服务的 IP 地址,例如 172.20.2.213

/ # nslookup 172.20.2.213
nslookup: can't resolve '(null)': Name does not resolve

Name:      172.20.2.213
Address 1: 172.20.2.213 172-20-2-213.servicename.namespace.svc.cluster.local

在Pod中执行nslookup serviceName的IP命令。
/ # nslookup servicename
nslookup: can't resolve '(null)': Name does not resolve

Name:      172.20.2.213
Address 1: 172.20.2.213 172-20-2-213.servicename.namespace.svc.cluster.local

现在服务URL为servicename.namespace.svc.cluster.local,通过nslookup命令的输出结果中去除IP地址后,再添加上对应的服务端口。


0
通常在K8s环境中运行的基于Docker的容器会剥离掉任何多余的工具,但如果您进入您的Pod:
kubectl exec -it <pod-name> -n <namespace> -- /bin/sh

然后使用dnsdomainname,如下所示:

kafka-0:/$ dnsdomainname
kafka-headless.kafka.svc.cluster.local

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