Kubernetes使用Istio

1、基本概念

1.1、流量方向

南北流量(NORTH-SOURTH-TRAFFIC):客户端到服务器之间通信的流量

东西流量(EAST-WEST-TRAFFIC):指的是服务器和服务器之间的流量

1.2、Service Mesh

在这里插入图片描述

1.3、术语解释

envoy:网络代理,所有对Pod的流量都须经过envoy这个网络代理

sidecar:对应用中envoy容器的称呼

gateway:网关

  • ingressgateway:入口网关
  • egressgateway:出口网关

virtualservice:虚拟服务,可以想象为一个ingress规则,将符合规则的请求分发至dr(destinationrule)

destinationrule:目标规则,用于对pod进行编组

2、安装Istio

kubernetes与istio版本对应关系:https://istio.io/latest/docs/releases/supported-releases/#support-status-of-istio-releases

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-98cFTNis-1687458259076)(C:\Users\lianxin\AppData\Roaming\Typora\typora-user-images\image-20230618125358118.png)]

2.1、下载

# wget https://github.com/istio/istio/releases/download/1.18.0/istio-1.18.0-linux-amd64.tar.gz
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.18.0 TARGET_ARCH=x86_64 sh -
tar -zxvf istio-1.18.0-linux-amd64.tar.gz
cd istio-1.18.0/
mv bin/istioctl /usr/local/bin/
istioctl version

2.2、安装Istio Operator

istioctl operator init
kubectl get all -n istio-operator
# 有可能镜像下载失败,可使用下面的镜像修改tag
docker pull registry.cn-hangzhou.aliyuncs.com/ialso/istio-operator:1.18.0
docker tag registry.cn-hangzhou.aliyuncs.com/ialso/istio-operator:1.18.0 istio/operator:1.18.0

2.3、安装Istio

官方已经预定义了一些配置文件,这里我们使用minimal
在这里插入图片描述

