以 Spring Cloud 与 Dubbo 为代表的微服务开发框架非常普及。基于这些传统微服务框架构建的应用系统在享受其优势的同时,痛点也越加明显。

包括但不限于:

  • 侵入性强
    • 想要集成 SDK 的能力,要添加相关依赖,还要在业务代码中增加代码、或注解、或配置;业务代码与治理层代码界限不清晰。
  • 升级成本高
    • 每次升级都需要业务应用修改 SDK 版本,重新进行功能回归测试,对于业务方来说,与业务的快速迭代开发是有冲突的,大多不愿意停下来做这些与业务目标不太相关的事情
  • 版本碎片化严重
    • 由于升级成本高,而中间件却不会停止向前发展的步伐,久而久之,会导致线上不同服务引用的 SDK 版本不统一、能力参差不齐,造成很难统一治理。
  • 中间件演变困难
    • 由于版本碎片化严重,导致中间件向前演进的过程中就需要在代码中兼容老版本逻辑,带着 “枷锁” 前行,无法实现快速迭代。
  • 内容多、门槛高
    • Spring Cloud 被称为微服务治理的全家桶,包含大大小小几十个组件,内容相当之多,需要较长时间去熟悉关键组件。而要使用 Spring Cloud 作为完整的治理框架,则需要深入了解原理与实现,否则遇到问题很难定位。
  • 治理功能不全
    • 不同于 RPC 框架,Spring Cloud 作为治理全家桶的典型,也不是万能的,如协议转换支持、多重授权机制、动态请求路由、故障注入、灰度发布等高级功能并没有覆盖到。这些功能往往是企业大规模落地不可获缺的功能。

安装

参考:https://istio.io/latest/docs/setup/getting-started/

文章基于1.7.3版本进行说明!

wget https://github.com/istio/istio/releases/download/1.7.3/istio-1.7.3-linux-amd64.tar.gz
tar zxf istio-1.7.3-linux-amd64.tar.gz
cd istio-1.7.3
cp bin/istioctl /bin/

实现istio命令tab自动补全
cat tools/istioctl.bash >> /root/.bash
source /root/.bashrc

$ istioctl install —set profile=demo
$ kubectl -n istio-system get po

istio针对不同的环境,提供了几种不同的初始化部署组件
# 查看提供的profile类型
$ istioctl profile list
# 获取kubernetes的yaml:
$ istioctl manifest generate —set profile=demo > istio-kubernetes-manifest.yaml

卸载
$ istioctl manifest generate —set profile=demo | kubectl delete -f -

快速入门

场景一

模型图
image.png
#资源清单
front-tomcat-dpl-v1.yaml

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: front-tomcat
  6. version: v1
  7. name: front-tomcat-v1
  8. namespace: istio-demo
  9. spec:
  10. replicas: 1
  11. selector:
  12. matchLabels:
  13. app: front-tomcat
  14. version: v1
  15. template:
  16. metadata:
  17. labels:
  18. app: front-tomcat
  19. version: v1
  20. spec:
  21. containers:
  22. - image: consol/tomcat-7.0:latest
  23. name: front-tomcat

bill-service-dpl-v1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    service: bill-service
    version: v1
  name: bill-service-v1
  namespace: istio-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      service: bill-service
      version: v1
  template:
    metadata:
      labels:
        service: bill-service
        version: v1
    spec:
      containers:
      - image: nginx:alpine
        name: bill-service
        command: ["/bin/sh", "-c", "echo 'this is bill-service-v1'>/usr/share/nginx/html/index.html;nginx -g 'daemon off;'"]

bill-service-svc.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    service: bill-service
  name: bill-service
  namespace: istio-demo
spec:
  ports:
  - name: http
    port: 9999
    protocol: TCP
    targetPort: 80
  selector:
    service: bill-service
  type: ClusterIP

操作
$ kubectl create namespace istio-demo
$ kubectl apply -f front-tomcat-dpl-v1.yaml
$ kubectl apply -f bill-service-dpl-v1.yaml
$ kubectl apply -f bill-service-svc.yaml
$ kubectl -n istio-demo exec front-tomcat-v1-548b46d488-r7wv8 — curl -s bill-service:9999
this is bill-service-v1

场景二

模型图
image.png

资源清单
bill-service-dpl-v2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    service: bill-service
    version: v2
  name: bill-service-v2
  namespace: istio-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      service: bill-service
      version: v2
  template:
    metadata:
      labels:
        service: bill-service
        version: v2
    spec:
      containers:
      - image: nginx:alpine
        name: bill-service
        command: ["/bin/sh", "-c", "echo 'hello, this is bill-service-v2'>/usr/share/nginx/html/index.html;nginx -g 'daemon off;'"]

操作
$ kubectl apply -f bill-service-dpl-v2.yaml
$ kubectl -n istio-demo exec front-tomcat-v1-548b46d488-r7wv8 — curl -s bill-service:9999

说明
此时,访问规则会按照v1和v2的pod各50%的流量分配。

需求
后台账单服务更新v2版本,前期规划90%的流量访问v1版本,导入10%的流量到v2版本

模型图
image.png

使用Istio注入
$ istioctl kube-inject -f bill-service-dpl-v1.yaml|kubectl apply -f -
$ istioctl kube-inject -f bill-service-dpl-v2.yaml|kubectl apply -f -
$ istioctl kube-inject -f front-tomcat-dpl-v1.yaml|kubectl apply -f -

引入两个新的资源类型:VirtualServiceDestinationRule
若想实现上述需求,需要解决如下两个问题:
- 让访问账单服务的流量按照我们期望的比例,其实是一条路由规则,如何定义这个规则
- 如何区分两个版本的服务

bill-service-destnation-rule.yaml

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: dest-bill-service
  namespace: istio-demo
spec:
  host: bill-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

bill-service-virtualservice.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-bill-service
  namespace: istio-demo
spec:
  hosts:
  - bill-service
  http:
  - name: bill-service-route
    route:
    - destination:
        host: bill-service
        subset: v1
      weight: 90
    - destination:
        host: bill-service
        subset: v2
      weight: 10

使用client验证流量分配是否生效
$ kubectl apply -f bill-service-virtualservice.yaml
$ kubectl apply -f bill-service-destnation-rule.yaml
$ kubectl -n istio-demo exec front-tomcat-v1-78cf497978-ltxpf -c front-tomcat — curl -s bill-service

结果
从front-tomcat中访问nginx的svc,能够出现9:1的流量分发效果。