Kubernetes允许客户通过DNS查找发现pod IP。通常,当执行服务的DNS查找时,DNS服务器会返回单个IP——服务的cluster IP。但是,如果告诉Kubernetes,不需要为服务提供cluster IP(通过在服务spec中将clusterIP字段设置为None),则DNS服务器将返回pod IP而不是单个的服务IP。
DNS服务器不会返回单个DNS A记录,而是会为该服务返回多个A记录,每个记录指向该服务后端的单个pod的IP。客户端因此可以做一个简单的DNS A记录查找并获取属于该服务所有的pod的IP。

5.6.1创建headless service

将服务spec中的clusterIP字段设置为None会使服务成为headless service,因为Kubernetes不会为其分配cluster IP (这是一个虚拟IP)。
image.png

  1. cd /root/k8s
  2. kubectl delete all --all
  3. kubectl create -f kubia-rc.yaml
  4. cat >kubia-svc-headless.yaml <<'EOF'
  5. apiVersion: v1
  6. kind: Service
  7. metadata:
  8. name: kubia-headless
  9. spec:
  10. clusterIP: None
  11. ports:
  12. - port: 80
  13. targetPort: 8080
  14. selector:
  15. app: kubia
  16. EOF
  17. kubectl create -f kubia-svc-headless.yaml

image.png

5.6.2 通过DNS发现pod

不通过YAML文件运行pod

运行一个包含nslookup和dig二进制文件的pod,需要下载镜像
kubectl run dnsutils --image=tutum/dnsutils --command -- sleep infinity

理解headless service的DNS A记录解析

image.png
DNS服务器为kubia-headless.default.svc.cluster.local FQDN返回3个不同的IP,这与常规的service返回的DNS不同(Cluster IP)。

即使使用headless服务,客户也可以通过连接到服务的DNS名称来连接到pod上,就像使用常规服务一样。但是对于headless服务,由于DNS返回了pod的IP,客户端直接连接到该pod,而不是通过服务代理。

注意:headless服务仍然提供跨pod的负载平衡,但是通过DNS轮询机制不是通过服务代理。

5.6.3发现所有的pod——包括未就绪的pod

只有准备就绪的pod能够作为服务的后端。但有时希望即使pod没有准备就绪,服务发现机制也能够发现所有匹配服务的标签选择器的pod。

可以使用DNS查找机制来查找那些未准备好的pod。要告诉Kubemetes无论pod的准备状态如何,希望将所有pod添加到服务中,必须将以下注解添加到服务中:

  1. kind: Service
  2. metadata:
  3. annotations:
  4. service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"

或 使用svc.spec.publishNotReadyAddresses字段

kind: Service
metadata:
spec:
  publishNotReadyAddresses: true

注意:一般不建议开启这两个功能。如果pod还未就绪,发送到上面的请求可能得不到正常的响应。