# 导出minimal配置文件,根据自己的需要修改配置文件
istioctl profile dump minimal > minimal.yaml
istioctl install -y -f istio.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  # 组件镜像的仓库
  hub: docker.io/istio
  profile: minimal
  tag: 1.18.0
  # 自定义Istio组件
  components:
    base:
      enabled: true
    cni:
      enabled: false
    egressGateways:
      - enabled: true
        name: istio-egressgateway
    ingressGateways:
      - enabled: true
        name: istio-ingressgateway
        k8s:
          service:
            type: NodePort
            ports:
              - name: status-port
                port: 15021
                targetPort: 15021
                nodePort: 35021
              - name: http2
                port: 80
                targetPort: 8080
                nodePort: 30080
              - name: https
                port: 443
                targetPort: 8443
                nodePort: 30443
              - name: tcp
                port: 31400
                targetPort: 31400
                nodePort: 31400
              - name: tls
                port: 15443
                targetPort: 15443
                nodePort: 35443
    istiodRemote:
      enabled: false
    pilot:
      enabled: true
  # 网格(数据平面)相关的配置参数
  meshConfig:
    defaultConfig:
      proxyMetadata: {}
    enablePrometheusMerge: true
  # 传递给Chart的各参数值
  values:
    base:
      enableCRDTemplates: false
      validationURL: ""
    defaultRevision: ""
    gateways:
      istio-egressgateway:
        autoscaleEnabled: true
        env: {}
        name: istio-egressgateway
        secretVolumes:
          - mountPath: /etc/istio/egressgateway-certs
            name: egressgateway-certs
            secretName: istio-egressgateway-certs
          - mountPath: /etc/istio/egressgateway-ca-certs
            name: egressgateway-ca-certs
            secretName: istio-egressgateway-ca-certs
        type: ClusterIP
      istio-ingressgateway:
        autoscaleEnabled: true
        env: {}
        name: istio-ingressgateway
        secretVolumes:
          - mountPath: /etc/istio/ingressgateway-certs
            name: ingressgateway-certs
            secretName: istio-ingressgateway-certs
          - mountPath: /etc/istio/ingressgateway-ca-certs
            name: ingressgateway-ca-certs
            secretName: istio-ingressgateway-ca-certs
        type: LoadBalancer
    global:
      configValidation: true
      defaultNodeSelector: {}
      defaultPodDisruptionBudget:
        enabled: true
      defaultResources:
        requests:
          cpu: 10m
      imagePullPolicy: ""
      imagePullSecrets: []
      istioNamespace: istio-system
      istiod:
        enableAnalysis: false
      jwtPolicy: third-party-jwt
      logAsJson: false
      logging:
        level: default:info
      meshNetworks: {}
      mountMtlsCerts: false
      multiCluster:
        clusterName: ""
        enabled: false
      network: ""
      omitSidecarInjectorConfigMap: false
      oneNamespace: false
      operatorManageWebhooks: false
      pilotCertProvider: istiod
      priorityClassName: ""
      proxy:
        autoInject: enabled
        clusterDomain: cluster.local
        componentLogLevel: misc:error
        enableCoreDump: false
        excludeIPRanges: ""
        excludeInboundPorts: ""
        excludeOutboundPorts: ""
        image: proxyv2
        includeIPRanges: '*'
        logLevel: warning
        privileged: false
        readinessFailureThreshold: 30
        readinessInitialDelaySeconds: 1
        readinessPeriodSeconds: 2
        resources:
          limits:
            cpu: 2000m
            memory: 1024Mi
          requests:
            cpu: 100m
            memory: 128Mi
        statusPort: 15020
        tracer: zipkin
      proxy_init:
        image: proxyv2
      sds:
        token:
          aud: istio-ca
      sts:
        servicePort: 0
      tracer:
        datadog: {}
        lightstep: {}
        stackdriver: {}
        zipkin: {}
      useMCP: false
    istiodRemote:
      injectionURL: ""
    pilot:
      autoscaleEnabled: true
      autoscaleMax: 5
      autoscaleMin: 1
      configMap: true
      cpu:
        targetAverageUtilization: 80
      enableProtocolSniffingForInbound: true
      enableProtocolSniffingForOutbound: true
      env: {}
      image: pilot
      keepaliveMaxServerConnectionAge: 30m
      nodeSelector: {}
      podLabels: {}
      replicaCount: 1
      traceSampling: 1
    telemetry:
      enabled: true
      v2:
        enabled: true
        metadataExchange:
          wasmEnabled: false
        prometheus:
          enabled: true
          wasmEnabled: false
        stackdriver:
          configOverride: {}
          enabled: false
          logging: false
          monitoring: false
          topology: false
# 有可能镜像下载失败,可使用下面的镜像修改tag
docker pull registry.cn-hangzhou.aliyuncs.com/ialso/istio-pilot:1.18.0
docker pull registry.cn-hangzhou.aliyuncs.com/ialso/istio-proxyv2:1.18.0
docker tag registry.cn-hangzhou.aliyuncs.com/ialso/istio-pilot:1.18.0 istio/pilot:1.18.0
docker tag registry.cn-hangzhou.aliyuncs.com/ialso/istio-proxyv2:1.18.0 istio/proxyv2:1.18.0
# 验证安装
[root@kubernetes1 ~]# kubectl get po -n istio-system 
NAME                                    READY   STATUS    RESTARTS   AGE
istio-egressgateway-55bf95754-s7mjq     1/1     Running   0          44s
istio-ingressgateway-5576d7f7c4-lv7s4   1/1     Running   0          44s
istiod-5855798659-j848t                 1/1     Running   0          48s
[root@kubernetes1 ~]# istioctl version
client version: 1.18.0
control plane version: 1.18.0
data plane version: 1.18.0 (2 proxies)

3、Bookinfo示例

3.1、准备工作

kubectl create ns istio-demo
# 配置命名空间自动sidecar注入
kubectl label namespace istio-demo istio-injection=enabled

3.2、部署项目

这里使用官方提供的Bookinfo项目,源码地址:https://github.com/istio/istio/tree/master/samples/bookinfo

