Kubernetes / 云原生

Kubernetes Service资源

浅时光博客 · 4月5日 · 2021年 37342次已读

一、场景说明

在K8S平台之上,Pod是有生命周期的,所以为了能够给对应的客户端提供一个所谓的固定访问端点,因此我们在客户端与服务端(服务Pod之间)添加了一个固定的中间层,这个中间层为Service,这原文链接:https://www.dqzboy.comService的真正工作还要严重依赖于k8s集群之上部署的一个附件,我们称之为叫kubernetes dns服务;

不同的K8S版本中实现方式不同,K8S新版本中默认使用的是CoreDNS1.11之前的版本默认使用的是kubeDNS

Service的解析是强依赖于dns附件的,因此我们部署完k8s集群之后,必须要去部署一个dns服务;K8S要想能够向客户端提供网络功能,需要依赖于第三方的容器网络CNI协议的网络插件提供的接口接入,任何遵循这种插件标准的第三方网络方案(比如:flannelcalico)

这里我也顺便提一句,如果你是使用的是calico网络插件,那么你可以借助于calico网络插件固定Pod IP

  • 在K8S环境当中存在有三类IP地址:
    • 1、节点网络:配置在节点接口之上;
    • 2、Pod网络:配置在Pod资源之上;
      • 以上两种网络是实实在在配置在某个设备上的,可能是纯硬件的也可以能是软件模拟的
    • 3、集群地址:service地址,虚拟地址,没有实实在在配置在某个接口上,仅存在于service的规则当中

二、Service是什么

在每个工作节点之上工作有一个组件kube-proxykube-proxy组件将始终监视着API Service当中有关service资源的变动信息,通过k8s中的一个固有的一种请求方式watch实现的;一旦有service资源中的内容发生变化,kube-proxy都要将它转换为当前节点之上能够实现将用户请求调度到后端对应pod资源上的规则,这个规则有可能是iptables或者ipvs,取决于service的实现方式。

三、Service实现方式

1、三种工作模型

注意:以下3中模型都是四层代理,四层调度(代理)的缺陷,由于工作在TCP/IP协议栈(OSI七层模型的第四层),因此用户如果访问的是HTTP/HTTPS的请求则无法访问到后端的程序;

内部使用HTTP,而互联网访问则使用HTTPS,但是Service调度时,ClusterIP:ServicePort无论是以下哪种模型,它们都是四层调度,从而无法实现卸载会话;如果想要运行在K8S中的应用基于HTTPS协议来向外提供服务,我们必须得在后端每个Pod上配置HTTPS,这样客户端与应用程序才能建立HTTPS会话;

而在K8S集群中则每个Pod后端程序不配置SSL,而是在这些Pod前面加一个特殊的调度器(Pod),而这个是运行在用户空间的应用程序,比如Nginx或HAProxy,这个Pod配置HTTPS,所以用户访问则先到这个Pod由此Pod反向代理到明文访问(HTTP)后端程序

(1)User Space用户空间

k8s 1.1之前用的是userspace
  • 用户空间:来自外部用户的请求到达对应节点之上,这个请求一定先到达当前节点内核空间的iptables规则,这个iptables规则就是service的规则。
  • 工作方式:请求到达service以后,由service先把它转为本地监听在某个套接字之上的用户空间kube-proxy,由kube-proxy进行处理,处理完之后再转给service ip,最后代理至这个service相关联的各个Pod,实现调度。

(2)iptables

  • 客户端Pod IP请求时,直接请求service的IP,这个请求报文被本地内核空间上的service规则所截取,进而直接调度给相关联的Pod
  • k8s 1.10之前版本;直接工作到内核空间,由iptables规则直接负责调度

(3)ipvs

  • Client请求到达内核空间之后,直接由ipvs规则来调度
  • k8s 1.11之后默认为ipvs;客户端请求到达内核空间以后,直接由ipvs进行调度
  • 注意:如果K8S集群中未安装ipvs模块则默认降级到iptables
文章来源(Source):https://www.dqzboy.com

2、四种类型

Cluster IP

这种类型所定义的服务,只能在集群内部可达,可以被各Pod和节点本身所访问,但是无法接入集群边界外部的流量

  • 备注:NO Cluster IP
    • ClusterIP是引入流量接入的重要接入点,是整个服务的头部;ClusterIP是Service中的主流要件,但是我们也可以把它移除,如果一个Service没有了ClusterIP,那么则这个服务为Headless Service(无头服务)
  • 无头的主要作用:把服务名称(ServiceName)直接解析到后端Pod IP;原来解析的是ServiceIP(ClusterIP)

NodePort

用户请求先到达NodeIP:NodePort,然后再到ClusterIP:ServicePort,再到PodIP:ContainerPort

  • 注意:NodePort是以ClusterIP为前提的,如果没有ClusterIP则NodePort无法工作,因为NodeIP:NodePort之后还要到达ClusterIP:ServicePort;NodePort是在ClusterIP之上新增强的功能,而不是完全一个新的功能

LoadBalancer

必须工作在一个支持公有云的LbaaS原文链接:https://www.dqzboy.com的环境中

  • 注意:LoadBalancer是在NodePort之上增强的功能
说明:所以以上三种类型,后一个都是前一个的增强版

ExternelName

将集群外部的服务映射到集群内部,而这个是一个FQDN名称(这个记录是一个CNAME记录,而这个CNAME记录指向真正的外部主机地址)

当Pod需要访问集群外部服务时,我们可以把集群外部服务映射到集群内部来,而就需要使用ExternelName来实现,而ExternelName就是一个主机名(FQDN)或者是一个域名;

FQDN:

第一个是在集群内部取一个由集群内部DNS(如:CoreDNS)解析的服务名称,而第二个则是由互联网DNS解析的服务器IP地址的FQDN名称,然后映射到集群内部解析的服务名称。

3、Endpoints

endpoint也是一个k8s中的标准对象

  • service到pod有一个中间层,service不会直接到pod,service而是先到endpoints,然后再由endpoint关联至后端的pod程序。

三、资源记录

  • 资源记录格式:SVC_NAME(服务名).NS_NAME(名称空间).DOMAIN.LTD(域名后缀)
  • 集群默认后缀:svc.cluster.local
  • 例子:
    • yp-v7-client.yp-k8s-dev.svc.cluster.local
  • 备注:
    • yp-v7-client:SVC服务名称
    • yp-k8s-dev:该服务所属的名称空间
    • svc.cluster.local:集群默认后缀
  • 注意:如果集群访问的资源类型是带有端口的,则需要添加端口号:如9090端口

本文作者:浅时光博客
原文链接:https://www.dqzboy.com/6409.html
版权声明:知识共享署名-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)协议进行许可,转载时请以>超链接形式标明文章原始出处和作者信息
免责声明:本站提供的内容仅限于个人学习和研究使用;禁止将内容用于商业或非法用途。下载后请在24小时内彻底删除,否则后果由用户承担。访问和下载本站内容即表示您已同意上述条款 。

0 条回应

必须 注册 为本站用户, 登录 后才可以发表评论!