Kubernetes基础(五)-Service

1 引言

Service 主要用于提供网络服务,通过Servicel的定义,能够 为客户端应用提供稳定的访问地址(域名或IP地址)和负载均衡功能,以及屏蔽后端Endpoint的变化,是Kubernetes实现微服务的核心资源。

本文详细讲解下Service的相关概念及原理。

2 Service介绍

2.1 Service的概念

下面演示在没有Service之前,是如何访问一个多副本的应用容器组提供的服务。

以Tomcat容器为例,其Deployment资源文件定义如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: webapp
spec:replicas: 2selector:matchLabels:app: webapptemplate:metadata:labels:app: webappspec:containers:- name: webappimage: kubeguide/tomcat-app:v1 ports:- containerPort: 8080

创建完成后,查看每个pod的ip地址:

客户端应用可以直接通过这两个Pod的IP地址和端口号8080访问Web服务,例如:curl 10.0.95.22:8080

但是,提供服务的容器应用通常是分布式的,通过多个Pod副本共同提供服务(还需要考虑扩缩容的问题),要实现动态感知服务后端实例的变化,会大大增加客户端系统实现的复杂度,为了解决这个问题,Kubernetes引入 Service资源类型 。

2.2 概念

Service实现的是微服务架构中的几个核心功能:全自动的服务注册、服务发现、 服务负载均衡等。

2.2.1 创建Service的方式

2.2.1.1 使用kubectl expose命令创建

命令如下:

$ kubectl expose deployment webapp 
service/webapp exposed

查看新创建的Service,可以看到系统为它分配了一个虚拟​​IP​​​地址(​​ClusterIP​​ 地址),Service的端口号则从Pod中的containerPort复制而来:

通过curl 169.169.140.242:8080 也是可以访问的。访问时,会被自动负载分发到了后端两个Pod之一:10.0.95.22:8080或10.0.95.23:8080。 

2.2.1.2 资源文件创建
除了使用命令,还可以使用yaml资源文件的方式来创建:
apiVersion: v1
kind: Service
metadata:name: webapp
spec:ports:- protocol: TCPport: 8080targetPort: 8080selector:app: webapp

Service定义中的关键字段是ports和selector:

  • ports:定义部分指定了Service本身的端口号为8080;
  • targetPort:指定后端Pod的容器端口号;
  • selector:定义部分设置的是后端Pod所拥有的 ​​label:app=webapp​​。

使用​​kubectl create​​​命令创建后,能看到和使用​​kubectl expose​​命令创建Service的效果一样。

2.2.2 Endpoint

一个Service对应的 “后端” 由Pod的IP和容器端口号组成,这在k8s系统中称为Endpoint。

可以通过​​kubectl descirbe svc ​​命令查看Endpoint列表,如:

Kubernetes自动创建了与Service关联的Endpoint资源对象,这可以通过查询Endpoint对象讲行查看:

3 负载均衡机制

当一个 Service 对象在 Kubernetes 集群中被定义出来时,集群内的客户端应用就可以通过服务IP访问到具体的Pod容器提供的服务了。

从服务IP到后端Pod的负载均衡机制,则是由每个Node上的kube-proxy负责实现的。通过Service的负载均衡机制,Kubernetes实现了一种分布式应用的统一入口,免去了客户端应用获知后端服务实例列表和变化的复杂度。。

3.1 kube-proxy的代理模式

kube-proxy代理模式参考:Kubernetes基础(四)-Kube-proxy_kubectl proxy-CSDN博客

3.2 会话保持模式

Service支持通过设置sessionAffinity实现基于客户端IP的会话保持机制,即:首次将某个客户端来源IP发起的请求转发到后端的某个Pod上,之后从相同的客户端 IP发起的请求都将被转发到相同的后端Pod上。

配置参数为 ​​service.spec.sessionAffinity​​​,也可以设置会话保持的最长时间(​​service.spec.sessionAffinityConfig.clientIP.timeoutSeconds​​),例如下面的服务将会话保持时间设置为10800s(3h):

apiVersion: v1
kind: Service
metadata:name: webapp
spec:sessionAffinity: ClientIP sessionAffinityConfig:clientIP:timeoutSecondes: 10080ports:- protocol: TCPport: 8080targetPort: 8080selector:app: webapp

4 Service的多端口设置

一个容器应用可以提供多个端口的服务,在Service的定义中也可以相应地设置多个端口号。

在下面的例子中,Service设置了两个端口号来分别提供不同的服务,如web服务和management服务(下面为每个端口号都进行了命名,以便区分):

