什么是无头服务,它能完成/完成什么工作,合法的用例有哪些?

Joh*_*xus 30 kubernetes

我已经阅读了一些用Kubernetes编写的书以及文档中有关无头服务的页面的几段内容。但是我仍然不确定它的真正作用以及为什么有人会使用它。是否有人对它有很好的了解,它能完成什么以及为什么有人会使用它?

Kon*_*tin 42

好吧,我认为您需要一些理论。整个互联网上有很多解释(包括官方文档),但是我认为Marco Luksa做到了最好:

与该服务的每个连接都转发到一个随机选择的后备容器。但是,如果客户端需要连接到所有这些Pod,该怎么办?如果后备箱本身需要分别连接到所有其他后备箱,该怎么办。通过服务进行连接显然不是实现此目的的方法。什么是?

为了使客户端连接到所有Pod,它需要确定每个Pod的IP。一种选择是让客户端调用Kubernetes API服务器并通过API调用获取Pod列表及其IP地址,但是由于您应始终努力使应用与Kubernetes无关,因此使用API​​服务器并不理想

幸运的是,Kubernetes允许客户端通过DNS查找来发现Pod IP。通常,当您对服务执行DNS查找时,DNS服务器会返回一个IP(服务的群集IP)。但是,如果您告诉Kubernetes,您不需要服务的群集IP(通过在服务规范中将clusterIP字段设置为None来完成此操作),DNS服务器将返回容器IP,而不是单个服务IP。DNS服务器将返回该服务的多个A记录,而不是返回单个DNS A记录,每个记录都指向当时支持该服务的单个pod的IP。因此,客户端可以进行简单的DNS A记录查找,并获取服务中所有pod的IP。然后,客户端可以使用该信息来连接到一个,多个或全部。

将服务规范中的clusterIP字段设置为None会使该服务变得毫无头绪,因为Kubernetes不会为它分配一个群集IP,客户端可以通过该群集IP连接到支持它的Pod。

Marco Luksa的“ Kubernetes在行动”

  • 我很乐意为您提供帮助,但我建议您购买这本书。毫无疑问,作者做得很好,应该受到鼓励。 (8认同)
  • 感谢您链接这本书-非常感谢。我将看看是否可以在网上找到一份副本并阅读。答案很棒,但我真的很感激。 (2认同)

小智 17

简而言之,Headless 服务默认 ClusterIP 服务相同,但缺少负载平衡或代理。允许您直接连接到 Pod。

  • Headless 服务仍然提供跨 Pod 的负载平衡,但通过 DNS 循环机制而不是通过服务代理。 (6认同)
  • k8s 文档称无头服务缺乏负载均衡。https://kubernetes.io/docs/concepts/services-networking/service/#headless-services (6认同)

VKa*_*atz 10

让我按照我们在敏捷中所做的方式将这个问题分解为每个子部分。

什么是无头服务。

它用于发现单个 Pod(尤其是 IP),这允许另一个服务直接与 Pod 而不是代理交互。使用 NodePort、LoadBalancer、ExternalName 和 ClusterIP 客户端通常通过服务(简单直观地解释 Kubernetes 服务)而不是直接连接来连接到 pod 。

它有什么作用?

要求不是像其他服务类型那样制作单个 IP。我们需要位于服务背后的所有 pod 的 IP。

它有哪些合法用例?

  • 创建有状态服务。

  • 将 RabbitMQ 或Kafka(或任何消息代理服务)部署到 Kubernetes 需要一个有状态的 RabbitMQ 集群节点集。

  • 关系数据库的部署

  • 还有很多


一些实际操作

部署配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  labels:
    app: server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
Run Code Online (Sandbox Code Playgroud)

定期服务

apiVersion: v1
kind: Service
metadata:
  name: regular-svc
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
Run Code Online (Sandbox Code Playgroud)

无头服务

apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None # <= Don't forget!!
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
Run Code Online (Sandbox Code Playgroud)

创建所有资源并运行 tmp pod。

k run tmp01 --image=tutum/dnsutils -- sleep infinity

k exec tmp01 -it -- /bin/sh

#=> nslookup regular-svc
Server:     10.96.0.10
Address:    10.96.0.10#53

Name:   regular-svc.moon.svc.cluster.local
Address: 10.109.150.46
Run Code Online (Sandbox Code Playgroud)

#=> nslookup headless-svc
Server:     10.96.0.10
Address:    10.96.0.10#53

Name:   headless-svc.moon.svc.cluster.local
Address: 172.17.0.31
Name:   headless-svc.moon.svc.cluster.local
Address: 172.17.0.30
Name:   headless-svc.moon.svc.cluster.local
Address: 172.17.0.32
Run Code Online (Sandbox Code Playgroud)

DNS 服务器返回三个不同IPsheadless-svc.moon.svc.cluster.local FQDN.

注意 1: 对于无头服务,客户端可以通过连接到服务的 DNS 名称来连接到它的 pod,就像使用常规服务一样。但是对于无头服务,因为 DNS 返回 Pod 的 IP,客户端直接连接到 Pod,而不是通过服务代理。

注 2: Headless 服务仍然提供跨 Pod 的负载平衡,但通过 DNS 轮询机制而不是通过服务代理。


Adr*_*ian 5

我认为最常见的用例主要是 StatefulSets,它目前需要一个 Headless Service。当你可能使用一个时,看看为什么-statefulsets-cant-a-stateless-pod-use-persistent-volumes ...