Kubernetes v1.17
αservice topology 服务拓扑能使kubernetes的service基于集群的node拓扑来路由流量。例如service可以指定将流量优先路由到与client客户端同一节点或者在同一可用区域的node上的pod。
为了启用拓扑感知的服务路由,需要满足以下先决条件:
Kubernetes 1.17或更高版本
Kube-proxy在iptables模式或IPVS模式下运行
为所有Kubernetes组件启用ServiceTopology
和EndpointSlice
功能门:
--feature-gates="ServiceTopology=true,EndpointSlice=true"
默认情况下,发送到ClusterIP
或NodePort
服务的流量通过iptables
或者ipvs
转发规则随机路由到该服务的任何后端endpoints地址。不支持更加复杂灵活的拓扑(比分:分区路由)
Service Topology功能允许服务建立者定义路由基于Node labels
对源和目的节点流量做有针对的策略路由规则。
通过使用源和目的地之间的Node labels
匹配,操作员可以针对一些特定metrics来指定物理拓扑(机架位置)或者网络拓扑(可用区域)上的“更近”和“更远”的一组节点。
例如,对于公共云中的许多运营商而言,倾向于将服务流量保持在同一区域内,因为区域间流量具有与其相关的成本,而区域内流量则没有。其他常见需求包括能够将流量路由到由DaemonSet管理的本地Pod,或将流量保持到连接到同一机架顶部交换机的节点,以实现最低延迟。
如果您的集群启用了服务拓扑,则可以通过topologyKeys
在服务规范上指定字段来控制服务流量路由。该字段是节点标签的优先顺序列表,将在访问此服务时用于对端点进行排序。流量将被定向到其第一个标签的值与该标签的始发节点的值匹配的节点。如果在匹配的节点上没有该服务的后端,则将考虑第二个标签,依此类推,直到没有标签剩余为止。
如果找不到匹配项,则流量将被拒绝,就像该服务根本没有后端一样。即,基于具有可用后端的第一个拓扑密钥选择端点。如果指定了此字段,并且所有条目都没有与客户端拓扑匹配的后端,则该服务没有该客户端的后端,因此连接将失败。该特殊值"*"
可以用来表示“任何拓扑”。如果使用了此包罗万象的值,则仅作为列表中的最后一个值才有意义。
如果topologyKeys
未指定或为空,则不会应用拓扑约束。
考虑一个带有节点的群集,这些节点用其主机名,区域名称和区域名称标记。然后,您可以如下设置topologyKeys
服务的值以引导流量。
["kubernetes.io/hostname"]
。["kubernetes.io/hostname", "topology.kubernetes.io/zone", "topology.kubernetes.io/region"]
。例如,在数据局部性很关键的情况下,这可能很有用。["topology.kubernetes.io/zone", "*"]
。externalTrafficPolicy=Local
,因此服务不能同时使用这两个功能。可以在不同服务上的同一群集中使用这两个功能,而不能在同一服务上使用。kubernetes.io/hostname
, topology.kubernetes.io/zone
和topology.kubernetes.io/region
,但将来会推广到其他节点标签。"*"
,则它必须是拓扑键中的最后一个值。以下是使用服务拓扑功能的常见示例。
仅路由到节点本地终结点的服务。如果节点上不存在端点,则会丢弃流量:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
topologyKeys:
- "kubernetes.io/hostname"
首选节点本地终结点但如果节点本地终结点不存在则回退到群集范围终结点的服务:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
topologyKeys:
- "kubernetes.io/hostname"
- "*"
优先选择区域端点而不是区域端点的服务。如果两个端点均不存在端点,则会丢弃流量。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
topologyKeys:
- "topology.kubernetes.io/zone"
- "topology.kubernetes.io/region"
一种服务,它偏爱节点本地,区域终结点和区域终结点,但回退到群集范围的终结点。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
topologyKeys:
- "kubernetes.io/hostname"
- "topology.kubernetes.io/zone"
- "topology.kubernetes.io/region"
- "*"