[单master节点k8s部署]27.Istio流量管理(三)

上面的内容先是部署了istio,后面又部署了bookinfo的微服务,现在来利用istio对bookinfo进行流量治理。 

设置网关

进入/root/istio-1.10.1/samples/bookinfo/networking目录下,运行下面yaml文件,从而进行网关配置:

[root@master networking]# kubectl apply -f bookinfo-gateway.yaml 
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created

确认网关是否创建完成:

[root@master networking]# kubectl get gateway
NAME               AGE
bookinfo-gateway   66m

 yaml文件中有一个gateway,一个virtualService。 Gateway 定义的是进出的端口、协议、主机名等网络层的配置。它不关心请求的具体路径或内容,而是为外部请求打开一个入口。而virtualService用来定义具体的路由规则。

下面的gateway配置中可以看到,hosts为任何主机名,入口为80端口,允许进入的是http请求。

而virtualService中定义了目标端口,为productpage的9080端口,对于进入gateway的http请求,只允许转发匹配到/productpage、/login等的。

[root@master networking]# cat bookinfo-gateway.yaml 
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-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

事实上,当我们查看istio的三个pod,可以发现有一个ingressgateway的pod

[root@master networking]# kubectl get pods -n istio-system
NAME                                    READY   STATUS    RESTARTS   AGE
istio-egressgateway-798787bd74-kj7tr    1/1     Running   0          25h
istio-ingressgateway-5d6489bf96-ps5t5   1/1     Running   0          25h
istiod-7d58bfb8-xtfjd                   1/1     Running   0          25h

 而这个ingressgateway的pod,有以下标签,而我们写的gateway的selector就匹配了其中的标签。

Labels:       app=istio-ingressgateway
              chart=gateways
              heritage=Tiller
              install.operator.istio.io/owning-resource=unknown
              istio=ingressgateway
              istio.io/rev=default
              operator.istio.io/component=IngressGateways
              pod-template-hash=5d6489bf96
              release=istio
              service.istio.io/canonical-name=istio-ingressgateway
              service.istio.io/canonical-revision=latest
              sidecar.istio.io/inject=false

所以,我们写的gateway.yaml实际是指导istio的ingressgateway的pod来如何处理流量,实际当外部客户端发送请求(例如通过 HTTP 或 HTTPS),这些请求会首先到达 istio-ingressgateway Pod。Gateway 资源定义了这个 Pod 应该监听的端口(如 80 或 443),并且可以通过 VirtualService 进一步定义流量的路由规则。

部署bookinfo的微服务成功后,可以看到如下信息:

[root@master ~]# kubectl get virtualservice
NAME       GATEWAYS               HOSTS   AGE
bookinfo   ["bookinfo-gateway"]   ["*"]   47m
[root@master ~]# kubectl get gateway
NAME               AGE
bookinfo-gateway   48m
蓝绿发布/金丝雀发布

上面的virtualservice里面有一个destination的字段,但是实际上为了实现蓝绿发布、金丝雀发布等更加高级的路由规则,可以另写一个destination的yaml文件。上面的virtualService定义的是针对所有host的,如果要针对不同的host,virtualservice需要定义不同的路由规则。假设有两个主机名:

  • myapp.example.com
  • testapp.example.com

其中针对myapp的主机名,进行了金丝雀发布,也就是只有10%的流量去v2版本,大部分都在v1版本处理。而对于testapp的主机名,进行蓝绿发布,也就是说v2是目前的版本,v1不再使用。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: multi-host-virtualservice
spec:
  hosts:
  - myapp.example.com
  - testapp.example.com
  http:
  - match:
    - headers:
        host:
          exact: myapp.example.com
    route:
    - destination:
        host: myapp
        subset: v1
      weight: 90
    - destination:
        host: myapp
        subset: v2
      weight:10
  - match:
    - headers:
        host:
          exact: testapp.example.com
    route:
    - destination:
        host: testapp
        subset: v2
      weight: 100
    - destination:
        host: testapp
        subset: v1
      weight: 0

这里还需要写service定义的destination文件,因为一个destination文件对应一个service,所以这里需要两个destination文件来描述myapp和testapp的配置。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: myapp-destination
spec:
  host: myapp
  subsets:
  - name: v1 
    labels:
      version: v1
  - name: v2
    labels:
      version: v2 
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: testapp-destination
spec:
  host: test
  subsets:
  - name: v1 
    labels:
      version: v1
  - name: v2
    labels:
      version: v2 
