一、Kubernetes 原生服务发现有两条路

原文把服务发现分成了两种最基础的方式:

  • 环境变量
  • DNS

两者都能找到服务,但侧重点不同。

1.1 环境变量方式

当 Pod 启动时,kubelet 会把已存在 Service 的地址和端口注入成环境变量,例如:

{SVCNAME}_SERVICE_HOST
{SVCNAME}_SERVICE_PORT

例如 kube-dns 可能会被注入成:

kubectl exec -it metrics-server-xxx -n kube-system -- env | grep KUBE_DNS_PORT

这种方式的注意点也很明确:如果客户端 Pod 创建时目标 Service 还不存在,它就拿不到这些变量。

1.2 DNS 方式

DNS 方式由 CoreDNS 之类的集群 DNS 服务负责,Service 创建后会自动生成解析记录。原文示例中可以这样验证:

kubectl run redis --image=redis:3.2.10-alpine
kubectl exec -it redis -- nslookup kube-dns.kube-system

这也是现在更主流的服务发现方式,因为它和应用代码的耦合更低。

二、Headless Service 和普通 Service 最大的区别

普通 Service 解析出来的是 Service 的 ClusterIP;Headless Service 不分配 ClusterIP,而是直接返回后端 Pod 的 IP 列表。

也就是说:

  • 普通 Service 更像统一入口
  • Headless Service 更像实例目录

这正是它适合有状态应用和分布式系统的原因。

三、Headless Service 是怎么定义的

定义方式很简单,关键是把 clusterIP 设为 None

apiVersion: v1
kind: Service
metadata:
  name: headless
  labels:
    app: headless
spec:
  ports:
  - port: 80
  clusterIP: None
  selector:
    app: headless

原文示例还把它和 StatefulSet 一起使用:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: headless
spec:
  serviceName: "headless"
  replicas: 3
  selector:
    matchLabels:
      app: headless
  template:
    metadata:
      labels:
        app: headless
    spec:
      containers:
      - name: headless
        image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2

四、Headless Service 适合哪些场景

原文给出的典型场景有三类:

  • 有状态应用的服务发现和实例互联
  • 需要直接访问 Pod IP 的应用
  • 分布式系统中节点对节点的直接通信

所以像数据库集群、消息队列、注册中心、分布式协调组件,都很适合这种模式。

五、Pod 级 DNS 长什么样

Headless Service 创建后,Kubernetes 会为每个 Pod 创建可解析的 DNS 记录,典型格式是:

<pod-name>.<service-name>.<namespace>.svc.cluster.local

原文示例里,3 个 Pod 分别可以解析成:

  • headless-0.headless.default.svc.cluster.local
  • headless-1.headless.default.svc.cluster.local
  • headless-2.headless.default.svc.cluster.local

验证时可以直接:

nslookup headless-0.headless
nslookup headless-1.headless
nslookup headless-2.headless

每条记录都会返回对应 Pod 的真实 IP。

六、直接解析 Service 名会发生什么

如果直接解析 headless 本身,而不是某个具体实例名,结果通常会返回所有后端 Pod 的地址:

nslookup headless

这说明 Headless Service 不提供传统意义上的单一虚拟入口,而是把可用实例列表交给客户端自己感知和处理。

七、怎么选更合适

如果你的目标是“隐藏后端实例,只给一个统一入口”,选普通 Service;如果你的目标是“明确知道每个实例是谁、地址是多少”,选 Headless Service。

而在大多数生产集群里,环境变量和 DNS 是服务发现的基础机制,Headless Service 则是在此之上更进一步暴露“实例身份”的网络抽象。