API 网关深度集成火山引擎容器服务 VKE,可实时动态获取 VKE 集群中部署的 K8S Service 信息,作为 K8S Service 对外提供服务的流量入口。同时,API 网关提供 Upstream 流量分配,方便用户进行服务的灰度发布,实现敏捷迭代、平滑升级。本文为您介绍如何通过 API 网关实现容器服务中应用的蓝绿部署和灰度发布。
为了保证服务稳定地对外提供服务,各企业都十分重视发布策略的选择。目前被业界广泛采用的服务发布策略有蓝绿部署和灰度发布,请根据实际情况选择适合的发布策略。
本文通过一个 service-demo 服务,为您演示容器服务集群中应用的蓝绿发布和灰度发布。该服务已提供一个查询当前版本的接口,请求路径为/version
。API 网关将该 service-demo 服务抽象为一个 Upstream,并通过 Pod 标签来标识旧版本 v1 和新版本 v2。用户发送请求后,API 网关便可将请求按照设置的权重转发至新旧版本,实现应用的多版本流量管理。
容器服务 VKE
API 网关
使用如下 YAML 配置,在容器服务集群中部署 v1 版本应用和服务。
apiVersion: apps/v1 kind: Deployment metadata: name: app-old namespace: default spec: replicas: 2 selector: matchLabels: app: demo template: metadata: labels: app: demo version: v1 spec: containers: - image: cr-apig-cn-beijing.cr.volces.com/apig-demo/http-server:v1 name: demo ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: service-demo spec: selector: app: demo ports: - name: rule protocol: TCP port: 80 targetPort: 80 type: NodePort
创建 Upstream 并关联 service-demo 服务。
为 Upstream 添加 version:v1
版本标识。该标识对应 Pod 的spec.template.metadata.labels
配置,用于区分应用的不同版本。详情可参见 管理容器服务类型 Upstream 版本。
创建路由,发布服务。其中,请求路径为/version
,目标 Upstream 为 service-demo 服务,版本为 v1,权重为 100%。
执行以下命令,进行 10 次访问测试。
for i in {1..10}; do curl ${网关服务域名}/version;echo;done
预期结果如下,所有请求均成功转发至 v1 版本应用。
{"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"}
使用如下 YAML 配置,在容器服务集群中部署 v2 版本应用和服务。
注意
使用 API 网关实例发布容器服务集群中的应用,支持同集群部署和跨集群部署。
apiVersion: apps/v1 kind: Deployment metadata: name: app-new spec: replicas: 1 selector: matchLabels: app: demo template: metadata: labels: app: demo version: v2 spec: containers: - image: cr-apig-cn-beijing.cr.volces.com/apig-demo/http-server:v2 name: demo ports: - containerPort: 80
为已创建的 Upstream 添加 version:v2
版本标识。详情请参见 管理容器服务类型 Upstream 版本。
修改已创建的路由规则,将流量按所需权重转发至 v1 和 v2 版本。在本例中,配置 v1 应用权重为 80%,v2 应用权重为 20%。详情请参见 管理路由。
执行以下命令,进行 10 次访问测试。
for i in {1..10}; do curl ${网关服务域名}/version;echo;done
预期结果如下,10 个请求中有 2 个请求转发至新版本 v2,流量比例符合预期。
{"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"}
注意
在真实业务场景中,新版本验证完毕后,便可继续调大访问新版本的流量权重。期间注意对新版本扩容,按需对旧版本缩容。
使用以下 YAML 配置,在容器服务集群中部署 v1 版本应用和服务。
apiVersion: v1 kind: Service metadata: name: service-old namespace: default spec: ports: - name: port port: 80 targetPort: 80 protocol: TCP selector: app: old type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: app-old namespace: default spec: replicas: 2 selector: matchLabels: app: old template: metadata: labels: app: old spec: containers: - image: cr-apig-cn-beijing.cr.volces.com/apig-demo/http-server:v1 name: demo ports: - containerPort: 80
创建 Upstream 并关联 servcie-old 服务。
创建路由,发布服务。其中,请求路径为/version
,目标 Upstream 为 service-old 服务,权重为 100%。
执行以下命令,进行 10 次访问测试。
for i in {1..10}; do curl ${网关服务域名}/version;echo;done
预期结果如下,所有请求均转发至 v1 版本应用。
{"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"}
使用以下 YAML 配置,在容器服务集群中部署 v2 版本应用和服务。
注意
使用 API 网关实例发布容器服务集群中的应用,支持同集群部署和跨集群部署。
apiVersion: v1 kind: Service metadata: name: service-new namespace: default spec: ports: - name: port port: 80 targetPort: 80 protocol: TCP selector: app: new type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: app-new spec: replicas: 1 selector: matchLabels: app: new template: metadata: labels: app: new spec: containers: - image: cr-apig-cn-beijing.cr.volces.com/apig-demo/http-server:v2 name: demo ports: - containerPort: 80
创建 Upstream 并关联 servcie-new 服务。
修改已创建的路由规则,将流量按所需权重转发至 service-old 服务和 service-new 服务。在本例中,配置 service-old 服务权重为 80%,service-new 服务权重为 20%。详情请参见 管理路由。
执行以下命令,进行 10 次访问测试。
for i in {1..10}; do curl ${网关服务域名}/version;echo;done
预期结果如下,10 个请求中有 2 个请求转发至新服务,流量比符合期望比例。
{"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"}
注意
在真实业务场景中,新服务验证完毕后,便可继续调大访问新服务的流量权重。期间注意对新服务扩容,按需对旧服务缩容。
使用以下 YAML 配置,在容器服务集群中部署 v1 版本应用和服务。
apiVersion: v1 kind: Service metadata: name: service-old namespace: default spec: ports: - name: port port: 80 targetPort: 80 protocol: TCP selector: app: old type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: app-old namespace: default spec: replicas: 2 selector: matchLabels: app: old template: metadata: labels: app: old spec: containers: - image: cr-apig-cn-beijing.cr.volces.com/apig-demo/http-server:v1 name: demo ports: - containerPort: 80
创建 Upstream 并关联 servcie-old 服务。
创建路由,发布服务。其中,请求路径为/version
,目标 Upstream 为 service-old 服务,权重为 100%。
执行以下命令,进行 10 次访问测试。
for i in {1..10}; do curl ${网关服务域名}/version;echo;done
预期结果如下,所有请求均转发至 v1 版本应用。
{"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"}
使用以下 YAML 配置,在容器服务集群中部署 v2 版本应用和服务。
注意
使用 API 网关实例发布容器服务集群中的应用,支持同集群部署和跨集群部署。
apiVersion: v1 kind: Service metadata: name: service-new namespace: default spec: ports: - name: port port: 80 targetPort: 80 protocol: TCP selector: app: new type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: app-new spec: replicas: 1 selector: matchLabels: app: new template: metadata: labels: app: new spec: containers: - image: cr-apig-cn-beijing.cr.volces.com/apig-demo/http-server:v2 name: demo ports: - containerPort: 80
创建 Upstream 并关联 servcie-new 服务。
创建路由规则,发布 service-new 服务。其中:
执行以下命令,进行 10 次未包含 Header 的访问请求。
for i in {1..10}; do curl ${网关服务域名}/version;echo;done
预期结果如下。由于未包含 Header,访问请求全部转发至 v1 服务。
{"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"} {"code": 200, "message": "version: v1"}
执行以下命令,进行 10 次包含 Header 的访问请求。
for i in {1..10}; do curl -H "foo:bar" ${网关服务域名}/version;echo;done
预期结果如下。由于包含 Header,访问请求全部转发至 v2 服务。
{"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"} {"code": 200, "message": "version: v2"}
如上所示,两条路由都允许通过相同的服务域名进行访问,如果访问中带上 Header(foo=bar),则转发至 v2 版本的应用;否则转发至 v1 版本的应用。
注意
在真实业务场景中,新服务验证完毕后,便可继续调大访问新服务的流量权重。期间注意对新服务扩容,按需对旧服务缩容。