1、项目介绍
  • roductpage:productpage微服务调用details和reviews微服务来填充页面
  • details:details微服务包含图书信息
  • reviews:reviews微服务包含了书评。它也称为ratings微服务
    • 版本v1不会调用该ratings服务
    • 版本v2调用该ratings服务,并将每个评级显示为1到5个黑色星
    • 版本v3调用该ratings服务,并将每个评级显示为1到5个红星
  • ratings:ratings微服务包含伴随书评书排名信息
    在这里插入图片描述
2、部署
kubectl apply -f bookinfo.yaml --namespace=istio-demo
# samples/bookinfo/platform/kube/bookinfo.yaml
# Copyright Istio Authors
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

##################################################################################################
# This file defines the services, service accounts, and deployments for the Bookinfo sample.
#
# To apply all 4 Bookinfo services, their corresponding service accounts, and deployments:
#
#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
#
# Alternatively, you can deploy any resource separately:
#
#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l service=reviews # reviews Service
#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews # reviews ServiceAccount
#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v3 # reviews-v3 Deployment
##################################################################################################

##################################################################################################
# Details service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
  name: details
  labels:
    app: details
    service: details
spec:
  ports:
    - port: 9080
      name: http
  selector:
    app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookinfo-details
  labels:
    account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: details-v1
  labels:
    app: details
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: details
      version: v1
  template:
    metadata:
      labels:
        app: details
        version: v1
    spec:
      serviceAccountName: bookinfo-details
      containers:
        - name: details
          # 替换镜像
          image: registry.cn-hangzhou.aliyuncs.com/ialso/istio-examples-bookinfo-details-v1:1.17.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9080
          securityContext:
            runAsUser: 1000
---
##################################################################################################
# Ratings service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
  name: ratings
  labels:
    app: ratings
    service: ratings
spec:
  ports:
    - port: 9080
      name: http
  selector:
    app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookinfo-ratings
  labels:
    account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ratings-v1
  labels:
    app: ratings
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ratings
      version: v1
  template:
    metadata:
      labels:
        app: ratings
        version: v1
    spec:
      serviceAccountName: bookinfo-ratings
      containers:
        - name: ratings
          # 替换镜像
          image: registry.cn-hangzhou.aliyuncs.com/ialso/istio-examples-bookinfo-ratings-v1:1.17.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9080
          securityContext:
            runAsUser: 1000
---
##################################################################################################
# Reviews service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
  name: reviews
  labels:
    app: reviews
    service: reviews
spec:
  ports:
    - port: 9080
      name: http
  selector:
    app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookinfo-reviews
  labels:
    account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reviews-v1
  labels:
    app: reviews
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: reviews
      version: v1
  template:
    metadata:
      labels:
        app: reviews
        version: v1
    spec:
      serviceAccountName: bookinfo-reviews
      containers:
        - name: reviews
          # 替换镜像
          image: registry.cn-hangzhou.aliyuncs.com/ialso/istio-examples-bookinfo-reviews-v1:1.17.0
          imagePullPolicy: IfNotPresent
          env:
            - name: LOG_DIR
              value: "/tmp/logs"
          ports:
            - containerPort: 9080
          volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
          securityContext:
            runAsUser: 1000
      volumes:
        - name: wlp-output
          emptyDir: {}
        - name: tmp
          emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reviews-v2
  labels:
    app: reviews
    version: v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: reviews
      version: v2
  template:
    metadata:
      labels:
        app: reviews
        version: v2
    spec:
      serviceAccountName: bookinfo-reviews
      containers:
        - name: reviews
          # 替换镜像
          image: registry.cn-hangzhou.aliyuncs.com/ialso/istio-examples-bookinfo-reviews-v2:1.17.0
          imagePullPolicy: IfNotPresent
          env:
            - name: LOG_DIR
              value: "/tmp/logs"
          ports:
            - containerPort: 9080
          volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
          securityContext:
            runAsUser: 1000
      volumes:
        - name: wlp-output
          emptyDir: {}
        - name: tmp
          emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reviews-v3
  labels:
    app: reviews
    version: v3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: reviews
      version: v3
  template:
    metadata:
      labels:
        app: reviews
        version: v3
    spec:
      serviceAccountName: bookinfo-reviews
      containers:
        - name: reviews
          # 替换镜像
          image: registry.cn-hangzhou.aliyuncs.com/ialso/istio-examples-bookinfo-reviews-v3:1.17.0
          imagePullPolicy: IfNotPresent
          env:
            - name: LOG_DIR
              value: "/tmp/logs"
          ports:
            - containerPort: 9080
          volumeMounts:
            - name: tmp
              mountPath: /tmp
            - name: wlp-output
              mountPath: /opt/ibm/wlp/output
          securityContext:
            runAsUser: 1000
      volumes:
        - name: wlp-output
          emptyDir: {}
        - name: tmp
          emptyDir: {}