apiversion: v1
kind: Service
metadata:name: webapp
spec:
ports:
- port: 8080targetPort: 8080name: web
- port: 8005targetPort: 8005 name: management
selector:
app: webapp

另一个例子是同一个端口号使用的协议不同,如TCP和UDP,也需要设置为多个端口号来提供不同的服务:

apiVersion: v1
kind: Service
metadata:name: kube-dnsnamespace: kube-system labels:k8s-app: kube-dnskubernetes.io/cluster-service: "true" kubernetes.io/name: "KubeDNS"
spec:selector:k8s-app: kube-dnsclusterIP: 169.169.0.100ports:- name: dns port: 53protocol: UDP- name: dns-tcpport: 53protocol: TCP

5 将外部服务定义为Service

普通的Service通过Label Selector对后端Endpoint列表进行了一次抽象,如果后端的Endpoint不是由Pod副本集提供的,则Service还可以抽象定义任意其他服务,将一个Kubernetes集群外部的已知服务定义为Kubernetes内的一个Service, 供集群内的其他应用访问。

5.1 场景

常见的应用场景包括:

  • 已部署的一个集群外服务:例如数据库服务、缓存服务等;
  • 其他Kubernetes集群的某个服务;
  • 迁移过程中对某个服务进行Kubernetes内的服务名访问机制的验证。

Service指向外部服务如下图所示:

5.2 定义

对于这种应用场景,用户在创建​​Service​​资源对象时不设置​​Label Selector​​(后端​​Pod​​也不存在),同时再定义一个与​​Service​​关联的​​Endpoint​​资源对象,在​​Endpoint​​中设置外部服务的​​IP​​地址和端口号,例如:

apiVersion: v1
kind: Service
metadata:name: my-service
spec:ports:- protocol: TCPport: 80targetPort: 80-----------
apiversion: v1
kind: Endpoints
metadata:name: my-service
subsets:
- addresses:- IP: 1.2.3.4ports:- port: 80

6 Service类型

Kubernetes为Service创建的ClusterIP地址是对后端Pod列表的一层抽象,对于集群外部来说并没有意义,但有许多Service是需要对集群外部提供服务的,Kubernetes提供了多种机制将Service暴露出去,供集群外部的客户端访问。

这可以通过Service资源对象的类型字段“type”进行设置。

Kubernetes 服务有四种类型——ClusterIP、NodePort、LoadBalancer 和 ExternalName。 服务spec中的 type 属性决定了服务如何暴露给网络。

6.1 ClusterIP(集群IP)

  • ClusterIP 是默认和最常见的服务类型。
  • Kubernetes 会为 ClusterIP 服务分配一个集群内部 IP 地址。 这使得服务只能在集群内访问。
  • 不能从集群外部向服务(pods)发出请求。
  • 可以选择在服务定义文件中设置集群 IP。

6.1.1 使用场景

集群内的服务间通信。 例如应用程序的前端(front-end)和后端(back-end)组件之间的通信。

举例

apiVersion: v1
kind: Service
metadata:name: my-backend-service
spec:type: ClusterIP # Optional field (default)clusterIP: 10.10.0.1 # within service cluster ip rangeports:- name: httpprotocol: TCPport: 80targetPort: 8080

6.2 NodePort(节点端口)

  • NodePort 服务是 ClusterIP 服务的扩展。 NodePort服务路由到的 ClusterIP 服务会自动创建。
  • 它通过在 ClusterIP 之上添加一个集群范围的端口来公开集群外部的服务。
  • NodePort 在静态端口(NodePort)上公开每个节点 IP 上的服务。每个节点将该端口代理到后端服务中。因此,外部流量可以访问每个节点上的固定端口。这意味着对该端口上的集群的任何请求都会转发到该服务。
  • 用户可以通过请求 <NodeIP>:<NodePort> 从集群外部联系 NodePort 服务。
  • 节点端口必须在 30000-32767 范围内。手动为服务分配端口是可选的。如果未定义,Kubernetes 会自动分配一个。
  • 如果用户要明确选择节点端口,请确保该端口尚未被其他服务使用。

6.2.1 使用场景

  • 当用户想要启用与后端服务的外部连接时。
  • 使用 NodePort 可以让用户自由地设置自己的负载平衡解决方案,配置 Kubernetes 不完全支持的环境,甚至直接公开一个或多个节点的 IP。
  • 最好在节点上方放置负载均衡器以避免节点故障。

举例

