更新时间:2025-07-18 GMT+08:00

Headless Service

Headless Service是Kubernetes中的一种特殊服务类型,与其他Service相比,Headless Service不会分配ClusterIP,因此不会通过服务的IP地址进行负载均衡。当客户端通过Headless Service的DNS名称查询时,Kubernetes会直接返回与该服务匹配的Pod的IP地址列表,客户端可以直接与这些Pod通信,适用于某些特定的应用(如数据库集群、缓存集群等)。

Headless Service的应用场景如下:

  • 有状态应用:对于有状态负载,例如MySQL、Kafka、Elasticsearch等,每个实例有独立职责,而不需要进行负载均衡。Headless Service可以为每个Pod提供单独的访问入口。
  • 自定义负载均衡:某些情况下,应用可能期望自行控制负载均衡策略,而不使用Kubernetes默认提供的负载均衡能力。

创建Headless Service

  1. 使用kubectl连接集群,详情请参见通过kubectl连接集群
  2. 创建一个StatefulSet和对应的Headless Service。

    vi headless.yaml

    内容如下:

    apiVersion: v1
    kind: Service       # 对象类型为Service
    metadata:
      name: nginx-headless
      labels:
        app: nginx
    spec:
      ports:
        - name: web       # Pod间通信的端口名称
          port: 80        # Pod间通信的端口号
      selector:
        app: nginx        # 选择标签为app:nginx的Pod
      clusterIP: None     # 必须设置为None,表示Headless Service
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      serviceName: nginx-headless   # StatefulSet对应Headless Service的名称
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:alpine
            ports:
            - containerPort: 80
              name: web
          imagePullSecrets:
            - name: default-secret

  3. 执行如下命令创建上述StatefulSet和Headless Service。

    kubectl create -f headless.yaml

  4. 检查Pod是否创建成功。

    kubectl get pods -l app=nginx -o wide

    回显如下:

    NAME     READY   STATUS    RESTARTS   AGE     IP          NODE            NOMINATED NODE   READINESS GATES
    web-0    1/1     Running   0          41s     10.0.0.22   192.168.0.194   <none>           <none>
    web-1    1/1     Running   0          38s     10.0.0.23   192.168.0.194   <none>           <none>
    web-2    1/1     Running   0          37s     10.0.0.39   192.168.0.21    <none>           <none>

  5. 检查Headless Service是否创建成功。

    kubectl get svc nginx-headless

    回显如下:

    NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    nginx-headless   ClusterIP   None         <none>        80/TCP    2m20s

  6. 创建一个临时Pod来查询DNS。

    kubectl run -it --rm --image=busybox:1.28 test-pod -- sh

    查询DNS的命令如下:

    nslookup nginx-headless

    回显如下:

    Server:    10.247.3.10
    Address 1: 10.247.3.10 coredns.kube-system.svc.cluster.local
    
    Name:      nginx-headless
    Address 1: 10.0.0.22 web-0.nginx-headless.default.svc.cluster.local
    Address 2: 10.0.0.23 web-1.nginx-headless.default.svc.cluster.local
    Address 3: 10.0.0.39 web-2.nginx-headless.default.svc.cluster.local

    说明StatefulSet的每个Pod都有单独的DNS记录。

  7. 验证是否可以访问每个Pod。

    wget -qO- web-0.nginx-headless