为了账号安全,请及时绑定邮箱和手机立即绑定

service mesh istio微服务实验

标签:
Kubernetes

简介

本实验通过在k8s上部署istio,实现微服务的基础功能。其中会涉及到服务的限流,超时,熔断,降级,流量分隔,A/B测试等功能。实验之前需要安装k8s和istio,请参考之前文章。注意开启istio的自动注入功能。

本实验的服务间调用关系如下:

本实验采用时下流行的前后端分离模式

前端项目基于vue/react实现

前端调用python实现的API接口

python服务调用后端node实现的服务和lua实现的服务

node服务调用go实现的服务

  • ---->service-js

  • ---->service-python

    • ---->service-go

    • ---->service-lua

    • ---->service-node

本实验使用的语言技术栈:

  • vue/react

  • python2/3

  • node8/10

  • openresty1.11 /1.13

  • go1.10/1.9

架构图如下:

webp

image

下载实验仓库

git clone https://github.com/mgxian/istio-test

部署服务

cd istio-test
kubectl apply -f service/go/v1/go-v1.yml
kubectl apply -f service/go/v2/go-v2.yml
kubectl apply -f service/python/v1/python-v1.yml
kubectl apply -f service/python/v2/python-v2.yml
kubectl apply -f service/js/v1/js-v1.yml
kubectl apply -f service/js/v2/js-v2.yml
kubectl apply -f service/node/v1/node-v1.yml
kubectl apply -f service/node/v2/node-v2.yml
kubectl apply -f service/lua/v1/lua-v1.yml
kubectl apply -f service/lua/v2/lua-v2.yml

暴露服务

# 使用istio提供的ingress功能# 暴露js和python服务让k8s集群外部访问kubectl apply -f istio/ingress-python.yml
kubectl apply -f istio/ingress-js.yml# 查看kubectl get ingress

测试访问

# 配置hosts解析# 11.11.11.112为其中一个node的ip11.11.11.112 istio-test.will# 使用curlcurl -I istio-test.will
curl -s istio-test.will | egrep "vue|React"# 此时如果作用浏览器,可能会出会页面显示不正常的情况。# 因为此时请求会轮流分发到后端js服务的v1/v2版本,因此css/js并不能正常加载

流量管理

根据请求的信息,把流量路由到服务的不同版本。实验过程如果没有达到预期效果,很有可能是因为存在路由规则冲突,而且没有设置优先级,可以先删除之前设置的路由规则或者把优先级设置高一点。

把所有流量导向v1版本

# 创建路由规则istioctl create -f istio/route-rule-all-v1.yml# 查看路由规则istioctl get routerule# 访问浏览器测试http://istio-test.will/# 此时你会看到react app的界面# 点击发射按钮,会发送ajax请求到python服务# 由于把所有流量都导向了v1版本# 多次点击发射按钮会得到一样的内容# react----->Python2.7.15----->Gogo1.9.6# 清除路由规则istioctl delete -f istio/route-rule-all-v1.yml

根据请求把流量导向不同版本(A/B测试)

# 创建路由规则# 根据浏览器的不同返回不同内容istioctl create -f istio/route-rule-js-by-agent.yml# 使用访问浏览器# 如果你用chrome浏览器你会看到react app的界面# 如果你用firefox浏览器你会看到vue app的界面# 多次点击发射按钮,会获取到不同的内容# 根据前端app不同使用不同版本的python服务istioctl create -f istio/route-rule-python-by-header.yml# 此步骤创建的第一个路由规则保留不删除,为下面做实验提供方便istioctl delete -f istio/route-rule-python-by-header.yml

根据源服务把流量导向不同版本

# 创建路由规则istioctl create -f istio/route-rule-go-by-source.yml# 此时规则如下# 所有chrome浏览器都走v1版本服务# 所有firefox浏览器都走v2版本服务# react----->Python2.7.15----->Gogo1.9.6# vue----->Python3.6.5----->Gogo1.10.2# 清除路由规则istioctl delete -f istio/route-rule-go-by-source.yml

指定权重进行流量分隔

# 指定权重把流量分隔# 25%流量路由到v1版本# 75%流量路由到v2版本# 创建路由规则istioctl create -f istio/route-rule-go-v1-v2.yaml# 清除路由规则istioctl delete -f istio/route-rule-go-v1-v2.yaml

集群内访问公开服务

# 默认情况下,启用了istio的服务是无法访问外部url的# 如果需要访问外部url,需要使用egress进行配置# egress同样支持设置路由规则# httpistioctl create -f istio/egress-rule-http-bin.yml# tcpistioctl create -f istio/egress-rule-tcp-wikipedia.yml# 查看istioctl get egressrule# 测试# 使用exec进入作为测试源使用的podkubectl apply -f istio/sleep.yaml
kubectl get pods
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SOURCE_POD -c sleep bash# http测试curl http://httpbin.org/headers# tcp测试curl -o /dev/null -s -w "%{http_code}\n" https://www.wikipedia.orgcurl -s https://en.wikipedia.org/wiki/Main_Page | grep articlecount | grep 'Special:Statistics'# 清理istioctl delete -f istio/egress-rule-http-bin.yml
istioctl delete -f istio/egress-rule-tcp-wikipedia.yml
kubectl delete -f istio/sleep.yaml

故障管理

  • 调用超时设置和重试设置

  • 故障注入,模拟服务故障

设置超时时间与模拟服务超时故障

# 设置python服务超时时间istioctl create -f istio/route-rule-python-timeout.yml# 模拟go服务超时故障istioctl create -f istio/route-rule-go-delay.yml# 使用浏览器访问并打开调试面板查看网络标签(按F12键)# 多次点击发射按钮观察响应时间# 会看到平均50%的请求会返回504超时# 清除路由规则istioctl delete -f istio/route-rule-python-timeout.yml
istioctl delete -f istio/route-rule-go-delay.yml

