您的位置:首页 > 其它

IBM Kubernetes Service - 玩转Istio 1.5(三)

2020-07-13 04:39 344 查看

今天我们延续玩转Istio 1.5前两篇文章,开始利用Istio来实现A/B测试,以及金丝雀发布。Istio 1.5开始,Pilot作为独立组件的所有功能都纳入到istiod,所以在1.5以及之后的版本用于流量管理的核心组件就是istiod,它管理和配置部署在特定Istio服务网格中的所有Envoy Proxy实例。它允许用户指定规则来在Envoy Proxy之间路由流量,这些代理作为Sidecar运行到网格中的每个服务。每个服务由运行在pods、容器、vm等上的任意数量的实例组成。每个服务可以有任意数量的版本(即服务子集)。可以有不同的服务实例的子集运行应用程序二进制文件的不同变形。这些变形可以是不同的API版本,也可以是对相同服务的迭代更改,部署在不同的环境中(prod、staging、dev等)。istiod将高级规则转换为低级配置,并将此配置分发给Envoy实例。

istiod使用三种类型的配置资源来管理其服务网格中的流量: 虚拟服务(Virtual Services)、目标规则(Destination Rules)和服务条目(Service Entries)

虚拟服务定义了一组在寻址主机时应用的流量路由规则。每个路由规则为特定协议的流量定义匹配标准。如果流量匹配,则将其发送到服务注册中心中定义的指定目标服务(或其子集或版本)。

目标规则定义了在发生路由后应用于服务的流量的策略。这些策略指定负载均衡的配置、sidecar中的连接池大小以及用于从负载均衡池中检测和驱逐不健康主机的离群点检测设置。在虚拟服务规则中引用的任何目标主机和子集都必须在相应的目标规则中定义,并应用于流量的“真实”目标地址。

服务条目可以将条目添加到 Istio  内部维护的服务注册表中。添加服务条目后,Envoy  代理可以将流量发送到该服务,就好像该服务条目是网格中的服务一样。通过配置服务条目,可以管理在网格外部运行的服务的流量。

如果之前的IBM Kubernetes和应用的环境还在,那就非常方便了,如果没有,请先参考前两篇文章安装IKS及其组件istio 1.5,启用Kiali,安装Guestbook v1和v2

https://blog.csdn.net/ox821110/article/details/106997407

https://blog.csdn.net/ox821110/article/details/107005109

 

我们要先下载练习的资料:git clone https://github.com/IBM/istio101.git

默认情况下,部署在服务网格上的组件不会在集群外部公开,通过在每个服务上创建外部负载均衡器或nodeport来提供对单个服务的外部访问。

把Guestbook应用程序服务暴露给Istio Ingress Gateway

首先要么要先设置下IKS集群的上下文配置。

 

然后进入目录istio101/workshop/plans:cd istio101/workshop/plans/,并执行:

kubectl create -f guestbook-gateway.yaml

创建后我们获取一下外部IP(EXTERNAL-IP),以便后续使用:kubectl get service istio-ingressgateway -n istio-system

获取后EXTERNAL-IP可以先生成环境变量:

export INGRESS_IP=Your EXTERNAL-IP

export MYCLUSTER=Your Cluster Name

连接Istio Ingress Gateway到IKS Network Load Balancer(NLB) 

NLB主机名是一个DNS Hostname,每个公开Network Load Balancer(NLB)服务的IKS都能够生成NLB,这些主机名附带SSL证书、DNS注册和健康检查,因此可以在IBM Cloud Kubernetes集群中并行运行IKS ALB、API Gateway、Istio Ingress Gateway和MQTT服务器。每个服务都有各自:公开可用的通配符主机名、与主机名关联的通配符SSL证书以及配置独立的监控检查。

首先使用Istio Ingress Gateway的外部IP,创建NLB Hostname:

ibmcloud ks nlb-dns create classic --cluster $MYCLUSTER --ip $INGRESS_IP

然后查看集群的NLB: ibmcloud ks nlb-dnss --cluster $MYCLUSTER

请注意以0001结尾的NLB主机名,因为它将在后面的部分用于访问应用程序,所以为它创建一个环境变量方便之后测试。

export NLB_HOSTNAME=mycluster-231123-0497ca13c6f79a7ecfaf9c5ba71b44fa-0001.us-south.containers.appdomain.cloud

接着我们启用新创建的NLB的监控检查,执行下面的命令开启,之后就能查到NLB的已启用监控检查。

ibmcloud ks nlb-dns monitor configure --cluster $MYCLUSTER --nlb-host $NLB_HOSTNAME --type HTTP --description "Istio ingress gateway health check" --path "/healthz/ready" --port 15020 --enable

