k8s 服务拓扑设置定向流量有哪些常见场景?
k8s 服务拓扑设置定向流量有哪些常见场景?
面试官:"说说你对Kubernetes 网络模型的理解?设计这种网络模型有什么好处?"
面试官:"Kubernetes 网络主要解决哪四方面的问题?"
面试官:"k8s利用服务拓扑的流量路由策略来设置定向流量,拓扑键的匹配规则是什么?"
面试官:"日常使用拓扑键有什么约束?"
面试官:"简单说说服务拓扑设置定向流量有哪些常见场景?试举例说明?"
囧么肥事-胡说八道
说说你对Kubernetes 网络模型的理解?设计这种网络模型有什么好处?
集群网络系统是 Kubernetes 的核心部分,Kubernetes 的宗旨就是在应用之间共享机器。
要解决的问题?
通常来说,共享机器需要两个应用之间不能使用相同的端口,但是在多个应用开发者之间 去大规模地协调端口是件很困难的事情,尤其是还要让用户暴露在他们控制范围之外的集群级别的问题上。
动态分配端口也会给系统带来很多复杂度 - 每个应用都需要设置一个端口的参数, 而 API 服务器还需要知道如何将动态端口数值插入到配置模块中,服务也需要知道如何找到对方等等。
针对这些问题,Kubernetes设计了一种干净的、向后兼容的网络模型,即 IP-per-pod
模型。怎么说?
Kubernetes 强制要求所有网络设施都满足以下基本要求(从而排除了有意隔离网络的策略):
节点上的 Pod 可以不通过 NAT 和其他任何节点上的 Pod 通信
节点上的代理(比如:系统守护进程、kubelet)可以和节点上的所有 Pod 通信
另外,对于支持在主机网络中运行 Pod
的平台(比如:Linux):
运行在节点主机网络里的 Pod 可以不通过 NAT 和所有节点上的 Pod 通信
这意味着什么?
意味着 k8s 假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中
从端口分配、命名、服务发现、负载均衡、应用配置和迁移的角度来看在这个模型,所有的
Pod
都可以被视作虚拟机或者物理主机。
Kubernetes 网络主要解决哪四方面的问题?
首先,k8s的架构体系决定了在K8S上的网络通信四大类:
第一类:高度耦合的容器之间的通信:同一个Pod内的多个容器之间通过本地回路(loopback)通信。
第四类:Service和集群外部客户端之间的通信,Service 资源允许对外暴露 Pods 中运行的应用程序,以支持来自于集群外部的访问,实现方式:Ingress、NodePort、Loadbalance
k8s利用服务拓扑的流量路由策略来设置定向流量,拓扑键的匹配规则是什么?
在说拓扑键的匹配规则之前,先了解下什么是服务拓扑的流量路由策略?
服务拓扑(Service Topology)可以让一个服务基于集群的 Node 拓扑进行流量路由。
例如,一个服务可以指定流量是被优先路由到一个和客户端在同一个 Node 或者在同一可用区域的端点。
Kubernetes 1.7 允许将“外部”流量路由到接收到流量的 节点上的 Pod。对于 ClusterIP
服务,无法完成同节点优先的路由,你也无法配置集群优选路由到同一可用区中的端点。
流量路由拓扑策略理解
通过在 Service 上配置 topologyKeys
,对源和目的之间的标签匹配,可以基于来源节点和目标节点的标签来定义流量路由策略。
对于拓扑键,可以根据节点间彼此“较近”和“较远” 来定义节点集合,可以基于符合自身需求的任何度量值来定义标签,来匹配定向流量资源。
使用服务拓扑,拓扑键的匹配规则是什么?
如果集群启用了 ServiceTopology
特性, 你就可以在 Service 规约中设定 topologyKeys
字段,从而控制其流量路由。此字段是 Node
标签的优先顺序字段,将用于在访问这个 Service
时对端点进行排序。流量会被定向到第一个标签值和源 Node
标签值相匹配的 Node
。如果这个 Service
没有匹配的后端 Node
,那么第二个标签会被使用做匹配, 以此类推,直到没有标签。
如果没有匹配到,流量会被拒绝,就如同这个 Service
根本没有后端。换言之,系统根据可用后端的第一个拓扑键来选择端点。如果这个字段被配置了而没有后端可以匹配客户端拓扑,那么这个 Service
对那个客户端是没有后端的,链接应该是失败的。这个字段配置为 "*"
意味着任意拓扑。这个通配符值如果使用了,那么只有作为配置值列表中的最后一个才有用。
如果 topologyKeys
没有指定或者为空,就没有启用这个拓扑约束。
拓扑键有什么约束?
拓扑键的约束,其实就是使用拓扑键需要注意规避的一些原则,在规则上更好的实现流量控制:
服务拓扑和
externalTrafficPolicy=Local
是不兼容的,所以Service
不能同时使用这两种特性。但是在同一个集群的不同Service
上是可以分别使用这两种特性的,只要不在同一个Service
上就可以。有效的拓扑键目前只有:
kubernetes.io/hostname
、topology.kubernetes.io/zone
和topology.kubernetes.io/region
,但是未来会推广到其它的Node
标签。拓扑键必须是有效的标签,并且最多指定16个。
通配符:
"*"
,如果要用,则必须是拓扑键值的最后一个值。
简单说说服务拓扑设置定向流量有哪些常见场景?试举例说明?
在一个集群中,其 Node
的标签被打为其主机名,区域名和地区名。那么就可以设置 Service
的 topologyKeys
的值,控制流量路由。
例如,在公有云上,你可能更偏向于把流量控制在同一区内,因为区间流量是有费用成本的, 而区内流量则没有。
常见需求还包括把流量路由到由
DaemonSet
管理的本地 Pod 上,或者把将流量转发到连接在同一机架交换机的节点上,以获得低延时。
以下是使用服务拓扑功能的一些经典的常见示例
第一种:仅路由到节点本地端点,如果节点上不存在端点,流量则被丢弃,只定向到同一个
Node
上的端点,Node
上没有端点存在时就失败:配置["kubernetes.io/hostname"]
。第二种:首先节点本地端点,如果节点本地端点不存在,则回退到集群范围端点:配置["kubernetes.io/hostname", "*"]
第三种:偏向定向到同一个 `Node` 上的端点,回退同一区域的端点上,然后是同一地区, 其它情况下就失败。例如,数据局部性很重要的情况下或许就很有用:配置
["kubernetes.io/hostname", "topology.kubernetes.io/zone", "topology.kubernetes.io/region"]
。第四种:偏向于同一区域,但如果此区域中没有可用的终结点,则回退到任何可用的终结点:配置
["topology.kubernetes.io/zone", "*"]
。第五种:仅地域或区域端点,首选地域端点而不是区域端点的一种服务, 如果以上两种范围内均不存在端点, 流量则被丢弃。配置:["topology.kubernetes.io/zone", "topology.kubernetes.io/region"]
第六种:优先选择节点本地端点、地域端点,然后是区域端点,最后才是集群范围端点。配置:
["kubernetes.io/hostname", "topology.kubernetes.io/zone", "topology.kubernetes.io/region", "*"]
。