kubernets Headless Services

什么是headless services:

Headless Services 是用来做什么的呢?

有时您不需要或不需要负载平衡和单个服务IP。在这种情况下,您可以通过指定"None"群集IP(.spec.clusterIP)来创建“无头”服务。

此选项允许开发人员通过允许他们自由地以自己的方式进行发现来减少与Kubernetes系统的耦合。应用程序仍然可以使用自注册模式,并且可以轻松地在此API上构建适用于其他发现系统的适配器。

为此Services,没有分配集群IP,kube-proxy不处理这些服务,并且平台没有为它们完成负载平衡或代理。如何自动配置DNS取决于服务是否已定义选择器。

 

Headless Service也是一种Service,但不同的是会定义spec:clusterIP: None,也就是不需要Cluster IPService

还记得Service的Cluster IP是做什么的吗?对,一个Service可能对应多个EndPoint(Pod),client访问的是Cluster IP,通过iptables规则转到Real Server,从而达到负载均衡的效果(实现原理请见这里)。如下

 

[root@feiba-k8s-master1-192-168-1-16 nginx]# kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1            443/TCP   23d
nginx1       ClusterIP   None                 80/TCP    3h


[root@feiba-k8s-master1-192-168-1-16 nginx]# kubectl describe  service kubernetes
Name:              kubernetes
Namespace:         default
Labels:            component=apiserver
                   provider=kubernetes
Annotations:       
Selector:          
Type:              ClusterIP
IP:                10.96.0.1
Port:              https  443/TCP
TargetPort:        6443/TCP
Endpoints:         192.168.1.12:6443,192.168.1.13:6443,192.168.1.14:6443
Session Affinity:  None
Events:

            
[root@feiba-k8s-master1-192-168-1-16 nginx]# nslookup  kubernetes.default.svc.flybycs.com 10.96.0.114
Server:		10.96.0.114
Address:	10.96.0.114#53

Name:	kubernetes.default.svc.flybycs.com
Address: 10.96.0.1

虽然service有3个endpoint,但是dns查询时只会返回service的地址。具体client访问的是哪个Real Server,是由iptables来决定的。

我们在来看下Headless Service的效果

kubectl get service
NAME                      CLUSTER-IP       EXTERNAL-IP       PORT(S)    AGE
nginx                     None             <none>            80/TCP     1h
kubectl describe  service nginx
Name:                   nginx
Namespace:              default
Labels:                 app=nginx
Selector:               app=nginx
Type:                   ClusterIP
IP:                     None
Port:                   web     80/TCP
Endpoints:              10.244.2.17:80,10.244.2.18:80
Session Affinity:       None
No events.
nslookup nginx.default.svc.cluster.local 10.96.0.114
Server:         10.96.0.114
Address:        10.96.0.114#53

Name:   nginx.default.svc.flybycs.com
Address: 10.244.2.17
Name:   nginx.default.svc.flybycs.com
Address: 10.244.2.18

dns查询会如实的返回2个真实的endpoint。

 

Headless Service有什么用处

所以,顾名思义,Headless Service就是没头的Service。有啥用呢?很简单,有时候client想自己来决定使用哪个Real Server,可以通过查询DNS来获取Real Server的信息。

另外,Headless Services还有一个用处。Headless Service的对应的每一个Endpoints,即每一个Pod,都会有对应的DNS域名;这样Pod之间就可以互相访问。我们还是看上面的这个例子。

kubectl get statefulsets web
NAME      DESIRED   CURRENT   AGE
web       2         2         1h
kubectl get pods
web-0                       1/1       Running   0          1h
web-1                       1/1       Running   0          1h
nslookup nginx.default.svc.flybycs.com 10.96.0.10
Server:         10.96.0.114
Address:        10.96.0.114#53

Name:   nginx.default.svc.flybycs.com
Address: 10.244.2.17
Name:   nginx.default.svc.flybycs.com
Address: 10.244.2.18

nslookup web-1.nginx.default.svc.flybycs.com 10.96.0.114
Server:         10.96.0.114
Address:        10.96.0.114#53

Name:   web-1.nginx.default.svc.flybycs.com
Address: 10.244.2.18

nslookup web-0.nginx.default.svc.flybycs.com 10.96.0.114
Server:         10.96.0.114
Address:        10.96.0.114#53

Name:   web-0.nginx.default.svc.flybycs.com
Address: 10.244.2.17

如上,web为我们创建的StatefulSets,对应的pod的域名为web-0,web-1,他们之间可以互相访问,这样对于一些集群类型的应用就可以解决互相之间身份识别的问题了。

完整示例:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.11
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      nodeSelector:
        node: kube-node3
      volumes:
        - name: www
          hostPath:
            path: /mydir

 

发表评论