Kubernetes必备知识: Kubernetes Service

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Kubernetes中一个应用服务会有一个或多个实例(Pod),每个实例(Pod)的IP地址由网络插件动态随机分配(Pod重启后IP地址会改变)。为屏蔽这些后端实例的动态变化和对多实例的负载均衡,引入了Service这个资源对象

所属技术领域:

Kubernetes

|名词定义|

Kubernetes中一个应用服务会有一个或多个实例(Pod),每个实例(Pod)的IP地址由网络插件动态随机分配(Pod重启后IP地址会改变)。为屏蔽这些后端实例的动态变化和对多实例的负载均衡,引入了Service这个资源对象,如下所示:
图片.png

根据创建Service的type类型不同,可分成4种模式:

ClusterIP: 默认方式。根据是否生成ClusterIP又可分为普通Service和Headless Service两类:
普通Service:通过为Kubernetes的Service分配一个集群内部可访问的固定虚拟IP(Cluster IP),实现集群内的访问。为最常见的方式。
Headless Service:该服务不会分配Cluster IP,也不通过kube-proxy做反向代理和负载均衡。而是通过DNS提供稳定的网络ID来访问,DNS会将headless service的后端直接解析为podIP列表。主要供StatefulSet使用。
NodePort:除了使用Cluster IP之外,还通过将service的port映射到集群内每个节点的相同一个端口,实现通过nodeIP:nodePort从集群外访问服务。
LoadBalancer:和nodePort类似,不过除了使用一个Cluster IP和nodePort之外,还会向所使用的公有云申请一个负载均衡器(负载均衡器后端映射到各节点的nodePort),实现从集群外通过LB访问服务。
ExternalName:是 Service 的特例。此模式主要面向运行在集群外部的服务,通过它可以将外部服务映射进k8s集群,且具备k8s内服务的一些特征(如具备namespace等属性),来为集群内部提供服务。此模式要求kube-dns的版本为1.7或以上。这种模式和前三种模式(除headless service)最大的不同是重定向依赖的是dns层次,而不是通过kube-proxy。
比如,在service定义中指定externalName的值"my.database.example.com":

此时k8s集群内的DNS服务会给集群内的服务名 ..svc.cluster.local 创建一个CNAME记录,其值为指定的"my.database.example.com"。
当查询k8s集群内的服务my-service.prod.svc.cluster.local时,集群的 DNS 服务将返回映射的CNAME记录"foo.bar.example.com"。

备注:

前3种模式,定义服务的时候通过selector指定服务对应的pods,根据pods的地址创建出endpoints作为服务后端;Endpoints Controller会watch Service以及pod的变化,维护对应的Endpoint信息。kube-proxy根据Service和Endpoint来维护本地的路由规则。当Endpoint发生变化,即Service以及关联的pod发生变化,kube-proxy都会在每个节点上更新iptables,实现一层负载均衡。

而ExternalName模式则不指定selector,相应的也就没有port和endpoints。
ExternalName和ClusterIP中的Headles Service同属于Headless Service的两种情况。Headless Service主要是指不分配Service IP,且不通过kube-proxy做反向代理和负载均衡的服务。
针对以上各发布方式,会涉及一些相应的Port和IP的概念。

|技术特点|

  1. 在 Kubernetes 上部署可扩展的 Web 应用
  2. 分析日志并监控 Kubernetes 应用的运行状况
  3. 持续部署到 Kubernetes
  4. 创建集群

|相关词|

Service
我们可以先来看一下 ServiceController 在 Service 对象变动时发生了什么事情,每当有服务被创建或者销毁时,Informer 都会通知 ServiceController,它会将这些任务投入工作队列中并由其本身启动的 Worker 协程消费:图片.png

不过 ServiceController 其实只处理了负载均衡类型的 Service 对象,它会调用云服务商的 API 接口,不同的云服务商会实现不同的适配器来创建 LoadBalancer 类型的资源。 图片.png
我们以 GCE 为例简单介绍一下 Google Cloud 是如何对实现负载均衡类型的 Service:图片.png
上述代码会先判断是否应该先删除已经存在的负载均衡资源,随后会调用一个内部的方法 ensureExternalLoadBalancer 在 Google Cloud 上创建一个新的资源,这个方法的调用过程比较复杂:

  1. 检查转发规则是否存在并获取它的 IP 地址;
  2. 确定当前 LoadBalancer 使用的 IP 地址;
  3. 处理防火墙的规则的创建和更新;
  4. 创建和删除指定的健康检查;
    想要了解 GCE 是如何对 LoadBalancer 进行支持的可以在 Kubernetes 中的 gce package 中阅读相关的代码,这里面就是 gce 对于云服务商特定资源的实现方式。