apiVersion: v1
kind: Service
metadata:name: my-frontend-service
spec:type: NodePortselector:app: webports:- name: httpprotocol: TCPport: 80targetPort: 8080nodePort: 30000 # 30000-32767, Optional field

6.3 LoadBalancer(负载均衡器)

  • LoadBalancer 服务是 NodePort 服务的扩展。 外部负载均衡器路由到的 NodePort 和 ClusterIP 服务是自动创建的。
  • 它将 NodePort 与基于云的负载均衡器集成在一起。
  • 它使用云厂商的负载均衡器在外部公开服务。
  • 每个云厂商(AWS、Azure、GCP 、阿里云、腾讯云等)都有自己的原生负载均衡器实现。 云厂商将创建一个负载均衡器,然后它会自动将请求路由到您的 Kubernetes 服务。
  • 来自外部负载均衡器的流量被定向到后端 Pod。 云厂商决定如何进行负载平衡。
  • 负载均衡器的实际创建是异步发生的。
  • 每次要向外界公开服务时,都必须创建一个新的 LoadBalancer 并获取 IP 地址。

6.3.1 使用场景

当用户使用云厂商来托管Kubernetes 集群时。

举例

apiVersion: v1
kind: Service
metadata:name: my-frontend-service
spec:type: LoadBalancerclusterIP: 10.0.171.123loadBalancerIP: 123.123.123.123selector:app: webports:- name: httpprotocol: TCPport: 80targetPort: 8080

6.4 ExternalName(外部名称)

  • ExternalName 类型的服务将 Service 映射到 DNS 名称,而不是典型的选择器,例如 my-service。
  • 用户可以使用 `spec.externalName` 参数指定这些服务。
  • 它通过返回带有其值的 CNAME 记录,将服务映射到 externalName 字段(例如 foo.bar.example.com)的内容。
  • 没有建立任何类型的代理。

6.4.1 使用场景

  • 这通常用于在 Kubernetes 内创建服务来表示外部数据存储,例如在 Kubernetes 外部运行的数据库。
  • 当来自一个命名空间的 Pod 与另一个命名空间中的服务通信时,用户可以使用该 ExternalName 服务(作为本地服务)。

举例

apiVersion: v1
kind: Service
metadata:name: my-service
spec:type: ExternalNameexternalName: my.database.example.com

7 将Service暴露给外部集群

Kubernetes为Service创建的ClusterIP地址是对后端Pod列表的一层抽象,对于集群外部来说并没有意义,但有许多Service是需要对集群外部提供服务的,Kubernetes提供了多种机制将Service暴露出去,供集群外部的客户端访问。 

外部访问方式参考:Kubernetes基础(三)-Service外部网络访问方式-CSDN博客

8 Service支持的网络协议

目前Service支持的网络协议如下.

协议描述
TCPService的默认网络协议,可用于所有类型的Service。
UDP可用于大多数类型的Service,LoadBalancer类型取决于云服务商对UDP的支持。
HTTP取决于云服务商是否支持HTTP和实现机制。
PROXY取决于云服务商是否支持HTTP和实现机制。
SCTP从Kubernetes1.12版本引入,到1.19版本时达到Beta阶段,默认启用,如需关闭该特性,则需要设置kube-apiserver的启动参数–feature- gates=-SCTPSupport=-false进行关闭。

Kubernetes从1.17版本开始,可以为Service和Endpoint资源对象设置一个新的段"AppProtocol",用于标识后端服务在某个端口号上提供的应用层协议类型,例如HTTP、HTTPS、SSL、DNS等。

要使用AppProtocol,需要设置kube-apiserver的启动参数​​--feature-gates=ServiceAppProtocol=true​​进行开启,然后在Service或Endpoint的定义中设置AppProtocol字段指定应用层协议的类型,例如: 

apiVersion: v1
kind: Service
metadata: name: webapp 
spec:ports:- port: 8080targetPort: 8080AppProtocol: HTTPselector:app: webapp

8 Kubernetes的服务发现机制

服务发现机制指客户端应用在一个Kubernetes集群中如何获知后端服务的访问地址,一共有两种方式。

8.1 环境变量方式

在一个Pod运行起来的时候,系统会自动为其容器运行环境注入所有集群中有效Service的信息。

Service的相关信息包括服务IP、服务端口号、各端口号相关的协议等,通过​{SVCNAME_SERVICE_HOST}​​​和​​{SVCNAME_SERVICE_PORT}​​格式进行设置。

其中SVCNAME的命名规则为:将Service的name字符串转换为全大写字母,将中横线“”替换为下画线 “_”,以webapp服务为例:

apiVersion: v1
kind: Service
metadata:name: webapp
spec: ports:- protocol: TCPport: 8080targetPort: 8080selector:app: webapp

在一个新创建的Pod(客户端应用)中,可以看到系统自动设置的环境变量如下:

WEBAPP_SERVICE_HOST=169.169.81.175
WEBAPP_SERVICE_PORT=8080
WEBAPP_P0RT=tcp://169.169.81.175:8080
WEBAPP_P0RT_8080_TCP=tcp://169.169.81.175:8080
WEBAPP_PORT_8080_TCP_PROTO=tcp
WEBAPP_PORT_8080_TCP_PORT=8080
WEBAPP_PORT_8080_TCP_ADDR=169.169.81.175

然后客户端应用就能够根据​​Service​​相关环境变量的命名规则,从环境变量中获取需要访问的目标服务的地址了,例如:

curl http://{WEBAPP_SERVICE_HOST}:${WEBAPP_SERVICE_HOST}

8.2 DNS方式

Service在Kubernetes系统中遵循DNS命名规范,Service的DNS域名表示方法 为​​<servicename>.<namespace>.svc.<clusterdomain>​​,其中:

  • servicename:为服务的名称;
  • namespace:为其所在namespace的名称;
  • clusterdomain:为Kubernetes集群设置的域名后缀(例如cluster.local),服务名称的命名规则遵循RFC 1123规范的要求。

另外,Service定义中的端口号如果设置了名称(name),则该端口号也会拥有一个DNS域名,在DNS服务器中以SRV记录的格式保存:​​​_<portname>._<protocol>.<servicename>.<namespace>.svc. <clusterdomain>​​,其值为端口号的数值。

当​​Service​​​以​​DNS​​​域名形式进行访问时,就需要在​​Kubernetes​​​集群中存在一个​​DNS​​​服务器来完成域名到​​ClusterIP​​​地址的解析工作了,经过多年的发展,目前由CoreDNS作为Kubernetes集群的默认DNS服务器提供域名解析服务。

以​​webapp​​服务为例,将其端口号命名为“​​http​​”:

apiversion: v1
kind: Service
metadata:name: webapp
spec:ports:- protocol: TCPport: 8080targetPort: 8080name: httpselector:app: webapp

解析名为 “http” 端口的​​DNS SRV​​记录“​​_http._tcp.webapp.default.svc.cluster.local'​​​”,可以查询到其端口号的值为​​8080​​。

9 Headless Service的概念和应用 

在某些应用场景中,客户端应用不需要通过Kubernetes内置Service实现的负载均衡功能,或者需要自行完成对服务后端各实例的服务发现机制,或者需要自行实现负载均衡功能,此时可以通过创建一种特殊的名为 “Headless‘”的服务来实现。headless介绍参考: Kubernetes基础(二)-Headless Service_alden_ygq的博客-CSDN博客​​​​​​

10 端点分片和服务拓扑

Service的后端是一组Endpoint列表,为客户端应用提供了极大的便利。但随着集群规模的扩大及Service数量的增加,特别是Service后端Endpoint数量的增加,kube-proxy需要维护的负载分发规则(例如iptables规则侧或 ipvs规则)的数量也会急剧增加,导致后续对Service后端Endpoint的添加、删除 等更新操作的成本急剧上升。

假设在​​Kubernetes​​​集群中有10000个​​Endpoint​​​运行在大约5000个​​Node​​​上,则对单个​​Pod​​​的更新将需要总计约​​5GB​​​的数据传输,这不仅对集群内的网络带宽浪费巨大,而且对​​Master​​​的冲击非常大,会影响​​Kubernetes​​​集群的整体性能,在​​Deployment​​不断进行滚动升级操作的情况下尤为突出。这种情况下K8s设计了一种端点分片(​​Endpoint Slices​​)机制来解决。

EndpointSlice通过对Endpoint进行分片管理来实现降低Master和各Node之间的网络传输数据量及提高整体性能的目标。对于Deployment的滚动升级,可以实现仅更新部分Node上的Endpoint信息,Master与Node之间的数据传输量可以减少100倍左右,能够大大提高管理效率。

​​Endpoint Slices​​要实现的第2个目标是为基于Node拓扑的服务路由提供支持,这需要与服务拓扑(Service Topology)机制共同实现。

10.1 端点分片

