一文搞懂 Kubernetes Gateway API 的 Policy Attachment
点击上方蓝字
关注我们
在《SMI 与 Gateway API 的 GAMMA 倡议意味着什么?》的一文中,介绍过 Kubernetes Gateway API 处理东西向(网格)流量的可能性。让我们重新看下 Gateway API 中对流量定义(路由)的定义,以 HTTP 路由为例:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: my-route
namespace: gateway-api-example-ns2
spec:
parentRefs:
- kind: Gateway
name: foo-gateway
namespace: gateway-api-example-ns1
hostnames:
- foo.example.com
rules:
- backendRefs:
- name: foo-svc
port: 8080
上面的 YAML 中,使用 parentRefs 字段将路由策略附加到了网关资源 foo-gateway 上。网关 foo-gateway 会根据请求头部的 HOST 来选择合适的 HTTPRoute,然后将流量代理到上游 Service foo-svc。简单来说,就是定义了“网关 -> 路由 -> 后端”的映射。
通过对流量的定义以及处理流量的资源的选择,实现7层 HTTP 协议的反向代理和负载均衡。但在实际的场景下,简单的代理路由策略还并不够,可能还需要配合治理策略来提升服务的健壮性,比如限流、重试、超时、熔断、自定义健康检查等等。
我们看下 Istio 的超时配置,首先使用了 reviews 进行流量的匹配,然后再根据路由的策略 uri 前缀 /review 进行路由匹配,将流量代理到目的地 v2 的 reviews。与此同时,该路由的超时为 0.5s。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- uri:
prefix: "/review"
route:
- destination:
host: reviews
subset: v2
timeout: 0.5s
在这段定义中耦合了流量匹配、路由匹配、后端指定、超时,如果需要配置重试呢,再加个 retries 字段。如此一来,灵活性大打折扣。
微软MVP实验室研究员
目标
Kubernetes Gateway API 的 策略附件(Policy Attachment)的设计目标:
策略和资源关联标准化
支持策略的默认值和覆盖值
不同资源上策略生效的优先级
为资源施加策略的时候,既要考虑通用性(标准化)又要考虑灵活性(策略值优先级)。
这里说的资源可以是网关相关的任何资源,比如 GatewayClass、Gateway、路由(如 HTTPRoute、TCPRoute、GRPCRoute)、Kubernetes 核心资源(如 Namespace、Service)。后面几种资源还会分命名空间,比如是请求发起方(Gateway、服务消费方)或者请求接收方(服务提供方)的命名空间。
这些资源的影响范围各有不同,我们暂且称为粒度,比如 GatewayClass 影响某类网关实现所有实例上的流量;Gateway 资源则特指进入某个网关实例的流量;Namespace 特指由该命名空间下的资源发出或者接收的流量;路由则特指具有某种特征的流量,并且路由的定义可以定义在发起方的命名空间,也可以定义在接收方的命名空间。
可见虽然策略是附加在资源上,但作用的最终目标还是流量:南北向流量和东西向流量,分别对应入口策略和网格策略。▍入口策略
▍网格策略
设计
▍策略与资源关联标准化
策略与资源关联的设计引入了 Target Reference API 的概念,即每个策略上必须要有一个 targetRef 字段,通过该字段将资源与策略进行关联,完成解耦。
apiVersion: networking.example.net/v1alpha1
kind: TimeoutPolicy
metadata:
name: foo
spec:
default:
connectionTimeout: 3
readTimeout: 5
targetRef:
kind: HTTPRoute
name: example
type PolicyTargetReference struct {
Group Group `json:"group"`
Kind Kind `json:"kind"`
Name ObjectName `json:"name"`
Namespace *Namespace `json:"namespace,omitempty"`
}
▍默认值和覆盖值
默认值体现的是缺省状态下的策略设置,比如前面具有 HTTPRoute example 描述的特征的流量,通过 spec.default 配置了默认超时时间。
下面的策略,则使用 spec.override 对所有进入 Gateway 资源 example(网关实例)的流量连接超时为5。
那最终哪个值会生效呢?我们可以这样理解,所有的覆盖值的优先级会高于默认值。也就是符合匹配策略条件的流量,会优先使用覆盖值。
apiVersion: networking.example.net/v1alpha1
kind: TimeoutPolicy
metadata:
name: foo
spec:
override:
connectionTimeout: 5
targetRef:
kind: Gateway
name: example
▍策略的优先级
默认值和覆盖值的优先级已经有了,上面在介绍资源的时候提到了资源的级别,并且策略也可以附加到不同的资源上。比如下面的策略定义了读取超时的默认值以及连接超时的覆盖值,附加到了 Service example 上,实际作用的资源是后端(Backend)工作负载。
apiVersion: networking.example.net/v1alpha1
kind: TimeoutPolicy
metadata:
name: foo
spec:
override:
connectionTimeout: 1
default:
readTimeout: 10
targetRef:
kind: Service
name: example
流量的路径是 Gateway example -> HTTPRoute example -> Backend example。
对于覆盖值,优先级与资源的级别相同;而默认值,则与资源的级别正好相反。因此,最终的生效设置是:
connectionTimeout: 5 # from gateway override
readTimeout: 10 # from backend default
现状
截止文章发出时,了解到的 Linkerd 在1.12中参考 Policy Attachment 的设计实现了 AuthorizationPolicy,并计划待 Gateway API 中的设计稳定后切换到 Gateway API 的 CRD。
如果你了解有其他的 Policy Attachment 实现,可以在文章下面留言。参考资料
策略附件(Policy Attachment): https://gateway-api.sigs.k8s.io/references/policy-attachment/ Target Reference API: https://gateway-api.sigs.k8s.io/references/policy-attachment/#target-reference-api
*未经授权请勿私自转载此文章及图片。
微软最有价值专家(MVP)
https://mvp.microsoft.com/zh-cn
谢谢你读完了本文!欢迎在评论区留言分享你的想法,并且转发到朋友圈。
点击「阅读原文」加入微软 MVP~