---
##################################################################################################
# Productpage services
##################################################################################################
apiVersion: v1
kind: Service
metadata:
  name: productpage
  labels:
    app: productpage
    service: productpage
spec:
  ports:
    - port: 9080
      name: http
  selector:
    app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookinfo-productpage
  labels:
    account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: productpage-v1
  labels:
    app: productpage
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: productpage
      version: v1
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9080"
        prometheus.io/path: "/metrics"
      labels:
        app: productpage
        version: v1
    spec:
      serviceAccountName: bookinfo-productpage
      containers:
        - name: productpage
          # 替换镜像
          image: registry.cn-hangzhou.aliyuncs.com/ialso/istio-examples-bookinfo-productpage-v1:1.17.0
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9080
          volumeMounts:
            - name: tmp
              mountPath: /tmp
          securityContext:
            runAsUser: 1000
      volumes:
        - name: tmp
          emptyDir: {}

3.3、GateWay

# samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
# 类似于Ingress
kind: Gateway
metadata:
  name: bookinfo-gateway
  # 添加命名空间
  namespace: istio-demo
spec:
  selector:
    istio: ingressgateway # 选择携带istio=ingressgateway标签的istio-ingressgateway控制器
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      # 通过任何域名都可以访问
      hosts:
        - "ialso.cn"
        - "*.ialso.cn"
kubectl apply -f gateway.yaml

3.4、VirtualService

现在需要让istio接管路由,比如将所有流量都路由到每个微服务的v1版本,Istio实现起来是非常简单的,只需要添加虚拟服务(VirtualService)即可

# samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
# 类似于Ingress Rule
kind: VirtualService
metadata:
  name: bookinfo
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - "bookinfo.ialso.cn"
  gateways:
    - bookinfo-gateway  # 指定所属Gateway名称
  http:
    - match:
        - uri:
            # 完全匹配
            exact: /productpage
        - uri:
            # 前缀匹配
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
      route:
        - destination:
            host: productpage
            port:
              number: 9080
kubectl apply -f vs.yaml

3.5、DestinationRule

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: productpage	# 将会在对应的svc上的pod的envoy上配置规则
  # 添加命名空间
  namespace: istio-demo
spec:
  host: productpage
  subsets:
    - name: v1
      labels:
        version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
  # 添加命名空间
  namespace: istio-demo
spec:
  host: reviews	# 将会在对应的svc上的pod的envoy上配置规则
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2
    - name: v3
      labels:
        version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ratings	# 将会在对应的svc上的pod的envoy上配置规则
  # 添加命名空间
  namespace: istio-demo
spec:
  host: ratings
  subsets:
    - name: v1
      labels:
        version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: details	# 将会在对应的svc上的pod的envoy上配置规则
  # 添加命名空间
  namespace: istio-demo
spec:
  host: details
  subsets:
    - name: v1
      labels:
        version: v1
kubectl apply -f dr.yaml

reviews有三个版本,在浏览器中访问 Bookinfo 应用程序的 /productpage,发现有时书评的输出包含星级评分,有时则不包含,因为在reviews服务中没有明确的默认服务版本路由
在这里插入图片描述

3.6、配置路由

为解决reviews访问不同版本不受控制,需要让istio接管路由,需要配置VirtualService来接管,同时控制只允许访问v1

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - productpage
  http:
    - route:
      - destination:
          host: productpage
          subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - reviews
  http:
    - route:
      - destination:
          host: reviews
          subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - ratings
  http:
    - route:
      - destination:
          host: ratings
          subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - details
  http:
    - route:
      - destination:
          host: details
          subset: v1

