k8s_day03_05

service 于endpoint 关系

​ k8s 当中,service 是标准的资源类型,作用是为了动态的一组pod 提供一个固定的 访问入口,clusterip,访问入口就可以认为是一组应用的前端负载均衡器。

​ 一个service 如何识别它背后有多少个pod ? 在每个pod 上 给他添加独立的标签,前端的service 将使用标签选择器来挑选中一组pod. 过滤名称空间下的pod ,满足标签选择条件的pod 都会被认为是service 的后端端点(一个服务的ip + port 构成的访问入口就把它称为端点endpoint ).

​ service 不仅能把标签选择器选中的pod 做为后端端点 , 它还能对后端端点做就绪状态检测。如果这个 pod/端点是就是的 ,service 就可以把它加入到 后端可用列表中来 , 否则就把它移除掉。 这个过程并不是service 自己直接做的,而是借助了 另一个 资源 Endpoint 也是标准的资源类型只不过service 会自动管理endpoint

​ 再重复一遍:

​ pod 是数据资源的一个schema , endpoint 也是。 service 创建成功之后能发挥作用是因为 有一个 叫 service controller 的组件,endpoint 同理 它要发挥作用也是靠 Endpoint Controller 。很多资源都有它的专用控制器,以确保它所对应的意义能实现

再重复一遍:

​ 创建一个pod 就是在apiserver 中添加一个数据项 ,一个pod 中包含 运行 容器的意义和价值,这时侯 就必须由控制器调用、或者 触发 apiserver /控制平面的调度器, 调度器会绑定某个节点对应的kubelet 来把这pod 中容器给运行起来 。所以控制器至关重要 ,它们都打包在 contpller manger 当中。

​ service 和 endponit 都有自己的service 确保自己能正常工作。 所以创建一个service , 必须指定的属性就是标签选择器。 而后 service 控制器 就会根据创建标签请求创建同名的ep 资源。 接着endpint 的控制器 就会介入,因为出现一个新的自己管理的资源,endpint 的控制器 会使用 endpoint 标签选择器(继承自service 的) 查找多个符合标签选择器的pod , 并且会检查pod 就绪状态。

​ ep 会把就绪状态的pod 告诉service , service 通通把它门加入后端端点,用clusterIp 来标识它们。所以说service 绑定pod 其实是由endpoint 做的

​ service只复责调度

简单来说 ,service 就是 为 一组具有相同功能的pod对象 ,使用标签过滤成为一组pod 对象。 并且把这一组对象作为能同一接受请求流量的后端进行管理 根据pod对象的就绪状态 决定是否把它加进来

kube-proxy代理模型 3种

​ 在k8s 当中 ,真正负责service 工作的 是叫kube-proxy 组件

kube-proxy , 是service controller 位于 各个节点的agent

kube-proxy 的代理模型:

1、userspace 代理模型 已经弃用

(因为发请求的过程报文会再次进入用户空间)

image-20211206151359957

​ 最早期的kube-proxy 是一个服务进程 , 和nginx一样,所有的调度都是由kube-proxy完成的。

pod 是运行在用户空间,pod 去访问其他节点的pod(或者service) , 它的请求会先到自己节点的内核空间 netfilter 上面来, 第一种方式是把service 实现为一种iptables拦截规则. 把请求拦截下来以后 但是自己不调度,会把拦截住的请求 重定向为同样运行在该节点用户空间 一个成为 kube-proxy 的进程。 kube-proxy 会 根据请求选定 后端调度地址后 再发回内核空间,最终调度给某一个pod。

因为请求报文会在内核于应用空间多次切换 ,所以效率低

2、iptables 模式
image-20211206152132389

pod 发请求进入到内核空间之后,同样会被iptables 规则拦截 ,但是iptables 同时加了 调度规则,这个报文会直接发出去,不用再回kube-proxy

​ 这里的kube-proxy 看起来没有用了? 错,它要监视着 apiserver 中 service 的定义 ,并且把它转化为本地的iptables 规则(userspace 模型也需要)。

因为纯内核级别 就能完成调度 ,所以比效率userspace 模型要好些,但是随着ep增多,会产生大量iptables规则

3、ipvs 模式。

对于ipvs 一个调度 ,只须一套规则。

  1. 定义集群
  2. 向集群添加 后端端点(rs ,real server).

所以区区2步骤ipvs规则就行 ,无论后端pod数量多少个 ,也不过是第二条规则的一个端点

使用kubeadm 部署时 ,会自动检测节点上的ipvs 相关模块是否被加载了,加载了就自动启用,否则就是iptables模式。当然也可以根据配置文件修改

image-20211206161348347

service 是定义在apiserver中的 , service controller 负责将其触发(其实主要是触发ep的)

kube-proxy 会注册监听着apiserver中的 所有service

​ 任何一个serivce的添加 ,都会由每一个节点上的kube-proxy 把它加载到本地节点并且转换为内核中的iptables/ipvs 规则

​ 任何一个一个节点上的iptables/ipvs 规则 通常 只负责本地节点上 pod 做为客户端发出请求时的过滤规则或者调度规则。 因此, client pod1 或者server pod1 去访问server pod2 时, 请求报文先到达本机内核空间,进而本iptables/ipvs 规则捕获 。iptables 规则一般在prerouting 链上,ipvs规则借助于prerouting 链上的iptables一两条(或几条)有限的规则 发送至INPUT 链上, 随后就被ipvs 所调度。

​ 一旦创建了一个service , 为了让service 能接收请求且做为端点能被各种pod 所访问, service 会有一个不变的地址 clusterip( 前提不删除修改) ,从而能作为内部接入内部pod 请求的IP地址,因此把它称为cluserip

kube-proxy如何确保service能正常工作;

service 类型
ClusterIP:

​ 通过集群内部IP地址暴露服务,但该地址仅在集群内部可见、可达,它无法被集群外部的客户端访问;默认类型;

​ 一旦创建了一个service , 为了让service 能接收请求且做为端点能被各种pod 所访问, service 会有一个不变的地址 clusterip( 前提不删除修改) ,从而能作为内部接入内部pod 请求的IP地址,因此把它称为cluserip

NodePort:

​ NodePort是ClusterIP的增强类型,它会于ClusterIP的功能之外,在每个节点上使用一个相同的端口号将外部流量引入到该Service上来。然后service 转发到其他pod 上去

​ 缺点就是 ,有可能 恰巧访问的那一台物理节点宕机了 ,就无法响应,所以需要创建一个外部的负载均衡器,LoadBlancer (external) ,把工作节点都加上去,负载均衡器是外部的,所以也要做高可用。

​ 如果把k8s 部署在公有云上,公有云会有一种叫LBass的服务 ,叫软负载均衡器,可用调用云服务的api,它能自动帮你创建一个外部的 公有云本身提供的均衡器,有一定意义上的高可用性

LoadBalancer:

​ LB是NodePort的增强类型,要借助于底层IaaS云服务上的LBaaS产品来按需管理LoadBalancer。

ExternalName:

借助集群上KubeDNS来实现,服务的名称会被解析为一个CNAME记录,而CNAME名称会被DNS解析为集群外部的服务的IP地址; 这种Service既不会有ClusterIP,也不会有NodePort;

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