如何使用 Kubernetes 端口名称?

38

在 Kubernetes 的 deployment 中,我可以这样指定端口:

 containers:
 - name: nginx
   image: nginx:latest
   ports:
    - name: nginx-port
      containerPort: 80
      protocol: TCP

现在在一个服务中,我可以这样引用该端口(使我只需指定服务的外部端口):


spec:
  type: ClusterIP
  ports:
  - name: nginx-port
    port: 80
    targetPort: nginx-port
    protocol: TCP

现在的问题是,我是否可以使用以下语法引用其他地方的服务和端口 nginx-service.default.svc.cluster.local:nginx-port?你知道我可以使用这些特殊名称引用服务,但我发现自己需要硬编码端口号,例如 nginx-service.default.svc.cluster.local:80


好的,就在我发布这篇文章之后,我意识到我可以利用注入容器的环境变量,例如$(NGINX_SERVICE_PORT)。不过我还是很好奇是否存在类似端口的DNS名称,例如nginx-service.default.svc.cluster.local - soosap
5个回答

36
通常,您会通过端口号引用目标端口。但是,您可以为每个Pod的端口指定特定名称,并在服务规范中引用此名称。
这将使您的服务更清晰。以下是一个小例子:
apiVersion: v1
kind: Pod
metadata:
  name: named-port-pod
  labels:
    app: named-port-pod
spec:
  containers:
    - name: echoserver
      image: gcr.io/google_containers/echoserver:1.4
      ports:
      - name: pod-custom-port
        containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: named-port-svc
spec:
  ports:
    - port: 80
      targetPort: pod-custom-port
  selector:
    app: named-port-pod

19
Kubernetes的DNS服务为所有具名端口的服务提供SRV记录,格式如下:https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#srv-records
_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example
在您的情况下,您应该通过查询以下域名来访问它。
_nginx-port._tcp.nginx-service.default.svc.cluster.local

例子

nslookup -type=SRV _nginx-port._tcp.nginx-service.default.svc.cluster.local

结果如下:

_nginx-port._tcp.nginx-service.default.svc.cluster.local   service = 0 100 80 nginx-service.default.svc.cluster.local.
在上面的输出中,nginx-service.default.svc.cluster.local 是目标域名,而 80 是您应该连接到的目标端口,即 nginx-service.default.svc.cluster.local:80

12

不可以使用端口名称替代端口号。ServicePort中的名称字段有不同的用途。

在ServiceSpec中,所有端口都必须具有唯一名称。此名称映射到EndpointPort对象中的“名称”字段。

对于每个Service,都会生成一个Endpoint对象。该Endpoint的每个端口都对应一个Service端口。ServicePort和EndpointPort中的名称字段用于进行匹配。


2
有没有文档记录这个?你能提供链接吗?谢谢 :) - maslick
ServicePortsEndpointPorts。它们如何融入整体框架,我一点也不清楚。 - Watercycle
1
你是不正确的。https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#srv-records - Grigoriev Nick

5
是一种使用与所有常规DNS服务器相同协议的DNS服务。从这个意义上说,DNS并不是为了解决"端口名称"而设计的,而是为了解决域名(映射到IP地址)。

有些人会使用反向代理将流量从一个端口代理到另一个端口(前提是我们谈论的是HTTP / HTTPS流量),https://serverfault.com/questions/85078/how-to-forward-dns-alias-to-hostnameport或者使用iptables规则https://www.digitalocean.com/community/tutorials/how-to-forward-ports-through-a-linux-gateway-with-iptables。但是,这些假设您首先会将流量转发到特定端口(例如80)。

正如您在评论中所写的那样,使用环境变量将是适合您情况的选项。


1

以下内容按预期工作:

{ name: svc-port, targetPort: pod-port, port: 1111 }
{ name: pod-port, containerPort: 2222 }

即定义映射 service:1111 -> pod:2222

但如果 service.port.name == pod.port.name,一切都会出错:

{ name: web, targetPort: web, port: 1111 }
{ name: web, containerPort: 2222 }

在这种情况下,service:1111 导致 pod:1111,这可能是您问题的根源。

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