一、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.localheadless-1.headless.default.svc.cluster.localheadless-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 则是在此之上更进一步暴露“实例身份”的网络抽象。