【问题标题】:Kube-dns service discovery cannot discover port number of servicekube-dns 服务发现无法发现服务的端口号
【发布时间】:2019-01-20 12:24:28
【问题描述】:

我正在使用基于 DNS 的服务发现来发现 K8s 集群中的服务。 从this 链接很明显,要发现名为 my-service 的服务,我们可以执行名称查找“my-service.my-ns”,并且 pod 应该能够找到服务。

但是,在服务的端口发现的情况下,解决方案将使用 是“_http._tcp.my-service.my-ns” 在哪里

_http 指的是 my-service 中名为 http 的端口。

但即使在使用 _http._tcp.my-service 之后,它也无法解析端口号。以下是详细信息。

需要发现的我的服务

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-service
  ports:
    - name: http
      protocol: TCP
      port: 5000
      targetPort: 5000

client-service yaml sn-p 试图发现 my-service 及其端口。

spec:
  containers:
  - name: client-service
    image: client-service
    imagePullPolicy: Always
    ports:
      - containerPort: 7799
    resources:
      limits:
        cpu: "100m"
        memory: "500Mi"
    env:
    - name: HOST
      value: my-service
    - name: PORT
      value: _http._tcp.my-service

现在,当我发出请求时,它会失败并记录以下请求,这显然是不正确的,因为它没有发现端口号。

 http://my-service:_http._tcp.my-service

我不确定我在这里做错了什么,但我按照文档中提到的相同说明进行操作。

有人可以建议这里出了什么问题以及我们如何使用基于 DNS 的服务发现来发现端口?我的理解是错误的,它会返回端口的字面值吗?

集群详情

K8s 集群版本为 1.11.5-gke.5 Kube-dns 正在运行

尝试从busybox发现服务但无法发现端口值5000的其他详细信息

kubectl exec  busybox -- nslookup my-service
Server:         10.51.240.10
Address:        10.51.240.10:53

Name:   my-service.default.svc.cluster.local
Address: 10.51.253.236

*** Can't find my-service.svc.cluster.local: No answer
*** Can't find my-service.cluster.local: No answer
*** Can't find my-service.us-east4-a.c.gdic-infinity-dev.internal: No answer
*** Can't find my-service.c.gdic-infinity-dev.internal: No answer
*** Can't find my-service.google.internal: No answer
*** Can't find my-service.default.svc.cluster.local: No answer
*** Can't find my-service.svc.cluster.local: No answer
*** Can't find my-service.cluster.local: No answer
*** Can't find my-service.us-east4-a.c.gdic-infinity-dev.internal: No answer
*** Can't find my-service.c.gdic-infinity-dev.internal: No answer
*** Can't find my-service.google.internal: No answer


kubectl exec  busybox -- nslookup _http._tcp.my-service
Server:         10.51.240.10
Address:        10.51.240.10:53

** server can't find _http._tcp.my-service: NXDOMAIN

*** Can't find _http._tcp.my-service: No answer

【问题讨论】:

  • kubectl exec -it busybox /bin/bash | nslookup my-service 肯定不会做你想做的事; (a)busybox 没有 bash (b) 该命令在 您的机器 上运行 nslookup 而不是busybox Pod (c) 语法绝对疯狂,因为您正在管道 输出 bash 到nslookup 命令
  • 感谢@MatthewLDaniel 指出错误。最初我尝试使用正确的语法,但在撰写问题时不知何故我犯了这个错误。我现在已经更正了。我提到的仍然是busybox的例子是为了获得更多信息,以消除任何关于糟糕的yaml配置可能性的猜测,你现在可以撤消你的否决了吗?我认为它现在是有效的内容。

标签: kubernetes google-kubernetes-engine kube-dns


【解决方案1】:

由于服务带有自己的(Kubernetes 内部)IP 地址,这里的简单答案是不要为服务选择任意端口。在您的服务定义中更改为port: 80,客户端将能够使用默认的 HTTP 端口访问它。设置环境变量时,设置

- name: PORT
  value: "80"

DNS 支持多种不同的记录类型;例如,A 记录将主机名转换为其 IPv4 地址,将 AAAA 转换为 IPv6 地址。您引用的 Kubernetes 服务文档(重点是我的)

您可以执行 DNS SRV 查询 ...以发现 "http" 的端口号。

虽然SRV records 似乎解决了这个问题的两半(它们为服务提供端口和主机名),但实际上它们似乎很少使用。链接的 Wikipedia 页面有一个使用它的服务列表,但是在我所知道的主流 TCP 客户端中,“连接到这个 SRV 记录指向的东西”不是一个选项。

您应该可以使用 (running this debugging image) 之类的命令来验证这一点

kubectl run debug --rm -it --image giantswarm/tiny-tools sh
# dig -t srv _http._tcp.my-service

(但请注意-t srv 参数;它不是默认记录类型。)

大多数需要PORT 环境变量或类似变量的东西都需要一个数字,或者如果没有,他们可以在/etc/services 文件中找到一个名称。您在此处尝试使用并尝试提供 DNS SRV 名称的语法可能不起作用,除非您知道特定软件支持它。

【讨论】:

  • 感谢您解释其背后的概念。真的很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
  • 2016-04-22
  • 2018-07-07
  • 2018-10-31
  • 2018-07-06
相关资源
最近更新 更多