4、流量治理

4.1、灰度发布

配置reviews VirtualService来接管路由,控制只允许访问v1、v2,且比例为8:2

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - reviews
  http:
    - route:
        - destination:
            host: reviews
            # 指定版本
            subset: v1
          # 配置权重
          weight: 80
        - destination:
            host: reviews
            # 指定版本
            subset: v2
          # 配置权重
          weight: 20

4.2、AB测试

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - reviews
  http:
    - match:
        - headers:
        	# 携带指定请求头的才会被转到下方的v3路由
            end-user:
              exact: jason
      route:
        - destination:
            host: reviews
            # 指定版本
            subset: v3
    - route:
        - destination:
            host: reviews
            # 指定版本
            subset: v1
          # 配置权重
          weight: 80
        - destination:
            host: reviews
            # 指定版本
            subset: v2
          # 配置权重
          weight: 20

4.3、重定向

# samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
# 类似于Ingress Rule
kind: VirtualService
metadata:
  name: bookinfo
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - "bookinfo.ialso.cn"
  gateways:
    - bookinfo-gateway  # 指定所属Gateway名称
  http:
    - match:
        - uri:
            # 完全匹配
            exact: /productpage
        - uri:
            # 前缀匹配
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
      route:
        - destination:
            host: productpage
            port:
              number: 9080
    - match:
        - uri:
            # 完全匹配
            exact: /map
      redirect:
        authority: map.baidu.com  # 跳转的域名
        uri: /@13530398,3652997,13z # 跳转的路径

4.4、路径重写

# samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
# 类似于Ingress Rule
kind: VirtualService
metadata:
  name: bookinfo
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - "bookinfo.ialso.cn"
  gateways:
    - bookinfo-gateway  # 指定所属Gateway名称
  http:
    - match:
        - uri:
            # 完全匹配
            exact: /productpage
        - uri:
            # 前缀匹配
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
      route:
        - destination:
            host: productpage
            port:
              number: 9080
    - match:
        - uri:
            # 完全匹配
            exact: /map
      redirect:
        authority: map.baidu.com  # 跳转的域名
        uri: /@13530398,3652997,13z # 跳转的路径
    - match:
        - uri:
            # 完全匹配
            exact: /
      rewrite:
        uri: /productpage # 将/重写为/productpage,访问项目只需https://bookinfo.ialso.cn
      route:
        - destination:
            host: productpage
            port:
              number: 9080

4.5、负载均衡策略

ROUND_ROBIN:轮询

LEAST_CONN:最小连接数

RANDOM:随机

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
  # 添加命名空间
  namespace: istio-demo
spec:
  host: reviews
  trafficPolicy: # 配置路由策略
    loadBalancer: # 配置负载均衡
      simple: RANDOM  # 负载均衡为RANDOM
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2
    - name: v3
      labels:
        version: v3

4.6、并发/链接数限制

部署测试工具

apiVersion: v1
kind: Service
metadata:
  name: fortio
  # 添加命名空间
  namespace: istio-demo
  labels:
    app: fortio
    service: fortio
spec:
  ports:
    - port: 8080
      name: http
  selector:
    app: fortio
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fortio-deploy
  # 添加命名空间
  namespace: istio-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fortio
  template:
    metadata:
      annotations:
        # This annotation causes Envoy to serve cluster.outbound statistics via 15000/stats
        # in addition to the stats normally served by Istio. The Circuit Breaking example task
        # gives an example of inspecting Envoy stats via proxy config.
        proxy.istio.io/config: |-
          proxyStatsMatcher:
            inclusionPrefixes:
            - "cluster.outbound"
            - "cluster_manager"
            - "listener_manager"
            - "server"
            - "cluster.xds-grpc"
      labels:
        app: fortio
    spec:
      containers:
        - name: fortio
          image: fortio/fortio:latest_release
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
              name: http-fortio
            - containerPort: 8079
              name: grpc-ping
