headless 类型

在学习StatefulSet的时候发现他有个好伙伴 headless.

在创建headless类型的Service并进行测试后发现一个问题: headless和普通的Service(后面统称为 clusterIP类型)的差距似乎只是没有一个自己的IP.

稳定的网络标识,也就是通过集群DNS来访问指定的pod是StatefulSet提供的功能,并不是headless.ClusterIP绑定StatefulSet同样具有稳定的网络标识,不知道为什么很多博客都说这是headless提供的功能.

接下来就是漫长的百度了,基本都是千篇一律说ClusterIP是负载,headless没有负载,然后更加具体的基本就不见了,然后测试了下直接访问Service不管是ClusterIP还是headless每次处理的pod都是随机的,不过得到部分有用信息,就是DNS解析headless类型的Service名称,得到的是pod的IP,而ClusterIP类型的返回的是Service自己的IP(还是没感觉有啥具体作用).

测试了一下确实是:

root@network-tools-66b6674fd9-vpjc4:/# nslookup nginx.default.svc.cluster.local
Server:     10.96.0.10
Address:    10.96.0.10#53Name:  nginx.default.svc.cluster.local
Address: 10.244.235.129
Name:   nginx.default.svc.cluster.local
Address: 10.244.189.88root@network-tools-66b6674fd9-vpjc4:/# nslookup nginx-clusterip.default.svc.cluster.local
Server:     10.96.0.10
Address:    10.96.0.10#53Name:  nginxi-clusterip.default.svc.cluster.local
Address: 10.98.85.244

查看Service

[root@master ~]# kubectl get svc
NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes         ClusterIP   10.96.0.1      <none>        443/TCP   16d
nginx              ClusterIP   None           <none>        80/TCP    37m
nginx-clusterip    ClusterIP   10.98.85.244   <none>        80/TCP    8s
[root@master ~]# kubectl get pod -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP               NODE      NOMINATED NODE   READINESS GATES
network-tools-66b6674fd9-vpjc4   1/1     Running   0          22m   10.244.235.138   worker1   <none>           <none>
web-0                            1/1     Running   0          24m   10.244.235.129   worker1   <none>           <none>
web-1                            1/1     Running   0          24m   10.244.189.88    worker2   <none>           <none>

下面用自己的理解描述下headless.

与其说ClusterIP是"负载",更不如说是"转发".为什么这么说呢,首先Service自己拥有一个IP地址的,当对Service发起请求的时候,数据包的三层源IP自然就是自己,目标IP是Service的IP.

假设在上面network-tools容器中(IP地址: 10.244.235.138)访问Servicenginxi-clusterip.

数据包三层目标IP应该是Service的IP,假设Service也是一个pod,按照正常的网络接收发送数据包.

Service可以正常收到这个包,因为目标IP是他自己,但是他不具备处理里面数据的能力,所以这个包最终是要交给pod去处理的.

但是这个包还不能直接发出去.因为目标IP是自己,数据包发出去即便能到对应的pod,那么pod也会将它丢弃.因为目标IP不是自己.

所以Service在此处要对数据包进行处理.而处理过程很简单 ,使用**DNAT**.

DNAT很简单,就是修改三层数据包中的目标IP,然后就变成了下面的样子:

这么一来,pod接收到数据包后发现目标IP是自己,就会继续拆包获取里面的数据.同时他还知道这个数据包的源IP,如果需要相应的话目标IP直接写数据包的源IP10.244.235.138即可.

Service基于iptables(或IPVS)实现,所以DNAT这个步骤是由iptables来完成的.

headless

访问ClusterIP类型的Service名称解析到Service的IP,然后对这个IP发起请求.而headless是没有这个IP的.他解析Service名字拿到的直接就是一组POD的IP.

直接少了一层转发,pod可以直接对pod发起请求.

headless特点2 无端口限制

在上面ClusterIP类型的Service请求中,可以看到一个targetPort字段和port字段.

targetPort : 监听从此端口来的流量

Port: 转发到pod的那个端口

在ClusterIP类型中,你请求Service时只能请求被targetPort定义的端口.这个很简单就能理解,同样把Service想象成一个主机,这个主机监听了8080端口,然后把这个端口接收到的请求转发到另一个主机的80端口.如果你请求一个Service没有定义的端口那么则和主机一样返回Connection refused(是Service返回的).

如果这个Service是headless类型的,那么则没有了这个端口的限制.headless类型的Service的yaml文件中的port字段实际也没什么意义.因为你解析这个Service的名字得到的是一组pod的IP,发起请求时数据包会全部被StatefulSet的 pod所接收到.只需要pod监听了对应的端口那么就能互相通信.

总结

直接解析Service的名字,headless返回的是所有pod的IP地址.ClusterIP返回的是自己的IP地址.

ClusterIP类型会DNAT转发数据包(改变目标IP)

在某些特殊的情景中,如服务端(StatefulSet)是一个集群,客户端想要获取所有的节点列表然后从中选取某个或者某些建立连接,那么headless明显更加合适.因为你直接请求他的Service便能得到所有健康的pod的IP地址.

再或者想要直接和pod建立连接,互相访问端口,headless的无端口转发限制的优点则可以更好地发挥.

而Service的IP地址比起pod的IP地址(headless DNS直接指向pod IP)来说更加稳定(排除重启,Service只有在被删除重建后IP地址才会被更改),而DNS实现已久,他不遵守TTL(生存时间值),有些应用程序甚至只执行一次DNS查找然后永久缓存.即便应用进行了适当的时间间隔更新DNS,也有可能给DNS服务带来高负载.

其他注意点

创建的Service是否能提供稳定的网络取决于StatefulSet的spec.serviceName字段.同时要求Service比StatefulSet更先创建出.如果Service的名字和StatefulSet的spec.serviceName字段不同,那么没办法使用"稳定的网络"这一特性.