kubernetes从1.19版本开始,EndpointSplice机制以及​​EndpointSliceProxying​​是默认开启的:

  • 通过设置​​kube-apiserver​​​和​​kube-proxy​​​服务的启动参数​​--feature-gates=“EndpointSlice=true“​​​进行启用。kube-proxy默认仍然使用Endpoint对象,为了提高性能,可以设置 kube-proxy启动参数​​--feature-gates-=“EndpointSliceProxying=true“​​让kube-proxy 使用EndpointSlice,这样可以减少kube-proxy与master之间的网络通信并提高性能。

以一个3副本的webapp服务为例,Pod列表如下:

服务和Endpoint的信息如下:

查看EndpointSlice,可以看到系统自动创建了一个名称前缀为“​​webapp-​​”的EndpointSlice:

查看其详情信息,可以看到3个Endpoint的IP地址和端口信息,同时为Endpoint设置了Topology相关信息:

 10.1.1 参数

默认情况下,在由EndpointSlice控制器创建的EndpointSlice中最多包含100个Endpoint,如需修改,则可以通过kube-controller-manager服务的启动参数​​-- max-endpoints-per-slice​​设置,但上限不能超过1000。

EndpointSlice的关键信息如下:

配置项描述
关联的服务名称将EndpointSlice与Service的关联信息设置为一个标签​​kubernetes.io/service-name=webapp​​,该标签标明了服务名称
地址类型AddressType

包括以下3种取值类型:

  • IPv4:IPv4格式的IP地址
  • IPv6:Pv6格式的IP地址
  • FQDN:全限定域名.
每个Endpoint的信息

在Endpoints列表中列出的每个Endpoint的信息:

  • Addresses:Endpoint的IP地址;
  • Conditions:Endpoint状态信息,作为EndpointSlice的查询条件;
  • Hostname:在Endpoint中设置的主机名nostname;
  • TargetRef:Endpoint对应的Pod名称;
  • Topology:拓扑信息,为基于拓扑感知的服务路由提供数据。

目前EndpointSlice控制器自动设置的拓扑信息如下:

  • -- kubernetes.io/hostname:Endpoint所在Node的名称;
  • -- topology.kubernetes.io/zone:Endpoint所在的Zone信息,使用Node标签topology.kubernetes.io/zone的值,例如上例中的Node拥有 topology.kubernetes.io/zone:north"标签。
  • -- topology.kubernetes.io/region:Endpoint所在的Region信息,使用Node标签topology.kubernetes.io/region的值。

在大规模集群中,管理员应对不同地域或不同区域的Node设置相关的 topology标签,用于为Node设置拓扑信息.

EndpointSlice的管理控制器通过​​endpointslice.kubernetes.io/managed-by​​​标签进行设置,用于存在多个管理控制器的应用场景中,例如某个​​Service Mesh​​​管理工具也可以对​​EndpointSlice​​​进行管理。为了支持多个管理工具对​​EndpointSlice​​​同时进行管理并且互不干扰,可以通过​​endpointslice.kubernetes.io/managed--by​​​标签设置管理控制器的名称,Kubernetes内置的EndpointSlice控制器自动设置该标签的值为​​endpointslice-controller.k8s.io​​,其他管理控制器应设置唯一名称用于标识.

10.1.2 复制功能

EndpointSlice复制(Mirroring)功能:应用程序有时可能会创建自定义的Endpoint资源,为了避免应用程序在创建Endpoint资源时再去创建EndpointSlice资源,Kubernetes控制平面会 自动完成 将Endpoint资源复制为EndpointSlice资源的操作。

以下几种情况下,不会执行自动复制操作:

  • Endpoint资源设置了Label:endpointslice.kubernetes.io/skip-mirror=true;
  • Endpoint资源设置了Annotation:control-plane.alpha.kubernetes.io/leader;
  • Endpoint资源对应的Service资源不存在;
  • Endpoint:资源对应的Service资源设置了非空的Selector;

一个Endpoint资源同时存在IPv4和IPv6地址类型时,会被复制为多个EndpointSlice资源,每种地址类型最多会被复制为1000个EndpointSlice资源。

10.1.3 数据分布管理机制

如上例所示,可以看到每个EndpointSlice资源都包含一组作用于全部Endpoint的端口号(Ports)。如果Service定义中的端口号使用了字符串名称,则对于相同name的端口号,目标Pod 的targetPort可能是不同的,结果是EndpointSlice资源将会不同。这与Endpoint 资源设置子集(subset)的逻辑是相同的。

