相关文章推荐
独立的书签  ·  nginx laravel 502 Bad ...·  昨天    · 
坚韧的酸菜鱼  ·  怎么将standard = ...·  2 月前    · 
成熟的柳树  ·  使用git ...·  1 年前    · 

一、首先说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