webp

超时模拟

设置重试与模拟服务500故障

# 设置python服务超时时间istioctl create -f istio/route-rule-python-retry.yml# 模拟go服务超时故障istioctl create -f istio/route-rule-go-abort.yml# 使用浏览器访问并打开调试面板查看网络标签(按F12键)# 多次点击发射按钮观察响应时间# 会看到部分请求会返回500错误# 清除路由规则istioctl delete -f istio/route-rule-python-retry.yml
istioctl delete -f istio/route-rule-go-abort.yml

webp

模拟服务500故障

超时和服务故障模拟配合使用

# 所有请求延迟5秒钟,然后失败其中的10%...  route:  - labels:      version: v1  httpFault:    delay:      fixedDelay: 5s    abort:      percent: 10      httpStatus: 400

熔断器

# 熔断器规则需要应用到路由规则上# 需要先配置至少一个路由规则# 设置路由规则istioctl create -f istio/route-rule-go-default.yml# 设置熔断规则istioctl create -f istio/route-rule-go-cb.yml# 查看规则istioctl get destinationpolicy# 创建测试用的fortiokubectl apply -f <(istioctl kube-inject --debug -f istio/fortio-deploy.yaml)# 正常访问测试FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -curl http://service-go/env# 测试熔断 2并发kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -c 2 -qps 0 -n 20 -loglevel Warning http://service-go/env# 测试熔断 3并发kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -c 3 -qps 0 -n 20 -loglevel Warning http://service-go/env# 增加并发会看到失败的请求占比增高# 查看状态# upstream_rq_pending_overflow 表示被熔断的请求数kubectl exec -it $FORTIO_POD  -c istio-proxy  -- sh -c 'curl localhost:15000/stats' | grep service-go | grep pending# 清理kubectl delete -f istio/fortio-deploy.yaml
istioctl delete -f istio/route-rule-go-default.yml
istioctl delete -f istio/route-rule-go-cb.yml

限流

动态设置服务qps

# 创建service-python默认路由# 经测试,一定要配置路由规则,否则无法完成限流# 所以极有可能限流是配置在路由规则上的# 在路由时进行限流统计istioctl create -f istio/route-rule-python-default.yml# 配置一个速率限制的memquota适配器# 默认设置500qpsistioctl create -f istio/ratelimit-handler.yaml# 配置速率限制实例和规则istioctl create -f istio/ratelimit-rule-service-go.yaml# 查看kubectl get memquota -n istio-system
kubectl get quota -n istio-system
kubectl get rule -n istio-system
kubectl get quotaspec -n istio-system
kubectl get quotaspecbinding -n istio-system# 创建测试用的fortiokubectl apply -f <(istioctl kube-inject -f istio/fortio-deploy.yaml)# 正常访问测试FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -curl http://service-python/env# 测试# 会出现部分请求不正常# python 返回 code 500# go 返回 code 429kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -qps 20 -n 100 -loglevel Warning http://service-python/env
kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -qps 50 -n 100 -loglevel Warning http://service-go/env# 清理istioctl delete -f istio/route-rule-python-default.yml
istioctl delete -f istio/ratelimit-handler.yaml
istioctl delete -f istio/ratelimit-rule-service-go.yaml
kubectl delete -f istio/fortio-deploy.yaml# 带条件的速率限制apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
 name: quota
 namespace: istio-system
spec:
 match: source.namespace != destination.namespace
 actions:
 - handler: handler.memquota
   instances:
   - requestcount.quota

流量镜像

复制服务的流量到别一个镜像服务,一般用于线上新上服务的测试。

# 创建默认策略# 默认所有流量路由到v1istioctl create -f istio/route-rule-go-default.yml# 创建测试用的fortiokubectl apply -f <(istioctl kube-inject -f istio/fortio-deploy.yaml)# 正常访问测试FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -curl http://service-go/env# 查看v1的日志kubectl logs -f $(kubectl get pods | grep service-go-v1 | awk '{print $1}'| head -n 1) -c service-go

# 查看v2的日志
# 再开一个终端查看日志
kubectl logs -f $(kubectl get pods | grep service-go-v2 | awk '{print $1}'| head -n 1) -c service-go# 创建镜像规则istioctl create -f istio/route-rule-go-mirror.yml# 测试多次访问kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -c 10 -qps 0 -t 10s -loglevel Warning http://service-go/env# 清理kubectl delete -f istio/fortio-deploy.yaml
istioctl delete -f istio/route-rule-go-default.yml
istioctl delete -f istio/route-rule-go-mirror.yml

清理

# 删除相关deploy和svckubectl delete -f service/go/v1/go-v1.yml
kubectl delete -f service/go/v2/go-v2.yml
kubectl delete -f service/python/v1/python-v1.yml
kubectl delete -f service/python/v2/python-v2.yml
kubectl delete -f service/js/v1/js-v1.yml
kubectl delete -f service/js/v2/js-v2.yml
kubectl delete -f service/node/v1/node-v1.yml
kubectl delete -f service/node/v2/node-v2.yml
kubectl delete -f service/lua/v1/lua-v1.yml
kubectl delete -f service/lua/v2/lua-v2.yml# 清除路由规则kubectl delete -f istio/ingress-python.yml
kubectl delete -f istio/ingress-js.yml
istioctl delete routerule $(istioctl get routerule | grep RouteRule | awk '{print $1}



作者:CountingStars_
链接:https://www.jianshu.com/p/fd90d4914505


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消