测试过程步骤

首先创建一个headless类型和普通的Service的资源

apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx
---
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webtargetPort: 8080selector:app: nginx

接下来创建对应的StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:serviceName: "nginx"replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80name: web

创建一个pod,对其发起网络请求

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: network-toolsname: network-toolsnamespace: default
spec:replicas: 1selector:matchLabels:app: network-toolstemplate:metadata:creationTimestamp: nulllabels:app: network-toolsspec:affinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues:- network-toolstopologyKey: kubenetes.io/hostnameweight: 1containers:- env:- name: SYSTEM_INFORMATIONvalue: centos# 镜像内默认安装了部分网络相关命令image: 528909316/check:debian_11imagePullPolicy: Alwaysname: network-toolsports:- containerPort: 9000protocol: TCPresources:limits:cpu: 100mmemory: 100Mirequests:cpu: 10mmemory: 30MirestartPolicy: Always

稳定的网络标识:

接下来,可以再新启动的容器中,使用域名web-0.nginx.default.svc.cluster.local或者web-0.nginx(pod名称.Service名称)来访问StatefulSet中指定的pod了.

ping -c 1 web-0.nginx.default.svc.cluster.local

稳定的网络标识是StatefulSet的功能,并不是headless提供的.如果将Service替换为ClusterIP类型同样有相同作用.


以上内容纯属个人总结理解,如有错误恳请大佬的斧正和指点,感激不尽.

Kubernetes Service的headless类型相关推荐

  1. Kubernetes集群服务发现Service资源LoadBalancer类型详解(二十九)

    Kubernetes集群服务发现Service资源LoadBalancer类型详解 1.LoadBalancer类型的service资源概念 LoadBalancer和Nodeport非常相似,目的都 ...

  2. Kubernetes Service(溪恒)

    本文将主要分享以下四方面的内容: 为什么需要 K8s service: K8s service 用例解读: K8s service 操作演示: K8s service 架构设计. 需求来源 为什么需要 ...

  3. 容器编排技术 -- Kubernetes Service

    容器编排技术 -- Kubernetes Service 1 定义 Service 1.1 没有 selector 的 Service 2 VIP 和 Service 代理 2.1 userspace ...

  4. 学练结合,快速掌握Kubernetes Service

    今天这篇文章里我们来讲一下Kubernetes里的Service对象.其实前面的文章<Kubernetes初体验--部署运行Go项目>里我们已经与Service有过一次短暂接触了,在那篇文 ...

  5. Kubernetes Service详解(概念、原理、流量分析、代码)

    Kubernetes Service详解(概念.原理.流量分析.代码) 作者: liukuan73 原文:https://blog.csdn.net/liukuan73/article/details ...

  6. Kubernetes Service与Ingress详解

    SVC与Ingress 一.Service 的概念 二.Service 的类型 三.VIP 和 Service 代理 四.ipvs代理模式 五.Service实验讲解 5.1 ClusterIP 5. ...

  7. k8s技术预研8--深入掌握Kubernetes Service

    本文内容已经基于k8s v1.8.8进行了验证测试. k8s的Service定义了一个服务的访问入口地址,前端的应用通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,来自外部的访问请求被负载 ...

  8. Kubernetes Service 对象的使用

    我们前面的课程中学习了Pod的基本用法,我们也了解到Pod的生命是有限的,死亡过后不会复活了.我们后面学习到的RC和Deployment可以用来动态的创建和销毁Pod.尽管每个Pod都有自己的IP地址 ...

  9. C# 开源一个基于 yarp 的 API 网关 Demo,支持绑定 Kubernetes Service

    关于 Neting 刚开始的时候是打算使用微软官方的 Yarp 库,实现一个 API 网关.目前写完了查看 Kubernetes Service 信息.创建 Route 和 Cluster 和绑定 K ...

最新文章

  1. Linux 命令(记录)
  2. 2010年11月编程语言排行榜:手机里的代码
  3. 【转】ABP源码分析七:Setting 以及 Mail
  4. 链路追踪php,easyswoole链路追踪
  5. HMC(Hamiltonian Monte Carlo抽样算法详细介绍)
  6. 最全数据指标体系集合!覆盖9个行业4个业务场景,全是干货
  7. 【amp;#9733;】Web精彩实战之amp;lt;智能迷宫amp;gt;
  8. .net mvc 导出excel表格
  9. 程序员的相亲那件小事,指南献给您
  10. 10个高效的摸鱼神器,你错过几个?
  11. Maven导入ojdbc6
  12. python开源怎么盈利_弄清楚Python最火的开源项目,你就掌握了商机
  13. 项目经理PMO必备的工作汇报技巧
  14. Re:PyQt5 从零开始的MVC开发模式规划
  15. java未来发展潜力_Java语言未来是否还有发展前景
  16. Java递归子集算法(树状结构)的逻辑和实例代码实现 @杨章隐
  17. SpringMVC基础入门
  18. STM32单片机蓝牙APP智能急救手表跌倒报警心率报警MAX30102
  19. TRIZ系列-创新原理-16-部分或超额行动原理
  20. 泛微OA使用笔记-测试

热门文章

  1. 【DM8数据库常用命令】
  2. windows下搭建python运行环境
  3. 虚拟机的安装及共享文件夹的创建
  4. python itertools_python - itertools 模块
  5. Vue源码解析-目录设计
  6. 安装VMWare虚拟机之后,发现网络贼卡,打开网页很慢
  7. github直接网页上传时出现 this file is empty
  8. Python 快速排序,代码实现
  9. 81、PON网络分光器基本常识汇总,弱电人要熟知!
  10. HMR(热模块代替)原理和react实践