在Guestbook应用程序中,建有一个服务: guestbook。guestbook服务对应两个不同的版本:基本版本(版本1)和现代化版本(版本2),每个版本都有3个副本(replicaset)。默认情况下,在创建任何规则之前,Istio将以轮询的方式在版本1和版本2的guestbook服务及其各自实例之间平均路由请求,这对新版本发布而言非常不可取,因为新版本自身的bug很容易在微服务架构的服务网络中引入风险,因此遵循A/B测试和金丝雀部署是一种很好的做法。

下面我们利用Istio实现A/B测试。A/B测试是对两个独立的服务版本执行相同测试的一种方法,以确定哪个执行得更好。
为了防止Istio在原始的和现代化的留言本服务之间执行默认的路由行为。我们先观察下guestbook-destination.yaml和virtualservice-all-v1.yaml这两个文件。

[code]apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: destination-rule-guestbook
spec:
host: guestbook
subsets:
- name: v1
labels:
version: '1.0'
- name: v2
labels:
version: '2.0'
[code]apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-service-guestbook
spec:
hosts:
- '*'
gateways:
- guestbook-gateway
http:
- route:
- destination:
host: guestbook
subset: v1

VirtualService定义了一个规则,该规则捕获所有通过istio ingress gateway、guestbook-gateway进入的HTTP流量,并将100%的流量路由到标签为“version: v1”的guestbook服务的pods上。路由目的地的子集或版本通过对指定服务子集的引用来标识,必须在相应的DestinationRule中声明该命名服务子集。由于有三个实例匹配host:guestbook和subset:v1的条件,缺省情况下Envoy将以循环的方式向这三个实例发送流量。

观察完后,我们回到/istio101/workshop/plans目录,创建DestinationRule和VirtualService。

kubectl create -f guestbook-destination.yaml
kubectl replace -f virtualservice-all-v1.yaml

然后echo $NLB_HOSTNAME,用输出的地址在浏览器里访问guestbook服务。此时我们发现VirtualService的规则生效了,只能访问到Guestbook v1。

进行A/B测试,需要修改下路由规则,我们观察一下virtualservice-test.yaml。

[code]apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-service-guestbook
spec:
hosts:
- '*'
gateways:
- guestbook-gateway
http:
- match:
- headers:
user-agent:
regex: '.*Firefox.*'
route:
- destination:
host: guestbook
subset: v2
- route:
- destination:
host: guestbook
subset: v1

在VirtualService规则中,每个服务只能有一个规则(rule),因此在定义多个HTTPRoute块时,它们在yaml中定义的顺序很重要。因此,将修改原来的VirtualService规则,而不是创建新规则。修改后的规则是:来自Firefox浏览器的请求将转到Guestbook v2版本。其他所有的请求都被传送到下一条route块,所有流量传送到原来v1版本上。

观察完后,我们执行一下:kubectl replace -f virtualservice-test.yaml

接下来就要准备两个浏览器,当然必须有一个是Firefox,浏览器访问一下NLB域名。

    

现在我们开始做金丝雀发布的练习。在金丝雀发布中,新版本的服务将逐步向用户推出,以最小化新版本上线带来的任何错误的风险。要开始逐步路由流量到更新版本的Guestbook服务,可以修改之前的VirtualService规则。

首先也是先观察一下virtualservice-80-20.yaml

[code]apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-service-guestbook
spec:
hosts:
- '*'
gateways:
- guestbook-gateway
http:
- route:
- destination:
host: guestbook
subset: v1
weight: 80
- destination:
host: guestbook
subset: v2
weight: 20

在修改后的规则中,路由流量被分割为Guestbook服务的两个不同子集。通过这种方式,新版本v2的访问量被控制在一个较小的百分比的基础上,以限制任何不可预见的错误的影响。此规则可以随着时间的推移进行修改,逐步把v1的流量调整到v2,一直到最终所有流量都被定向到服务的新版本。

然后我执行一下更新:kubectl replace -f virtualservice-80-20.yaml

完成后继续用浏览器访问,可以使用硬刷新(Mac上使用command + Shift + R, windows上使用Ctrl + F5)。应该注意到Guestbook应该按照指定的权重在V1或V2之间进行交换。

当然为了确保流量按照设定规则转发,我们可以通过Kiali查看,在下图中,我们可以清晰的看到将近80%的流量到v1,20%的流量到了v2

最后一步我们修改VirtualService规则将所有流量路由到Guestbook v2。

[code]cat <<EOF | kubectl replace -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-service-guestbook
spec:
hosts:
- '*'
gateways:
- guestbook-gateway
http:
- route:
- destination:
host: guestbook
subset: v2
EOF

我们还是通过浏览器访问服务,然后再次进入Kiali查看,流量已经100%路由到了v2版本了。完美!

好了,今天的Istio进行A/B测试以及金丝雀发布就介绍到这里。

本次的IBM Kubernetes Service - 玩转Istio 1.5就告一段落了,相信大家还意犹未尽。IBM Cloud我会持续关注,之后还会带来更多的Kubernetes主题给小伙伴们。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: