Knative 是基于Kubernetes之上提供的一款开源Serverless应用框架,帮助您部署和管理现代化的Serverless工作负载,打造企业级Serverless平台,当前阿里云容器服务已经集成 Knative。
ALB 是专门面向HTTP、HTTPS和QUIC等应用层负载场景的负载均衡服务,具备超强弹性及大规模七层流量处理能力,支持Header、Cookie灰度发布。
本文介绍如何在阿里云容器服务 Knative 集成 ALB。
容器服务 Knative 中网关使用现状
当前在容器服务 Knative 中已经支持社区的 Kourier 网关以及与SLB网关集成,但这 2 种网关在使用中还存在如下问题:
- Knative 社区提供的 Kourier 网关,但使用原生网关存在如下问题:
- 社区原生Kourier 网关,部署在用户集群,需要客户自行负责 Kourier 网关的运维,承担资源成本以及运维成本
- 不支持Cookie灰度发布
- Knative 已经集成了 SLB 网关,但该网关不支持Header、Cookie 灰度发布。
目标与收益
目标:在 Serverless Framework(Knative)中提供云产品 ALB 网关能力
收益:既带来 Serverless Framework 网关能力增强,又拓展了 ALB Ingress 应用场景。
对接 ALB 方案
基本思路:将 Knative Ingress 转换成 K8s Ingress, 然后通过 ALB Ingress Controller 创建ALB以及转发规则。架构图如下:
关键设计
- Knative Service、Knative Ingress与K8s Ingress对应关系
- 一个 Knative Service 对应一个 Knative Ingress ,对应一个 K8s Ingress
- vswitch 虚拟交换机配置
由于创建ALB需要指定vswitch,因此需要用户在 Knative 中配置vswitch id信息。
knative-serving 命名空间 config-network configmap中配置参数:
apiVersion: v1 kind: ConfigMap metadata: data: ingress.class: alb.ingress.networking.knative.dev vswitch-ids: vsw-2zeqgkyib34gw1fxxx,vsw-2zefv5qwao4prxxx ...
- 公网/内网访问
- 当创建 Knative Service 时, 开始创建ALB
- 根据 Ingress 判断是否公网。默认创建公网ALB。如果只有内网访问的Ingress, 则创建内网ALB
- 公网访问
- 创建 Albconfig: knative-internet
- 内网访问
- 创建 Albconfig: knative-intranet
- 灰度发布
- 基于流量比例的灰度发布
- Knative Ingress会将revision service的权重转换成 K8s Ingress 灰度权重
- 基于Header和 Cookie灰度发布
- Header:
- Knative当前支持Header方式进行灰度,通过Knative-Serving-Tag: {revision-tag}实现。
- 在Knative Service中通过注解方式指定 header 对应的 traffic revision
- Cookie:在Knative Service中通过注解方式指定 cookie 对应的 traffic revision
关键实现
Knative 对接 ALB 实现,关键在于:基于Cookie、Header、权重比例的灰度发布。这里主要对灰度发布实现进行介绍。
基于流量比例的灰度发布
Knative Ingress会将 revision service 的权重转换成 K8s Ingress 灰度权重。
Knative Service 示例如下:
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-go spec: template: metadata: annotations: autoscaling.knative.dev/maxScale: "100" autoscaling.knative.dev/minScale: "0" spec: containers: - env: - name: TARGET value: Knative11 image: registry-vpc.cn-beijing.aliyuncs.com/knative-sample/helloworld-go:73fbdd56 name: user-container ports: - containerPort: 8080 name: http1 protocol: TCP traffic: - latestRevision: false percent: 50 revisionName: helloworld-go-00002 - latestRevision: false percent: 50 revisionName: helloworld-go-00001
内部转换成 K8s Ingress 如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/actions.forward-default: '{"type":"ForwardGroup","forwardConfig":{"targetGroups":[{"serviceName":"helloworld-go-00002","servicePort":80,"weight":50},{"serviceName":"helloworld-go-00001","servicePort":80,"weight":50}]}}' labels: knative.aliyun.com/ingress: helloworld-go name: helloworld-go namespace: default spec: ingressClassName: knative-alb-ingress-internet rules: - host: helloworld-go.default.example.com http: paths: - backend: service: name: forward-default port: name: use-annotation path: / pathType: Prefix - host: helloworld-go.default.svc.cluster.local http: paths: - backend: service: name: forward-default port: name: use-annotation path: / pathType: Prefix
服务访问:
$ curl ${INGRESS_DNS} -H "Host:helloworld-go.default.example.com" Hello Knative! Hello Knative 2!
基于 Cookie、Header 灰度发布
- 社区基于 Header 灰度发布
当前通过Knative Service 配置 tag-header-based-routing 方式实现header灰度发布
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: helloworld-go spec: template: metadata: annotations: autoscaling.knative.dev/maxScale: "100" autoscaling.knative.dev/minScale: "0" spec: containers: - env: - name: TARGET value: Knative11 image: registry-vpc.cn-beijing.aliyuncs.com/knative-sample/helloworld-go:73fbdd56 name: user-container ports: - containerPort: 8080 name: http1 protocol: TCP traffic: - latestRevision: false percent: 0 revisionName: helloworld-go-00002 tag: rev1 - latestRevision: false percent: 100 revisionName: helloworld-go-00001
内部转换成K8s Ingress 如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/actions.forward-default: '{"type":"forward","forwardConfig":{"serverGroups":[{"serviceName":"helloworld-go-00002","servicePort":80,"weight":50},{"serviceName":"helloworld-go-00001","servicePort":80,"weight":50}]}}' alb.ingress.kubernetes.io/actions.forward-tag: '{"type":"forward","forwardConfig":{"targetGroups":[{"serviceName":"helloworld-go-00002","servicePort":80,"weight":100}]}}' alb.ingress.kubernetes.io/conditions.forward-tag: '[{"Type":"Header","CookieConfig":{"Values":null},"HeaderConfig":{"Key":"Knative-Serving-Tag","Values":["rev1"]}}]' labels: knative.aliyun.com/ingress: helloworld-go name: helloworld-go namespace: default spec: ingressClassName: knative-alb-ingress-internet rules: - host: helloworld-go.default.a97e861255a18699.app.alicontainer.com http: paths: - backend: service: name: forward-default port: name: use-annotation path: / pathType: Prefix - host: helloworld-go.default.svc.cluster.local http: paths: - backend: service: name: forward-default port: name: use-annotation path: / pathType: Prefix - host: helloworld-go.default.a97e861255a18699.app.alicontainer.com http: paths: - backend: service: name: forward-tag port: name: use-annotation path: / pathType: Prefix - host: helloworld-go.default.svc.cluster.local http: paths: - backend: service: name: forward-tag port: name: use-annotation path: / pathType: Prefix - host: rev1-helloworld-go.default.svc.cluster.local http: paths: - backend: service: name: forward-tag port: name: use-annotation path: / pathType: Prefix
访问方式:
curl ${INGRESS_DNS} -H "Host:helloworld-go.default.example.com" -H "Knative-Serving-Tag:rev1"
- 基于 Header 灰度发布
在Knative Service中支持通过注解方式指定 header 对应的 traffic revision
apiVersion: serving.knative.dev/v1 kind: Service metadata: annotations: alicloud.serving.knative.dev/headers: [{revision:helloworld-go-00002,headers:{demo:test}}] name: helloworld-go spec: template: metadata: annotations: autoscaling.knative.dev/maxScale: "100" autoscaling.knative.dev/minScale: "0" spec: containers: - env: - name: TARGET value: Knative11 image: registry-vpc.cn-beijing.aliyuncs.com/knative-sample/helloworld-go:73fbdd56 name: user-container ports: - containerPort: 8080 name: http1 protocol: TCP traffic: - latestRevision: false percent: 0 revisionName: helloworld-go-00002 - latestRevision: false percent: 100 revisionName: helloworld-go-00001
访问方式:
curl ${INGRESS_IP} -H "Host:helloworld-go.default.example.com" --header "demo=always" --header "header2=v2"
- 基于Cookie 灰度发布
在Knative Service中通过注解方式指定 cookie 对应的 traffic revision
apiVersion: serving.knative.dev/v1 kind: Service metadata: annotations: alicloud.serving.knative.dev/cookies: [{revision:helloworld-go-00002,cookies:{demo:always,cookie2:v2}}] name: helloworld-go spec: template: metadata: annotations: autoscaling.knative.dev/maxScale: "100" autoscaling.knative.dev/minScale: "0" spec: containers: - env: - name: TARGET value: Knative11 image: registry-vpc.cn-beijing.aliyuncs.com/knative-sample/helloworld-go:73fbdd56 name: user-container ports: - containerPort: 8080 name: http1 protocol: TCP traffic: - latestRevision: false percent: 0 revisionName: helloworld-go-00002 - latestRevision: false percent: 100 revisionName: helloworld-go-00001
访问方式:
curl ${INGRESS_DNS} -H "Host:helloworld-go.default.example.com" --cookie "demo=always" --cookie "cookie2=v2"
结论
将 Knative 与 ALB 集成,进一步提升 Knative Serverless 应用产品化能力,同时拓展了 ALB Ingress 产品使用场景。欢迎大家试用。
点击下方链接了解更多产品相关信息: