无头服务

无头服务(Headless Service)是 Kubernetes 中的一种特殊服务类型,主要用于提供稳定的网络标识,而不需要通过负载均衡来分配流量。它允许直接访问 Pod,而不经过集群内的负载均衡器,并且通常用于有状态的应用场景(如 StatefulSet)。无头服务的典型用例是数据库、缓存、或者有状态的集群应用。

无头服务的特点

  1. 没有 Cluster IP:与普通服务不同,无头服务不分配 ClusterIP,因此不会通过服务的 IP 地址进行负载均衡。
  2. 直接解析到 Pod IP:当客户端通过无头服务的 DNS 名称查询时,Kubernetes 会直接返回与该服务匹配的 Pod 的 IP 地址列表。客户端可以直接与这些 Pod 通信。
  3. 有状态应用:无头服务常用于有状态的应用,如 Kafka、Elasticsearch、Zookeeper 等,这类应用需要能够直接访问特定 Pod,而不是通过负载均衡器随机访问。也会通常与 StatefulSet 结合使用,以便于有状态应用能够通过稳定的网络标识直接访问各个 Pod
  4. 自定义负载均衡:在某些情况下,应用可能希望自己管理负载均衡,而不依赖 Kubernetes 提供的负载均衡功能。

无头服务的 DNS 解析

​ 无头服务的 DNS 解析与普通服务不同。普通服务通过单个 ClusterIP 提供服务,而无头服务返回的 DNS 记录是所有匹配的 Pod 的 IP 地址列表。以下是几种 DNS 解析方式:

  • Pod 级别的 DNS 解析:客户端可以通过 <pod-name>.<svc-name>.namespace.svc.cluster.local 直接访问特定 Pod。
  • 服务级别的 DNS 解析:无头服务会返回一个包含所有相关 Pod 的 IP 地址的列表,客户端可以选择其中一个进行通信。

无头服务与 Pod 的关联

​ 无头服务(Headless Service)与 Pod 的关联主要是通过选择器(selector)来完成的。无头服务通过选择器将流量路由到符合条件的 Pod,而 Deployment 负责创建和管理这些 Pod,它定义了要运行的 Nginx Pod 的副本和配置。使用标签(label)来标识这些 Pod。Kubernetes 中的服务选择器只能选择与服务位于同一命名空间中的 Pod。因此,定义无头服务的 selector 必须匹配它所管理的 Pod 的标签,而这些 Pod 必须在同一命名空间中。

关联流程
  1. 创建 Deployment:Deployment 会创建多个 Pod,并将这些 Pod 赋予 app: nginx 标签。
  2. 创建无头服务:无头服务根据选择器 app: nginx 查找所有带有该标签的 Pod。
  3. DNS 解析:无头服务会为每个 Pod 创建 DNS 记录,格式为 <pod-name>.nginx-headless.<namespace>.svc.cluster.local,允许直接通过 DNS 名称访问每个 Pod。

创建无头服务

​ 要创建一个无头服务,只需在服务的 spec 中将 clusterIP 字段设置为 None。以下是一个创建无头服务的示例:

apiVersion: v1
kind: Service
metadata:
  name: nginx-headless
  namespace: test
spec:
  clusterIP: None  # 无头服务,不分配 ClusterIP
  selector:
    app: nginx-headless  # 选择带有 app: nginx 标签的 Pod
  ports:
  - port: 80
    targetPort: 80
  • clusterIP: None:表示这是一个无头服务,不会分配 ClusterIP。无头服务直接返回匹配 Pod 的 IP 地址。
  • selector: app: nginx-headless:选择所有带有 app: nginx-headless 标签的 Pod。
  • ports:定义服务监听的端口和目标端口,port: 80 是服务端口,targetPort: 80 是 Pod 上的容器端口。

创建 nginx deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-headless
  name: nginx-headless
  namespace: test
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-headless
  template:
    metadata:
      labels:
        app: nginx-headless
    spec:
      containers:
      - image: m.daocloud.io/docker.io/library/nginx:latest
        name: nginx
        ports:
        - name: http
          containerPort: 80       #容器端口
  • metadata.labelsspec.selector.matchLabels:确保 Deployment 和 Service 的标签匹配,使无头服务能够选择这些 Pod。
  • replicas: 2:指定运行两个 Nginx Pod。
  • template.metadata.labels:Pod 模板中的标签,确保 Pod 带有 app: nginx-headless 标签。
  • containers:定义容器的镜像和端口设置,containerPort: 80 是容器中的端口。

测试

image-20240912145504871

测试部署的 nginx 的 PodIP 分别为

pod/nginx-headless-69db456d87-k4x4b 10.244.2.212 node2
pod/nginx-headless-69db456d87-ztdt4 10.244.1.62 node1

本地测试

测试本地服务解析

<service>.<namespace>.svc.cluster.local

# 测试本地DNS解析无头服务
kubectl exec -it nginx -n test -- nslookup nginx-headless.test.svc.cluster.local

image-20240912145804109

测试本地单个 Pod 解析

<pod-name>.nginx-headless.<namespace>.svc.cluster.local

# 测试本地DNS解析单个pod
kubectl exec -it nginx -n test -- nslookup nginx-headless-69db456d87-k4x4b.nginx-headless.test.svc.cluster.local

image-20240912150154523

跨域测试

导出无头服务

# 导出服务
subctl export service --namespace test nginx-headless
# 查看serviceimport
kubectl get serviceimport -A
# 查看serviceexport
kubectl get serviceexport -A

image-20240912150351501

测试跨域服务解析

<service>.<namespace>.svc.clusterset.local 或者

<clusterid>.<service>.<namespace>.svc.clusterset.local

kubectl exec -it nginx -n test -- nslookup nginx-headless.test.svc.clusterset.local
# 或者
kubectl exec -it nginx -n test -- nslookup pve3.nginx-headless.test.svc.clusterset.local

image-20240912150700976

image-20240912150737154

测试跨域单个 Pod 解析

<pod-name>.<clusterid>.<service>.<namespace>.svc.clusterset.local

kubectl exec -it nginx -n test -- nslookup nginx-headless-69db456d87-ztdt4.pve3.nginx-headless.test.svc.clusterse
t.local

image-20240912150926039

以上可解析的情况均可访问
image-20240912151046982

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