iptables
另一种常见的代理模式就是直接使用 iptables 转发当前节点上的全部流量,这种脱离了用户空间在内核空间中实现转发的方式能够极大地提高 proxy 的效率,增加 kube-proxy 的吞吐量。
图片.png

iptables 作为一种代理模式,它同样实现了 OnServiceUpdate、OnEndpointsUpdate 等方法,这两个方法会分别调用相应的变更追踪对象。
sequenceDiagram participant SC as ServiceConfig participant P as Proxier participant SCT as ServiceChangeTracker participant SR as SyncRunner participant I as iptable SC->>+P: OnServiceAdd P->>P: OnServiceUpdate P->>SCT: Update SCT-->>P: Return ServiceMap deactivate P loop Every minSyncPeriod ~ syncPeriod SR->>+P: syncProxyRules P->>I: UpdateChain P->>P: writeLine x N P->>I: RestoreAll deactivate P end
变更追踪对象会根据 Service 或 Endpoint 对象的前后变化改变 ServiceChangeTracker 本身的状态,这些变更会每隔一段时间通过一个 700 行的巨大方法 syncProxyRules 同步,在这里就不介绍这个方法的具体实现了,它的主要功能就是根据 Service 和 Endpoint 对象的变更生成一条一条的 iptables 规则,比较感兴趣的读者,可以点击 proxier.go#L640-1379 查看代码。
当我们使用 iptables 的方式启动节点上的代理时,所有的流量都会先经过 PREROUTING 或者 OUTPUT 链,随后进入 Kubernetes 自定义的链入口 KUBE-SERVICES、单个 Service 对应的链 KUBE-SVC-XXXX 以及每个 Pod 对应的链 KUBE-SEP-XXXX,经过这些链的处理,最终才能够访问当一个服务的真实 IP 地址。
虽然相比于用户空间来说,直接运行在内核态的 iptables 能够增加代理的吞吐量,但是当集群中的节点数量非常多时,iptables 并不能达到生产级别的可用性要求,每次对规则进行匹配时都会遍历 iptables 中的所有 Service 链。
规则的更新也不是增量式的,当集群中的 Service 达到 5,000 个,每增加一条规则都需要耗时 11min,当集群中的 Service 达到 20,000 个时,每增加一条规则都需要消耗 5h 的时间,这也就是告诉我们在大规模集群中使用 iptables 作为代理模式是完全不可用的。

资料来源:

  1. 名词定义:CSDN社区https://blog.csdn.net/liukuan73/article/details/82585732
  2. 技术特点:https://www.ibm.com/cn-zh/cloud/container-service
  3. 相关词:https://draveness.me/kubernetes-service
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
4月前
|
Kubernetes 容器
K8S的Service的LoadBanlance之Metallb解决方案
本文介绍了如何在Kubernetes中使用MetalLB来实现Service的LoadBalancer功能,包括MetalLB的部署、配置、以及通过创建地址池和部署服务来测试MetalLB的过程。
181 1
K8S的Service的LoadBanlance之Metallb解决方案
|
5月前
|
Kubernetes 网络安全 容器
在K8S中,有个服务使用service的nodeport进行暴露,发现访问不到如何排查?
在K8S中,有个服务使用service的nodeport进行暴露,发现访问不到如何排查?
|
5月前
|
Kubernetes 负载均衡 网络协议
在K8S中,Service的类型有哪几种,请说⼀下他们的用途?
在K8S中,Service的类型有哪几种,请说⼀下他们的用途?
|
5月前
|
Kubernetes 监控 API
在k8S中,Metric Service是什么?
在k8S中,Metric Service是什么?
|
5月前
|
Kubernetes 负载均衡 网络协议
在k8S中,Headless Service是什么?
在k8S中,Headless Service是什么?
|
5月前
|
Kubernetes 负载均衡 网络协议
在K8S中,Service的类型有哪些?
在K8S中,Service的类型有哪些?
|
5月前
|
Kubernetes API 容器
在K8S中,Service的Nodeport端口范围?
在K8S中,Service的Nodeport端口范围?
|
5月前
|
Kubernetes 网络协议 网络安全
在K8S中,k8s中service访问有问题,该如何排查?
在K8S中,k8s中service访问有问题,该如何排查?
|
5月前
|
Kubernetes Perl 容器
在k8S中,Service怎么关联Pod的?
在k8S中,Service怎么关联Pod的?
|
5月前
|
Kubernetes 负载均衡 算法
在k8S中,Service分发后端的策略是什么?
在k8S中,Service分发后端的策略是什么?