流量镜像

流量镜像是一种测试策略,可以在不影响主流量的情况下,将请求副本发送到另一个服务,用于测试或监控。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
  - myapp.example.com
  http:
  - route:
    - destination:
        host: myapp
        subset: v1
  - mirror:
      host: myapp
      subset: v2
    mirrorPercentage:
      value: 100.0
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: myapp
spec:
  host: myapp
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
重试、超时和断路器
apiVersion: networking.iostio.io/v1alpha3
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
  - myapp.example.com
  http:
  - route:
    - destinatioon:
        host: myapp
        subset: v1
    retries:
      attempts: 3     #如果请求失败,最多试三次
      perTryTimeout: 2s     #每次请求的最大超时时间为2s
      retryOn: gateway-error,connection-failure,refused-stream   #重试的条件
   timeout: 5s
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: myapp
spec:
  host: myapp
  trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 100
        maxRequestsPerConnection: 10
    outlierDetection:
      consecutiveErrors: 5
      interval: 1s
      baseEjectionTime: 3m
      maxEjectionPercent: 50

 确定ingress IP和端口

[root@master 34istio]# kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                      AGE
istio-ingressgateway   LoadBalancer   10.105.230.164   <pending>     15021:32087/TCP,80:30636/TCP,443:32496/TCP,31400:32213/TCP,15443:30298/TCP   29h

ingressgateway暴露了以上端口,可以满足流量的监听和转发需求,15021是istio进行健康检查的端口,80是http请求的端口,443是https请求的端口,31400这是 Istio 的一个备用端口,用于 TCP 流量或其他自定义协议的路由。而15443用于处理来自其他网格内服务的**双向 TLS(mTLS)**流量。它用于网格内部的安全通信。这些ingress gateway对内暴露的端口,可以方便gateway监听并转发流量,但是这些端口对外对应的分别是32087,30636,32496,32213等。

尽管15021是用于内部健康检查的端口,但由于 istio-ingressgateway 使用了 LoadBalancer 服务类型,Kubernetes 默认会为每个服务端口(包括健康检查端口)分配一个 NodePort,暴露在物理节点上。

可以看到,目前bookinfo无法从集群外部进行访问,因为istio-ingressgateway 在 Kubernetes 集群内部,它的职责是处理和路由流量,而不是直接将自己暴露给外部网络。Kubernetes LoadBalancer 服务的职责是为服务创建一个外部负载均衡器,并将外部流量通过这个负载均衡器转发到内部的 istio-ingressgateway。这种架构使得 istio-ingressgateway 能够保持为一个内部组件,而由云平台的负载均衡器来处理外部的流量入口。

针对这个问题,我们可以使用本地ip+暴露端口的方式来访问,已知http暴露的80端口映射到外面是30636端口,因此直接访问。根据上面的gateway规则,路径还需要加上productpage。

刷新页面,可以看到 book reviews部分的页面是会变化的,因为reviews有三个版本,且他们的selector都是一样的,所以在没有预设的情况下,istio会以轮询的方式给三个pod分发流量。

review流量转发规则 

我们可以通过为review设置流量转发规则的方式来进行流量控制。已知review本身有一个服务svc,查看这个服务,可以看到selector是app:reviews

[root@master networking]# kubectl get svc reviews -o yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"reviews","service":"reviews"},"name":"reviews","namespace":"default"},"spec":{"ports":[{"name":"http","port":9080}],"selector":{"app":"reviews"}}}
  creationTimestamp: "2024-09-26T06:01:19Z"
  labels:
    app: reviews
    service: reviews
  name: reviews
  namespace: default
  resourceVersion: "8274224"
  selfLink: /api/v1/namespaces/default/services/reviews
  uid: fd3c4f5a-8081-41a9-8e39-1576d33ac078
spec:
  clusterIP: 10.97.52.159
  clusterIPs:
  - 10.97.52.159
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: http
    port: 9080
    protocol: TCP
    targetPort: 9080
  selector:
    app: reviews
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

我们写一个virtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  namespace: default
spec:
  http:
  - route:
    - destination:
        host: reviews
        subset: v2
      weight: 50
    - destination:
        host: reviews
        subset: v3
      weight: 50
  hosts:
  - reviews
  

写一个destinationRule

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews-destination
  namespace: default
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3

就可以实现只展示v2和v3的reviews。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值