一、首先说headless Service和普通Service的区别
headless
不分配
clusterIP
headless service
可以通过解析
service
的
DNS
,返回所有
Pod
的地址和
DNS
(statefulSet部署的Pod才有DNS)
普通的
service
,只能通过解析
service
的
DNS
返回
service
的
ClusterIP
二、statefulSet和Deployment控制器的区别
statefulSet
下的
Pod
有
DNS
地址,通过解析
Pod
的
DNS
可以返回
Pod
的
IP
deployment
下的
Pod
没有
DNS
三、通过StatefulSet和headless server部署的服务效果
1.另一个pod里 可以通过dns+[pod的名称
]访问到 该服务
四、普通
Service
接续service的
DNS
结果
Service的ClusterIP工作原理:一个service可能对应一组endpoints(所有pod的地址+端口),client访问ClusterIP,通过iptables或者ipvs转发到Real Server(Pod),具体操作如下
[root@master01 ~]# kubectl get svc -n ms #获取所有svc,看到gateway这个service的clusterIP是10.0.0.14
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
eureka ClusterIP None <none> 8888/TCP 21h
gateway ClusterIP 10.0.0.14 <none> 9999/TCP 20h
mysql-production ClusterIP 10.0.0.251 <none> 3306/TCP 23h
portal ClusterIP 10.0.0.124 <none> 8080/TCP 17h
[root@master01 ~]# kubectl describe svc gateway -n ms #看到gateway这个service的具体信息
Name: gateway
Namespace: ms
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"gateway","namespace":"ms"},"spec":{"ports":[{"name":"gateway","po...
Selector: app=gateway,project=ms
Type: ClusterIP
IP: 10.0.0.14
Port: gateway 9999/TCP
TargetPort: 9999/TCP
Endpoints: 10.244.1.212:9999 #该service下的Pod地址
Session Affinity: None
Events: <none>
[root@master01 ~]# kubectl exec -it gateway-6cd76c98fb-8w92t -n ms sh #进入一个容器测试解析
/ # nslookup gateway.ms.svc.cluster.local #测试解析gateway这个service的DNS
nslookup: can't resolve '(null)': Name does not resolve
Name: gateway.ms.svc.cluster.local
Address 1: 10.0.0.14 gateway.ms.svc.cluster.local #这个结果就是gateway这个service的ClusterIP
从上面的结果能看到,虽然
Service
有1个
endpoint
,但是DNS查询时只会返回
Service
的
ClusterIP
地址,具体
Client
访问的是哪个
real serve
r,由
iptables
或者
ipvs
决定
五
、headless Service
的解析service的
DNS
结果
[root@master01 ~]# kubectl get svc -n ms #查看所有SVC,看到eureka的这个headless service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
eureka ClusterIP None <none> 8888/TCP 21h
gateway ClusterIP 10.0.0.14 <none> 9999/TCP 20h
mysql-production ClusterIP 10.0.0.251 <none> 3306/TCP 23h
portal ClusterIP 10.0.0.124 <none> 8080/TCP 18h
[root@master01 ~]# kubectl describe svc eureka -n ms #看到eureka的这个headless service下面的endpoints
Name: eureka
Namespace: ms
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"eureka","namespace":"ms"},"spec":{"clusterIP":"None","ports":[{"n...
Selector: app=eureka,project=ms
Type: ClusterIP
IP: None
Port: eureka 8888/TCP
TargetPort: 8888/TCP
Endpoints: 10.244.1.210:8888,10.244.1.211:8888,10.244.2.45:8888
Session Affinity: None
Events: <none>
[root@master01 ~]# kubectl exec -it gateway-6cd76c98fb-8w92t -n ms sh #进入容器测试解析
/ # nslookup eureka.ms.svc.cluster.local #通过解析eureka这个headless service的DNS地址,可以看到关联的具体endpoints信息
nslookup: can't resolve '(null)': Name does not resolve
Name: eureka.ms.svc.cluster.local
Address 1: 10.244.1.211 eureka-2.eureka.ms.svc.cluster.local
Address 2: 10.244.1.210 eureka-0.eureka.ms.svc.cluster.local
Address 3: 10.244.2.45 eureka-1.eureka.ms.svc.cluster.local
/ # nslookup eureka-2.eureka.ms.svc.cluster.local #解析pod的DNS记录,也能返回Pod的IP
nslookup: can't resolve '(null)': Name does not resolve
Name: eureka-2.eureka.ms.svc.cluster.local
Address 1: 10.244.1.211 eureka-2.eureka.ms.svc.cluster.local
根据结果看到,
dns
查询会返回3个
endpoint
,也就是3个
pod
地址和
DNS
,通过解析
pod
的
DNS
也能返回
Pod的IP
六、
headless Service
就是没头的
Service
,有什么使用场景呢?
第一种:自主选择权,有时候
client
想自己决定使用哪个
Real Server
,可以通过查询
DNS
来获取
Real Server
的信息
第二种:
headless service
关联的每个
endpoint(也就是Pod)
,都会有对应的
DNS
域名;这样
Pod
之间就可以互相访问
[root@master01 ~]# kubectl get sts -n ms
NAME READY AGE
eureka 3/3 22h
[root@master01 ~]# kubectl get svc -n ms
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
eureka ClusterIP None <none> 8888/TCP 21h
[root@master01 ~]# kubectl describe svc eureka -n ms
Name: eureka
Namespace: ms
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"eureka","namespace":"ms"},"spec":{"clusterIP":"None","ports":[{"n...
Selector: app=eureka,project=ms
Type: ClusterIP
IP: None
Port: eureka 8888/TCP
TargetPort: 8888/TCP
Endpoints: 10.244.1.210:8888,10.244.1.211:8888,10.244.2.45:8888
Session Affinity: None
Events: <none>
[root@master01 ~]# kubectl exec -it gateway-6cd76c98fb-8w92t -n ms sh
/ # nslookup eureka.ms.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve
Name: eureka.ms.svc.cluster.local
Address 1: 10.244.1.211 eureka-2.eureka.ms.svc.cluster.local
Address 2: 10.244.1.210 eureka-0.eureka.ms.svc.cluster.local
Address 3: 10.244.2.45 eureka-1.eureka.ms.svc.cluster.local
/ # nslookup eureka-2.eureka.ms.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve
Name: eureka-2.eureka.ms.svc.cluster.local
Address 1: 10.244.1.211 eureka-2.eureka.ms.svc.cluster.local
/ # nslookup eureka-1.eureka.ms.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve
Name: eureka-1.eureka.ms.svc.cluster.local
Address 1: 10.244.2.45 eureka-1.eureka.ms.svc.cluster.local
/ # nslookup eureka-0.eureka.ms.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve
Name: eureka-0.eureka.ms.svc.cluster.local
Address 1: 10.244.1.210 eureka-0.eureka.ms.svc.cluster.local
如上,
eureka
就是我们场景的
StatefulSet
,对应的
pod
就是
eureka-0,eureka-1,eureka-2
,他们之间能互相访问,这样对于一些集群类型的应用就可以解决互相身份识别的问题了
七、为什么要用
headless service+statefulSet
部署有状态应用?
1.
headless service
会为关联的
Pod
分配一个域
<service name>.$<namespace name>.svc.cluster.local
2.
StatefulSet
会为关联的
Pod
保持一个不变的
Pod Name
statefulset
中
Pod
的
hostname
格式为$(StatefulSet name)-$(pod序号)
3.
StatefulSet
会为关联的
Pod
分配一个
dnsName
$<Pod Name>.$<service name>.$<namespace name>.svc.cluster.local