Kubernetes控制平面对于EndpointSlice中数据的管理机制是尽可能填满,但不会在多个EndpointSlice数据不均衡衡的情况下主动执行重新平衡(rebalance)操作,其背后的逻辑也很简单,步骤如下:

  1. 遍历当前所有EndpointSlice资源,删除其中不再需要的Endpoint,更新已更改的匹配Endpoint;
  2. 遍历第1步中已更新的EndpointSlice资源,将需要添加的新Endpoint填充进去;
  3. 如果还有新的待添加Endpoint,则尝试将其放入之前未更新的EndpointSlice中,或者尝试创建新的EndpointSlicez并添加。

重要的是,第3步优先考虑创建新的EndpointSlice而不是更新原EndpointSlice。例如,如果要添加l0个新的Endpoint,则当前有两个EndpointSlice各有5个剩余空间可用于填充,系统也会创建一个新的EndpointSlice用来填充这10个新Endpoint。换句话说,单个EndpointSlice的创建优于对多个EndpointSlice的更新。

以上主要是由于在每个节点上运行的kube-proxy都会持续监控EndpointSlice的变化,对EndpointSlice每次更新成本都很高,因为每次更新都需要​​Master​​​将更新数据发送到每个​​kube-proxy​​。

上述管理机制旨在限制需要发送到每个节点的更新数据量,即使可能导致最终有许多EndpointSlice资源未能填满。实际上,这种不太理想的数据分布情况应该是罕见的。

Master的EndpointSlice控制器处理的大多数更新所带来的数据量都足够小,使得对已存在 (仍有空余空间)EndpointSlice的数据填充都没有问题,如果实在无法填充,则无论如何都需要创建新的EndpointSlice资源。

此外,对Deployment执行滚动升级操作时,由于后端Pod列表和相关Endpoint列表全部会发生变化,所以也会很自然地对EndpointSlice资源的内容全部进行更新。

10.2 服务拓扑

在默认情况下,发送到一个Service的流量会被均匀转发到每个后端Endpoint,但无法根据更复杂的拓扑信息设置复杂的路由策略。服务拓扑机制的引入就是为了实现基于Node拓扑的服务路由,允许Service创建者根据来源Node和目标Node的标签来定义流量路由策略。

通过对来源Node和目标Node标签的匹配,用户可以根据业务需求对Node进行分组,设置有意义的指标值来标识 “较近” 或者 “较远” 的属性:

例如对于公有云环境来说,通常有区域(Zone或Region)的划分,云平台倾向于把服务流量限制在同一个区域内,这通常是因为跨区域网络流量会收取额外的费用。另一个例子是把流量路由到由DaemonSet管理的当前Node的Pod 上。又如希望把流量保持在相同机架内的Node上,以获得更低的网络延时。

10.2.1 配置

服务拓扑机制需要通过设置​​kube-apiserver​​​和​​kube-proxy​​​服务的启动参数​​--feature-gates-=“ServiceTopology=true,EndpointSlice=true“​​​进行启用(需要同时启用​​EndpointSlice​​​功能),然后就可以在​​Service​​​资源对象上通过定义 ​​topologyKeys​​字段来控制到Service的流量路由了。

对于需要使用服务拓扑机制的集群,管理员需要为Node设置相应的拓扑标签,包括​​kubernetes.io/hostname​​​、​​topology.kubernetes.io/zone​​​ 和​​topology.kubernetes.io/region​​。

然后为Service设置topologyKeys的值,就可以实现如下流量路由策略:

  • 配置为[“kubernetes.io/hostname“]:流量只会被路由到相同Node的
  • Endpoint上,如果Node的Endpoint不存在,则将请求丢弃。
  • 配置为[“kubernetes.io/hostname" "topology.kubernetes.io/zone“ “topology.kubernetes.io/region“]:流量优先被路由到相同Node的Endpoint上, 如果Node没有Endpoint,流量则被路由到同zone的Endpoint,如果在zone中没有Endpoint,流量则被路由到通region中的Endpoint上。
  • 配置为[“topology.kubernetes.io/zone“,“​​*​​​“]:流量优先被路由到同zone 的Endpoint上,如果在zone中没有可用的Endpoint,流量则被路由到任意可用的
  • Endpoint上。

目前使用服务拓扑有以下几个约束条件:

  • 服务拓扑和externalTrafficPolicy=Local是不兼容的,所以一个Service不能同时使用这两种特性。在同一个Kubernetes集群中,启用服务拓扑的Service和设置externalTrafficPolicy=Local特性的Service:是可以同时存在的。
  • topologyKeys目前可以设置的标签只有3个:kubernetes.io/hostname、topology.kubernetes.io/zone和topology.kubernetes.io/region,未来会增加更多 的标签。
  • topologyKeys必须是有效的标签格式,并且最多定义16个。
  • 如需使用通配符“*”,则它必须是最后一个值。

