Kubernetes——Headless类型的Service资源
Headless 类型的 Service 资源
Service 对象隐藏了各 Pod 资源,并负责将客户端的请求流量调度到该组 Pod 对象之上。
不过偶尔也存在这样一类需求:客户端需要直接访问 Service 资源后端的所有 Pod 资源,这时就应该向客户端暴露每个 Pod 资源的 IP 地址,而不再是中间层 Service 对象的 ClusterIP,这种类型的 Service 资源便称为 Headless Service。
Headless Service 对象没有 ClusterIP,于是 kube-proxy 便无须处理此类请求,也就更没有了负载均衡或代理它的需求。至于如何为此类 Service 资源配置 IP 地址,则取决于它的标签选择器的定义:
- 具有标签选择器:端点控制器(Endpoints Controller)会在 API 中为其创建 Endpoints 记录,并将 ClusterDNS 服务中的 A 记录直接解析到此 Service 后端的各 Pod 对象的 IP 地址上。
- 没有标签选择器:端点控制器(Endpoints Controller)不会在 API 中为其创建 Endpoints 记录,ClusterDNS 的配置分为两种情形,对 ExternalName 类型的服务创建 CNAME 记录,对其他三种类型来说,为那些与当前 Service 共享名称的所有 Endpoints 对象创建一条记录。
一、创建 Headless Service 资源
配置 Service 资源配置清单时,只需要将 ClusterIP 字段的值设置为 "None" 即可将其定义为 Headless 类型。下面是一个 Headless Servcie 资源配置清单示例,它拥有标签选择器:
kind: servcie
apiVersion: v1
metadata:
name: myapp-headless-svc
spec:
clusterIP: None
selector:
app: myapp
ports:
- port: 80
targetPort: 80
name: httport
使用资源创建命令 "kubectl create" 或 “kubectl apply” 完成资源创建后,使用相关查看命令获取 Service 资源的相关信息便可以看出,它没有 ClusterIP,不过,如果标签选择器能够匹配到相关的 Pod 资源,它便拥有 Endpoint 记录,这些 Endpoints 对象会作为 DNS 资源记录名称 myapp-headless-svc 查询时的 A记录解析结果。
二、Pod 资源发现
根据 Headless Service 的工作特性可知,它记录于 ClusterDNS 的 A 记录的相关解析结果是后端 Pod 资源的 IP 地址,这就意味着客户端通过此 Service 资源的名称发现的是各 Pod 资源。
kubectl run cirros-$RANDOM --rm -it --image=crros --sh
#nslookup myapp-headless-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: myapp-headless-svc
Address 1: 10.244.2.13
Address 2: 10.244.1.113
Address 3: 10.244.3.104
其解析结果证实 Headless Service 通过标签选择器关联到的所有 Pod 资源的 IP 地址。
于是,客户端向此 Servcie 对象发起的请求将直接接入到 Pod 资源中的应用之上,而不再由 Servcie 资源进行代理转发,它每次接入的 Pod 资源则是由 DNS 服务器接收到查询请求时间以轮询(roundrobin)的方式返回的 IP 地址。