在某些应用场景中,客户端应用不需要通过Kubernetes 内置Service 实现的负载均衡功能,或者需要自行完成对服务后端各实例的服务发现机制,或者需要自行实现负载均衡功能,此时可以通过创建一种特殊的名为“Headless” 的服务来实现。

Headless Service 的概念是这种服务没有入口访问地址(无ClusterIP 地址),kube-proxy 不会为其创建负载均衡转发规则,而服务名(DNS域名)的解析机制取决于该Headless Service 是否设置了Label Selector。

1. Headless Service 设置了Label Selector

如果Headless Service 设置了Label Selector ,Kubernetes 则将Label Selector 查询后端Pod 列表,自动创建Endpoint 列表,将服务名(DNS域名)的解析机制设置为:当客户端访问该服务名时,得到的是全部Endpoint 列表(而不是一个确定的IP地址)。

以下面的Headless Service 为例,其设置了Label Selector:

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

创建该Headless Service:

[root@k8s-master ~]# kubectl create -f nginx-headless-service.yaml 
service/nginx created

假设在集群中已经运行了2个副本nginx deployment ,查看他们的Pod IP 地址:

[root@k8s-master ~]# kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS        AGE   IP               NODE         NOMINATED NODE   READINESS GATES
nginx-deployment-64775df955-dzjps   1/1     Running   11 (3d1h ago)   36d   10.244.140.125   k8s-node-2   <none>           <none>
nginx-deployment-64775df955-jk28d   1/1     Running   11 (3d1h ago)   36d   10.244.109.121   k8s-node-1   <none>           <none>

查看该Headless Service 的详细信息,可以看到后端Endpoint 列表:

[root@k8s-master ~]# kubectl describe svc nginx
Name:              nginx
Namespace:         default
Labels:            app=nginx
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                None
IPs:               None
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         10.244.109.121:8080,10.244.140.125:8080
Session Affinity:  None
Events:            <none>

用nslookup 工具对Headless Service 名称尝试域名解析,将会看到DNS 系统返回的全部Endpoint 的IP地址,例如:

[root@k8s-master ~]# nslookup nginx.default.svc.cluster.local
Server:		169.169.0.100
Address:	169.169.0.100#53

Name: nginx.default.svc.cluster.local
Address: 10.244.109.121
Name: nginx.default.svc.cluster.local
Address: 10.244.140.125

当客户端通过DNS 服务名“nginx“(或其FQDN 全限定域名“nginx..svc.cluster.local”)和服务端口号访问该Headless 服务(URL=nginx:80) 时,将得到Service 后端Endpoint 列表10.244.109.121:8080 ,10.244.140.125:8080 ,然后由客户端程序自行决定如何操作,例如通过轮询访问各个Endpoint。

2. Headless Service 没有设置Label Selector

如果Headless Service 没有设置Label Selector,则Kubernetes 将不会自动创建对应的Endpoint 列表,DNS 系统会根据下列条件尝试对该服务名设置DNS 记录:
(1)如果Service 的类型为ExTernalName ,则对服务名的访问将直接被DNS 系统转换为Service 设置的外部名称(externalName)。
(2)如果系统中存在与Service 同名的Endpoint 定义,则服务名将被解析为Endpoint 定义中的列表,适用于ExTernalName类型的Service。

Logo

开源、云原生的融合云平台

更多推荐