10.2.2 案例

下面通过Service的YAML文件对几种常见的服务拓扑应用实例进行说明。

1)只将流量路由到相同Node的Endpoint上,如果Node没有可用的Endpoint,则将请求丢弃:

apiVersion: v1
kind: Service
metadata:name: webapp
spec:selector:app: webappports:- port: 8080topologykeys:- "kubernetes.io/hostname"

2)优先将流量路由到相同Node的Endpoint上,如果Node没有可用的Endpoint,则将请求路由到任意可用的Endpoint:

apiVersion: v1
kind: Service
metadata:name: webapp
spec:selector:app: webappports:- port:8080topologyKeys:- "kubernetes.io/hostname"- "*"

3)只将流量路由到相同zone或同region的Endpoint上,如果没有可用的Endpoint,则将请求丢弃:

apiVersion: v1
kind: Service
metadata:name: webapp
spec:selector:app: webappports:- port:8080topologyKeys:- "topology.kubernetes.io/zone" - "topology.kubernetes.io/region"

4)按同Node、同zone、同region的优先级顺序路由流量,如果Node、 zone、region都没有可用的Endpoint,则将请求路由到集群内任意可用的Endpoint.上:

apiVersion: v1
kind: Service
metadata: name: webapp
spec:selector:app: webappports:- port:8080topologyKeys:- "kubernetes.io/hostname"- "topology.kubernetes.io/zone" - "topology.kubernetes.io/region"- "*"

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144684.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud Netflix 教程和源码

本教程目标 想要系统地学习 Spring Cloud Netflix&#xff0c; 把自己的学习过程记录下来。 状态 持续更新中 微服务架构 微服务架构是一种将应用程序拆分为一组独立的、可独立部署的服务的架构模式。每个服务都运行在自己的进程中&#xff0c;可以独立地进行开发、测试和…

记录一次SQL注入src挖掘过程

记录一次小白SQL注入src挖掘过程&#xff0c;其中碰到了很多问题&#xff0c;报错和解决 先是使用谷歌语法找到一个可以注入的网站 谷歌语法&#xff1a; 公司inurl:php?id 然后该公司的URL为 URL:XXXXXXXXXX/xxx.php?id1 输入测试有无注入&#xff0c;有没有waf 发现…

LinkedList与链表

目录 一、Arraylist的缺陷 二、链表 2.1 链表的概念和结构 2.2 链表的实现 三、链表面试题 3.1 删除链表中所有值为val的节点 3.2 反转一个单链表 3.3 链表的中间节点 3.4 将有序链表合并 3.5 输出倒数第k个节点 3.6 链表分割 3.7 链表的回文结构 3.8 找两个链表的公共节…

23.1 Bootstrap 表格

1. 表格 1.1 基础表格 Bootstrap5 通过在<table>元素中添加.table类来设置基础表格的样式.<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wi…

零基础教程:Yolov5模型改进-添加13种注意力机制

1.准备工作 先给出13种注意力机制的下载地址&#xff1a; https://github.com/z1069614715/objectdetection_script 2.加入注意力机制 1.以添加SimAM注意力机制为例&#xff08;不需要接收通道数的注意力机制&#xff09; 1.在models文件下新建py文件&#xff0c;取名叫Sim…

路由器配置单区域(多区域)OSPF

目录 实验原理 案例 路由器配置单区域OSPF基本功能 单区域总结 路由器配置多区域OSPF基本功能 多区域特点 实验原理 OSPF&#xff08;Open Shortest Path First&#xff0c;开放最短路径优先&#xff09;是互联网的标准协议&#xff0c;是为克服RIP的缺点而开发的。目前针…

win10搭建Selenium环境+java+IDEA(2)

接着上一个搭建环境开始叙述&#xff1a;win10系统x64安装java环境以及搭建自动化测试环境_荟K的博客-CSDN博客 上一步结尾的浏览器驱动&#xff0c;本人后面改到了谷歌浏览器.exe文件夹下&#xff1a; 这里需要注意&#xff0c;这个新路径要加载到系统环境变量中。 上一步下…

排序学习总结

取每个对象的内接矩形框&#xff0c;然后再排序&#xff0c;根据排序的结果确定原对象顺序。 inner_rectangle1(RegionAffineTrans1, Row1, Column1, Row2, Column2) gen_rectangle1(Rect,Row1, Column1, Row2, Column2) sort_region(Rect,RectSort,character,true, row)count…