kubectl apply -f fortio.yaml
# 获取容器ID
FORTIO_POD=$(kubectl get pod -n bookinfo | grep fortio | awk '{ print $1 }')
# 打印容器ID
echo $FORTIO_POD
# 测试fortio请求
kubectl exec -ti $FORTIO_POD -n istio-demo -- fortio load -curl http://reviews:9080/reviews/0
# 测试fortio并发请求
kubectl exec -ti $FORTIO_POD -n istio-demo -- fortio load -c 2 -n 20 http://reviews:9080/reviews/0|grep "Code"

添加并发/链接数限制

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
  namespace: istio-demo
spec:
  host: reviews
  trafficPolicy: # 配置路由策略
    loadBalancer: # 配置负载均衡
      simple: RANDOM  # 负载均衡为RANDOM
    connectionPool: # 连接池配置
      tcp:
        maxConnections: 3 # 最大并发数
      http:
        http1MaxPendingRequests: 1  # 最大的待处理请求
        maxRequestsPerConnection: 1 # 每个请求最大的链接数
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2
    - name: v3
      labels:
        version: v3
# 再次测试fortio并发请求,此时可以看到出现了503,并发/链接数限制已经生效
kubectl exec -ti $FORTIO_POD -n istio-demo -- fortio load -c 2 -n 20 http://reviews:9080/reviews/0|grep "Code"

4.7、熔断

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
  namespace: istio-demo
spec:
  host: reviews
  trafficPolicy: # 配置路由策略
    loadBalancer: # 配置负载均衡
      simple: RANDOM  # 负载均衡为RANDOM
    connectionPool: # 连接池配置
      tcp:
        maxConnections: 3 # 最大并发数
      http:
        http1MaxPendingRequests: 1  # 最大的待处理请求
        maxRequestsPerConnection: 1 # 每个请求最大的链接数
    outlierDetection: # 熔断配置
      consecutive5xxErrors: 2 # 连续出现的错误超过2次,其余请求会被熔断
      interval: 5s  # 每5秒探测
      baseEjectionTime: 3m  # 熔断时间
      maxEjectionPercent: 50  # 实例熔断最大百分比
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2
    - name: v3
      labels:
        version: v3
# fortio并发请求
kubectl exec -ti $FORTIO_POD -n istio-demo -- fortio load -c 10 -n 50 http://reviews:9080/reviews/0|grep "Code"
# 查看熔断次数(upstream_rq_pending_overflow)
kubectl exec -it $FORTIO_POD -n istio-demo -c istio-proxy -- pilot-agent request GET stats | grep reviews | grep pending_overflow

4.8、延时故障

部署测试工具

# 部署debug-tool
kubectl run -it -n istio-demo debug-tool --image=registry.cn-hangzhou.aliyuncs.com/ialso/debug-tools
# 使用debug-tool
kubectl attach debug-tool -n istio-demo -c debug-tool -it
# 测试响应速率
time curl -I -s reviews:9080

添加故障注入

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - reviews
  http:
    - fault: # 添加错误
        delay: # 添加delay的故障
          percentage: # 故障注入的百分比
            value: 100
          fixedDelay: 2s  # 注入的延迟时间
      route:
        - destination:
            host: reviews
            # 指定版本
            subset: v3
# 再次测试相应速率,即可看到5s后才响应
time curl -I -s reviews:9080

4.9、中断故障

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - reviews
  http:
    - fault: # 添加错误
        abort: # 添加中断故障
          percentage: # 故障注入的百分比
            value: 100
          httpStatus: 400  # 故障状态码
      route:
        - destination:
            host: reviews
            # 指定版本
            subset: v2
# 再次测试相应速率,即可看到响应400
time curl -I -s reviews:9080

4.10、服务降级

productpage调用reviews,因此服务降级应在productpage上配置

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
  namespace: istio-demo
spec:
  hosts:
    - productpage
  http:
    - route:
        - destination:
            host: productpage
            subset: v1
      timeout: 0.5s
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  # 添加命名空间
  namespace: istio-demo
spec:
  hosts:
    - reviews
  http:
    - fault: # 添加错误
        delay: # 添加delay的故障
          percentage: # 故障注入的百分比
            value: 100
          fixedDelay: 2s  # 注入的延迟时间
      route:
        - destination:
            host: reviews
            # 指定版本
            subset: v3
Logo

更多推荐