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 IP
的Service
。
还记得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