小波变换学习笔记【1】

【声明】本博客为学习B站视频小波分解与重构所做笔记&#xff0c;供自己和大家查阅学习&#xff0c;想查看 up 原视频请移步 B 站&#xff0c;侵删。 1.1 小波变换的由来 傅里叶变换基本思想&#xff1a;将信号分解成一系列不同频率的连续正弦波的叠加。 其缺点是&#xff0c;…

进入IT行业:选择前端开发还是后端开发?

一、前言 开发做前端好还是后端好&#xff1f;这是一个常见的问题&#xff0c;特别是对于初学者来说。在编程世界中&#xff0c;前端开发和后端开发分别代表着用户界面和数据逻辑&#xff0c;就像城市的两个不同街区一样。但是&#xff0c;究竟哪个街区更适合我们作为开发者呢…

Redis过期删除策略和内存淘汰策略的区别

过期删除策略 有关过期时间的设置和查询 查看某个 key 剩余的存活时间&#xff0c;可以使用 TTL 命令&#xff08;单位是秒&#xff09;。 取消 key 的过期时间&#xff0c;则可以使用 PERSIST 命令。 # 取消 key1 的过期时间 > persist key1 (integer) 1# 使用完 persist…

分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测

分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测 目录 分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结…

Flutter笔记:用于ORM的Floor框架简记

Flutter笔记 用于ORM的Floor框架简记 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133377191 【介绍】&#xff1a;最近想找用于Dart和Flutter的ORM框架&#xff0c;偶然间发现了Floor&#xff0c;觉得还不错&#xff0c;做一些记录。 1. Floor 框…

wsl2 更新报错问题解决记录

1、问题 win10 中安装的 wsl2&#xff0c;启动 docker desktop 时提示 wsl2 有问题&#xff1a; 于是点击推荐的地址连接到微软&#xff0c;下载 wsl2 的更新文件。之后运行&#xff0c;又报错&#xff1a; 更新被卡住。 2、解决方法 WinR 输入 cmd 打开命令行窗口&#x…

Spring面试题7:面试官:Spring是如何进行异常处理的呢?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Spring是如何进行异常处理的呢? Spring通过异常处理机制来处理应用程序中的异常。它提供了多种方式来处理异常,包括以下几种: 声明式事务管理:…

目标检测如何演变:从区域提议和 Haar 级联到零样本技术

目录 一、说明 二、目标检测路线图 2.1 路线图&#xff08;一般&#xff09; 2.2 路线图&#xff08;更传统的方法&#xff09; 2.3 路线图&#xff08;深度学习方法&#xff09; 2.4 对象检测指标的改进 三、传统检测方法 3.1 维奥拉-琼斯探测器 (2001) 3.2 HOG探测器…

Video Caption / 视频字幕:常用指标(BELU-4,ROUGE-L,METEOR,CIDEr,SPICE)和数据集总结

本文作为入门Video Caption / 视频字幕 的随笔记录&#xff0c;用于查漏补缺和回顾&#xff0c;难免有疏漏和不足指出&#xff0c;烦请指出&#xff01; 一、指标 Video Caption / 视频字幕常用的标准指标有四种&#xff1a;BLEU-1[1]&#xff0c;BLEU-2[1]&#xff0c;BLEU-3[…

Oracle 11g RAC部署笔记

搭了三次才搭好&#xff0c;要记录一下。 1. Oracle 11g RAC部署的相关步骤以及需要的包&#xff0c;可以参考这里。 Oracle 11g RAC部署_12006142的技术博客_51CTO博客Oracle 11g RAC部署&#xff0c;Oracle11gRAC部署操作环境&#xff1a;CentOS7.4Oracle11.2.0.4一、主机网…

第十四届蓝桥杯大赛软件赛决赛 C/C++ 大学 B 组 试题 C: 班级活动

[蓝桥杯 2023 国 B] 班级活动 【问题描述】 小明的老师准备组织一次班级活动。班上一共有 n n n 名&#xff08; n n n 为偶数&#xff09;同学&#xff0c;老师想把所有的同学进行分组&#xff0c;每两名同学一组。为了公平&#xff0c;老师给每名同学随机分配了一个 n n …

(三)Python变量类型和运算符

所有的编程语言都支持变量&#xff0c;Python 也不例外。变量是编程的起点&#xff0c;程序需要将数据存储到变量中。 变量在 Python 内部是有类型的&#xff0c;比如 int、float 等&#xff0c;但是我们在编程时无需关注变量类型&#xff0c;所有的变量都无需提前声明&#x…