前提条件
本文假设您的 ACK 集群已经创建完成。
开启 MSE 微服务治理
- 点击 开通MSE微服务治理专业版 以使用微服务治理能力。
- 访问容器服务控制台,打开应用目录,搜索
ack-mse-pilot
,选择对应集群,点击创建。 - 如果您使用了ASK/ECI,请首先给 ECI 授权访问 MSE 的权限。
- 安装
ack-kubernetes-cronhpa-controller
,安装步骤请参考之前的说明 - 安装
ack-ingress-nginx
,安装步骤请参考之前的说明 - 访问 MSE 控制台,在K8s集群列表中选择相应集群,点击管理,选择
default
命名空间,点击开启服务治理能力。
开启 AHAS 应用防护
- 点击开通 AHAS 应用防护 以使用应用流控能力,请注意,需要开通 AHAS 流量防护专业版
- 访问容器服务控制台,打开应用目录,搜索
ack-ahas-sentinel-pilot
,选择对应集群,点击创建。
部署 Demo 应用程序
将下面的文件保存到 mse-demo.yaml 中,并执行 kubectl apply -f mse-demo.yaml
以部署应用,这里我们将要部署 zuul,A, B, C 三个应用,其中 A、B 两个应用分别部署一个基线版本和一个灰度版本,B应用的基线版本关闭了无损下线能力,灰度版本开启了无损下线能力。C应用有一个 spring-cloud-c-warmup
应用,开启了服务预热能力,其中预热时长为2分钟。
# 入口 zuul 应用 apiVersion apps/v1 kind Deployment metadata name spring-cloud-zuul spec replicas1 selector matchLabels app spring-cloud-zuul template metadata annotations msePilotCreateAppName spring-cloud-zuul alibabacloud.com/burst-resource eci labels app spring-cloud-zuul spec containers env name JAVA_HOME value /usr/lib/jvm/java-1.8-openjdk/jre name LANG value C.UTF-8 image registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-zuul1.0.1 imagePullPolicy Always name spring-cloud-zuul ports containerPort20000 # A 应用 base 版本,开启按照机器纬度全链路透传 --- apiVersion apps/v1 kind Deployment metadata labels app spring-cloud-a name spring-cloud-a spec replicas2 selector matchLabels app spring-cloud-a template metadata annotations msePilotCreateAppName spring-cloud-a ahasPilotAutoEnable"on" ahasAppName spring-cloud-a armsPilotAutoEnable"on" armsPilotCreateAppName spring-cloud-a alibabacloud.com/burst-resource eci k8s.aliyun.com/eci-use-specs 4-8Gi labels app spring-cloud-a spec containers env name LANG value C.UTF-8 name JAVA_HOME value /usr/lib/jvm/java-1.8-openjdk/jre name profiler.micro.service.tag.trace.enable value"true" image registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-a 0.1-SNAPSHOT imagePullPolicy Always name spring-cloud-a ports containerPort20001 protocol TCP resources requests cpu'4' memory 8Gi livenessProbe tcpSocket port20001 initialDelaySeconds10 periodSeconds30 # A 应用 gray 版本,开启按照机器纬度全链路透传 --- apiVersion apps/v1 kind Deployment metadata labels app spring-cloud-a-gray name spring-cloud-a-gray spec replicas2 selector matchLabels app spring-cloud-a-gray strategy template metadata annotations alicloud.service.tag gray msePilotCreateAppName spring-cloud-a alibabacloud.com/burst-resource eci k8s.aliyun.com/eci-use-specs 4-8Gi labels app spring-cloud-a-gray spec containers env name LANG value C.UTF-8 name JAVA_HOME value /usr/lib/jvm/java-1.8-openjdk/jre name profiler.micro.service.tag.trace.enable value"true" image registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-a 0.1-SNAPSHOT imagePullPolicy Always name spring-cloud-a-gray ports containerPort20001 protocol TCP resources requests cpu'4' memory 8Gi livenessProbe tcpSocket port20001 initialDelaySeconds10 periodSeconds30 # B 应用 base 版本,关闭无损下线能力 --- apiVersion apps/v1 kind Deployment metadata labels app spring-cloud-b name spring-cloud-b spec replicas2 selector matchLabels app spring-cloud-b strategy template metadata annotations msePilotCreateAppName spring-cloud-b alibabacloud.com/burst-resource eci k8s.aliyun.com/eci-use-specs 4-8Gi labels app spring-cloud-b spec containers env name LANG value C.UTF-8 name JAVA_HOME value /usr/lib/jvm/java-1.8-openjdk/jre name micro.service.shutdown.server.enable value"false" name profiler.micro.service.http.server.enable value"false" name profiler.micro.service.warmup.enable value"true" image registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-b 0.1-SNAPSHOT imagePullPolicy Always name spring-cloud-b ports containerPort8080 protocol TCP resources requests cpu'4' memory 8Gi livenessProbe tcpSocket port20002 initialDelaySeconds10 periodSeconds30 # B 应用 gray 版本,默认开启无损下线功能 --- apiVersion apps/v1 kind Deployment metadata labels app spring-cloud-b-gray name spring-cloud-b-gray spec replicas2 selector matchLabels app spring-cloud-b-gray template metadata annotations alicloud.service.tag gray msePilotCreateAppName spring-cloud-b alibabacloud.com/burst-resource eci k8s.aliyun.com/eci-use-specs 4-8Gi labels app spring-cloud-b-gray spec containers env name LANG value C.UTF-8 name JAVA_HOME value /usr/lib/jvm/java-1.8-openjdk/jre name profiler.micro.service.warmup.enable value"true" image registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-b 0.1-SNAPSHOT imagePullPolicy Always name spring-cloud-b-gray ports containerPort8080 protocol TCP resources requests cpu'4' memory 8Gi livenessProbe tcpSocket port20002 initialDelaySeconds10 periodSeconds30 lifecycle preStop exec command /bin/sh '-c' >- wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep 30;exit 0 # C 应用 base 版本 --- apiVersion apps/v1 kind Deployment metadata labels app spring-cloud-c name spring-cloud-c spec replicas2 selector matchLabels app spring-cloud-c template metadata annotations msePilotCreateAppName spring-cloud-c alibabacloud.com/burst-resource eci k8s.aliyun.com/eci-use-specs 4-8Gi labels app spring-cloud-c spec containers env name LANG value C.UTF-8 name JAVA_HOME value /usr/lib/jvm/java-1.8-openjdk/jre image registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-c 0.1-SNAPSHOT imagePullPolicy Always name spring-cloud-c ports containerPort8080 protocol TCP resources requests cpu'4' memory 8Gi livenessProbe tcpSocket port20003 initialDelaySeconds10 periodSeconds30 # C 应用 warmup 版本 --- apiVersion apps/v1 kind Deployment metadata labels app spring-cloud-c-warmup name spring-cloud-c-warmup spec replicas1 selector matchLabels app spring-cloud-c-warmup template metadata annotations msePilotCreateAppName spring-cloud-c-warmup alibabacloud.com/burst-resource eci k8s.aliyun.com/eci-use-specs 4-8Gi labels app spring-cloud-c-warmup spec containers env name LANG value C.UTF-8 name JAVA_HOME value /usr/lib/jvm/java-1.8-openjdk/jre name profiler.micro.service.warmup.enable value"true" name profiler.micro.service.warmup.time value"120" image registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/spring-cloud-c 0.1-SNAPSHOT imagePullPolicy IfNotPresent name spring-cloud-c-warmup ports containerPort8080 protocol TCP resources requests cpu'4' memory 8Gi livenessProbe tcpSocket port20003 initialDelaySeconds10 periodSeconds30 lifecycle preStop exec command /bin/sh '-c' >- wget http://127.0.0.1:54199/offline 2>/tmp/null;sleep 30;exit 0 # Nacos Server --- apiVersion apps/v1 kind Deployment metadata labels app nacos-server name nacos-server spec replicas1 selector matchLabels app nacos-server template metadata labels app nacos-server spec containers env name MODE value standalone image registry-vpc.cn-beijing.aliyuncs.com/wangtao-mse/nacos-server latest imagePullPolicy Always name nacos-server resources requests cpu 250m memory 512Mi dnsPolicy ClusterFirst restartPolicy Always # Nacos Server Service 配置 --- apiVersion v1 kind Service metadata name nacos-server spec ports port8848 protocol TCP targetPort8848 selector app nacos-server type ClusterIP #HPA 配置 --- apiVersion autoscaling.alibabacloud.com/v1beta1 kind CronHorizontalPodAutoscaler metadata labels controller-tools.k8s.io"1.0" name spring-cloud-b spec scaleTargetRef apiVersion apps/v1beta2 kind Deployment name spring-cloud-b jobs name"scale-down" schedule"0 */4 * * * *" targetSize2 name"scale-up" schedule"2 */4 * * * *" targetSize4 --- apiVersion autoscaling.alibabacloud.com/v1beta1 kind CronHorizontalPodAutoscaler metadata labels controller-tools.k8s.io"1.0" name spring-cloud-b-gray spec scaleTargetRef apiVersion apps/v1beta2 kind Deployment name spring-cloud-b-gray jobs name"scale-down" schedule"0 */5 * * * *" targetSize2 name"scale-up" schedule"3 */5 * * * *" targetSize4 --- apiVersion autoscaling.alibabacloud.com/v1beta1 kind CronHorizontalPodAutoscaler metadata labels controller-tools.k8s.io"1.0" name spring-cloud-c-warmup spec scaleTargetRef apiVersion apps/v1beta2 kind Deployment name spring-cloud-c-warmup jobs name"scale-down" schedule"0 */4 * * * *" targetSize0 name"scale-up" schedule"1 */4 * * * *" targetSize1 # zuul 网关开启 SLB 暴露展示页面 --- apiVersion v1 kind Service metadata name zuul-slb spec ports port80 protocol TCP targetPort20000 selector app spring-cloud-zuul type ClusterIP # 为 zuul 网关开启 Ingress --- apiVersion networking.k8s.io/v1beta1 kind Ingress metadata name zuul spec rules http paths backend serviceName zuul-slb servicePort80 path /
流量压力来源
在spring-cloud-zuul
应用中,每个 pod 具备并发为 100 qps 的访问本地 zuul 端口的 127.0.0.1:20000:/A/a
的http请求流量,另外有10 qps 会访问 127.0.0.1:20000:/A/a
并且带上 x-mse-tag=gray
这个header,当前 zuul 的 pod 数为1,所以 spring-cloud-a
应用的平均qps为 110。压力可以通过 环境变量 demo.qps
来调节压力大小,默认为100
流量架构图如下:
结果验证
MSE 场景一:对经过机器的流量进行自动染色,实现全链路灰度
我们在 MSE 控制台对 spring-cloud-a
应用配置如下流量比例规则,由于我们对 spring-cloud-a 应用增加了
profiler.micro.service.tag.trace.enable=true
的开关,spring-cloud-a 应用会对经过他的流量进行染色透传,从而实现全链路灰度。
spring-cloud-a
中,灰度分组的流量是10,基线分组的流量是100.
spring-cloud-b 中,灰度分组的流量是也是10,基线分组的流量是100.
找到 容器服务对外暴露的 Ingress 的端点。
在命令行中输入以下命令,发现正常的流量走到基线的机器上
curl http://$IP/A/a A[172.16.2.16] -> B[172.16.2.20] -> C[172.16.2.21]
在命令行中输入一下命令,带上特殊的 header ,发现灰度的流量走到灰度的机器上,并且会向后透传经过 A 和 B 的灰度机器,最后回到 C的基线版本中。
curl -H"x-mse-tag:gray" http://$IP/A/a Agray[172.16.2.23] -> Bgray[172.16.2.18] -> C[172.16.2.21]
MSE 场景二:服务预热
我们在 spring-cloud-c-warmup
应用开启了定时HPA模拟应用启动的过程,同时对spring-cloud-c-warmup 应用开启了默认2分钟时长的预热功能 profiler.micro.service.warmup.time=120
可以直接在spring-cloud-c-warmup应用直观地看到效果
从上图可以看出来流量缓慢增大,直观地服务预热看到服务预热的效果。
MSE 场景三:无损下线
由于我们对 spring-cloud-b
跟 spring-cloud-b-gray
应用均开启了定时HPA,模拟每4分钟进行一次定时的扩缩容。
我们可以直接从 spring-cloud-a
应用的监控看出来,未开启无损下线功能的监控存在错误。而 gray的流量因为默认开启了无损下线功能,流量默认无损。
可以看到gray的流量在pod扩缩容的过程中无流量损失,未打标的流量由于关闭了无损下线功能,在pod扩缩容的过程中流量出现了损失,如上图所示未打标的流量有 122 的请求错误。
通过 AHAS 实现限流降级
打开 AHAS 控制台 ,找到 spring-cloud-a
应用,选择接口详情,找到 /a
接口,点击 + 好号新增流控规则
选择流控规则,输入单机 QPS 限流阈值 10,点击下一步,最后点击新增。
点击新增添加流控规则
等待约 10s 左右,观察 接口的 QPS 情况,发现通过 QPS 从 100 下降到 20,拒绝 QPS 从 0 上升到 80,因为 spring-cloud-a
有两台机器,因此总的通过 QPS 为 20.
接下来,将该限流规则关闭
观察 QPS , 发现 通过 QPS 回到 100,拒绝 QPS 降低为 0。