当前位置: 首页 > news >正文

【k8s、docker】Headless Service(无头服务)

文章目录

  • 问题背景
  • 1、什么是Headless Service
    • 1.2 为什么 Zookeeper 使用 Headless Service?
    • 1.2 Headless Service 的 DNS 行为
    • 1.3 验证示例
    • 1.4 如何创建 Headless Service?
  • 2. zk-0.zookeeper.default.svc.cluster.local 域名是如何创建出来的? 是无头服务自动映射的吗

问题背景

zookeeper ClusterIP None 这中svc作用是什么,为什么没有cluster ip

1、什么是Headless Service

在 Kubernetes 中,ClusterIP 类型的 Service 被设置为 None(即 ClusterIP: None)时,表示这是一个 Headless Service(无头服务)。这种设计有特定的用途和行为模式:
Headless Service 的核心作用:

  1. 直接访问 Pod IP,跳过 Service 代理

    • 普通 Service:会分配一个虚拟 ClusterIP,流量通过 kube-proxy 负载均衡到后端 Pod。

    • Headless Service:没有 ClusterIP,DNS 查询直接返回所有后端 Pod 的 IP 地址(而非 Service 的虚拟 IP)。

  2. 适用场景

  • 有状态应用(如 Zookeeper、Kafka、MongoDB):需要直接访问特定 Pod(如通过 Pod 域名)。

  • 自定义服务发现:应用需要自行处理负载均衡或直接连接 Pod。

  • StatefulSet 配套使用:StatefulSet 的 Pod 具有稳定的域名(如 pod-name.svc-name.namespace.svc.cluster.local)。

1.2 为什么 Zookeeper 使用 Headless Service?

简单来说,当一个pod 是sts类型,每个副本的名称,都是固定的(固定名称是前提,不像deployment生成的pod都会带随机字符串 ),如 zk-0、zk-1,此时需要无头服务,被访问时,都是指定访问,不能直接负载均衡随机调度。

Zookeeper 是一个有状态分布式协调服务,它的典型配置需求:

支持应用层的负载均衡或服务发现:

  • 客户端应用(或应用内置的逻辑)可以获取到所有后端 Pod 的 IP 列表,然后自己决定如何连接(例如,轮询、根据角色选择 leader 等)。
  • 对于像 ZooKeeper 这样的集群,成员之间需要互相知道彼此的地址来形成集群,Headless Service 提供了完美的解决方案。

支持直接的 Pod-to-Pod 通信:

  • 当你需要直接连接到某个特定的 Pod 实例时(比如访问主节点进行写操作,或进行健康检查),可以通过其唯一的 DNS 名称直接访问。:StatefulSet + Headless Service 能为每个 Pod 提供固定域名

1.2 Headless Service 的 DNS 行为

对于 Service zookeeper:

  • 普通查询(非 Headless):

    nslookup zookeeper.mano-2.svc.cluster.local
    

    返回一个虚拟 ClusterIP。

  • Headless 查询:

    nslookup zookeeper.mano-2.svc.cluster.local
    

    返回所有后端 Pod 的 IP 地址(例如):

    Name:   zookeeper.mano-2.svc.cluster.local
    Address: 10.244.1.10  # zk-0 的 IP
    Address: 10.244.2.20  # zk-1 的 IP
    Address: 10.244.3.30  # zk-2 的 IP
    

如果您的 ZooKeeper StatefulSet 有 3 个副本,名为 zk-0, zk-1, zk-2,那么 DNS 会解析:

  • zookeeper.default.svc.cluster.local -> 返回 zk-0, zk-1, zk-2 的 IP 地址列表(A 记录)。
  • zk-0.zookeeper.default.svc.cluster.local -> 返回 zk-0 Pod 的 IP 地址。
  • zk-1.zookeeper.default.svc.cluster.local -> 返回 zk-1 Pod 的 IP 地址。
  • zk-2.zookeeper.default.svc.cluster.local -> 返回 zk-2 Pod 的 IP 地址。

1.3 验证示例

1、查看 Service 定义

kubectl get svc zookeeper -o yaml
输出关键字段:

spec:clusterIP: None  # 明确标记为 Headlessports:- port: 2181targetPort: 2181selector:app: zookeeper

2、通过 DNS 直接访问 Pod
每个 StatefulSet 的 Pod 会获得独立域名:

# 查询单个 Pod 的 DNS
nslookup zk-0.zookeeper.mano-2.svc.cluster.local# 客户端连接示例(Zookeeper 客户端)
zkCli.sh -server zk-0.zookeeper:2181,zk-1.zookeeper:2181,zk-2.zookeeper:2181

与普通 Service 的对比:

特性Headless Service普通 Service
ClusterIPNone自动分配虚拟 IP (如 10.96.x.x)
DNS 解析结果返回所有 Pod IP返回 Service 的 ClusterIP
负载均衡由客户端或应用层实现由 kube-proxy 实现(iptables/IPVS)
典型应用场景有状态服务(如 Zookeeper、MySQL)无状态服务(如 Nginx、微服务)

1.4 如何创建 Headless Service?

Headless 示例:

apiVersion: v1
kind: Service
metadata:name: zookeepernamespace: default
spec:clusterIP: None # 这是关键,指定为 Noneports:- port: 2181name: client- port: 2888name: server- port: 3888name: leader-electionselector:app: zookeeper # 选择后端 Pod 的标签# 注意:Headless Service 通常不指定 type,默认就是 ClusterIP
  • clusterIP: None:这不是“不想要 IP”,而是明确地、主动地要求创建一个 Headless Service(无头服务)。它告诉 Kubernetes:“我不要你为这个服务分配一个虚拟的 ClusterIP,我要直接访问后端的 Pod”。
  • 自动分配 ClusterIP:这是 Kubernetes Service 的默认行为。你不需要做任何特殊配置来“开启”自动分配。

有头示例:

apiVersion: v1
kind: Service
metadata:name: my-web-service
spec:# 注意:这里完全不写 clusterIP 字段ports:- port: 80targetPort: 8080protocol: TCPname: httpselector:app: my-web-app# type: ClusterIP # type 字段也可以省略,默认就是 ClusterIP

当你创建这个 Service 时,Kubernetes 会:

  • 自动从集群的 Service IP 池(由 --service-cluster-ip-range 参数定义)中选择一个可用的 IP 地址。
  • 将这个 IP 地址分配给该 Service。
  • 你可以在 kubectl get svc 的输出中看到这个分配的 IP(不再是 None)。

2. zk-0.zookeeper.default.svc.cluster.local 域名是如何创建出来的? 是无头服务自动映射的吗

是的,zk-0.zookeeper.default.svc.cluster.local 这个域名是由 Kubernetes 的 Headless Service(无头服务)机制自动创建的,其核心原理依赖于 Kubernetes DNS 系统(如 CoreDNS)的自动服务发现功能。

下面简述其工作原理:

1、 前提条件:Headless Service + StatefulSet
这个域名的自动生成,通常发生在以下组合中:

  • 一个 Headless Service:clusterIP: None
  • 一个 StatefulSet:管理有状态应用的 Pod,如 zk-0, zk-1, zk-2

2、DNS 自动映射原理
当满足上述条件时,Kubernetes DNS 组件(如 CoreDNS)会根据以下规则自动为每个 Pod 生成稳定的 DNS 记录:

规则一:Pod 主机名 DNS 记录
对于每一个由 StatefulSet 创建的 Pod(如 zk-0),DNS 会生成一条 A 记录:

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

在你的例子中:

pod-name = zk-0
service-name = zookeeper
namespace = default
cluster.local = 集群默认域名

在这里插入图片描述

http://www.lryc.cn/news/623466.html

相关文章:

  • python+flask后端开发~项目实战 | 博客问答项目--模块化文件架构的基础搭建
  • C++算法题目分享:二叉搜索树相关的习题
  • 【前端基础】flex布局中使用`justify-content`后,最后一行的布局问题
  • ubuntu 24.04 安装
  • Android RxJava线程调度与性能优化指南
  • (一)前端面试(cookie/)
  • PostgreSQL导入mimic4
  • 数据结构代码分享-1 顺序表
  • 简单的 VSCode 设置
  • Oracle algorithm的含义
  • 基于Vue + Node能源采购系统的设计与实现/基于express的能源管理系统#node.js
  • Qt 5.5 的安装与配置(使用 VSCode编辑)
  • 【架构师从入门到进阶】第五章:DNSCDN网关优化思路——第十二节:网关安全-信息过滤
  • 基于多Agent的AFSIM复杂场景脚本生成技术(使用Claude Code)
  • 根号算法Ⅰ
  • 天地图应用篇: 增加缩放、比例尺控件
  • 24. 什么是不可变对象,好处是什么
  • 【Docker】搭建一款功能强大且免费的开源在线绘图工具 - draw.io
  • 云原生俱乐部-RH134知识点总结(2)
  • 62.不同路径
  • 【计算机网络面试】键入网址到网页显示期间,发生了什么?
  • 网络常识-DNS如何解析
  • 数据结构初阶(19)外排序·文件归并排序的实现
  • Ugit使用记录
  • 【自动化运维神器Ansible】template流程控制:for循环与if条件判断详解
  • Flink作业执行的第一步:DataFlow graph的构建
  • C11期作业18(07.12)
  • 栈与队列:数据结构中的双生子
  • 【JavaEE】多线程 -- 单例模式
  • [python学习记录2]变量