作为业内首个全托管Istio兼容的阿里云服务网格产品ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。ASM产品是基于社区Istio定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了Istio组件与所管理的K8s集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。从2022年4月1日起,阿里云服务网格ASM正式推出商业化版本, 提供了更丰富的能力、更大的规模支持及更完善的技术保障,更好地满足客户的不同需求场景,详情可进入阿里云官方网站 - 搜索服务网格ASM。
背景故事
多集群环境下的服务网格
作为一种常见的备用和容灾手段,多集群环境往往成为很多业务在生产部署时采用的常用选项。其原理也很简单,只要在不同的可用区/地域下部署服务,就能在很大程度上避免因可用区/地域不可用造成的流量损失。
在多集群环境之中,“集群内流量保持”是一个自然而然的行为。所谓“集群内流量保持”,就是指在多集群环境下,在集群内的服务相互请求时,流量的上游服务和下游服务的端点都一定位于同一个集群之内。比如,设sleep服务与httpbin服务存在依赖关系(sleep服务会调用httpbin服务),若集群1和集群2中有同样的命名空间、部署了同样名为httpbin和sleep的服务,则集群1中的sleep服务对httpbin服务发起调用、只会请求到集群1中httpbin服务的端点,同理,这个结论对集群2中的服务也是成立的。对于每个Kubernetes集群中,集群内流量保持是当然的,因为每个集群的服务发现都只会发现自己集群内的服务端点,在通过Kubernetes Service发送流量时,对应流量的目的地当然也就不可能是另一个集群中的服务端点。
阿里云服务网格ASM提供了开箱即用的多集群管理机制,只要保证集群的网络配置不互相冲突,就可以将多个数据面集群统一纳管至同一个ASM控制面实例之下。将多个集群用统一的服务网格控制面管理的优势是显而易见的:用户在控制面配置的一份规则,会被同时下发到多集群中的Sidecar代理之中;换言之,用户只需要编写一份配置,就可以对多个集群下的流量规则进行统一管理,减少对多个集群进行统一管理的心智负担。
为什么要使用“集群内流量保持”?
如前所述,“集群内流量保持”应该是一个自然而然的行为,为什么要在这里提出“集群内流量保持”这个奇怪的用例呢?在Kubernetes集群中,集群内流量保持当然是自然而然的,因为每个集群的服务发现都只会发现自己集群内的服务端点。但当多个集群的流量被同一个服务网格进行统一纳管时,这个情况就发生了变化。
对于服务网格来说,业务应用的流量将被部署在每个业务容器旁边的Sidecar进行代理,而每个Sidecar代理内部都保存了每个服务的端点信息(对于envoy来说,就是每个cluster的endpoint信息),这些端点信息是由服务网格控制面进行统一维护的。
对于服务网格来说,其没有自己的服务发现系统,而是通过对接数据面的服务发现来获取服务发现信息。在多集群统一纳管的环境下,服务网格控制面将同时接受所有数据面集群中的服务发现信息。此时就产生了一个现象:若两个集群中,同一命名空间下配置了名称完全相同的Service,这两个Service会被服务网格解释为同一个服务在两个集群下的不同端点。对于用户来说,最直观的感受就是“集群内流量保持”失效了。
如,设sleep服务与httpbin服务存在依赖关系(sleep服务会调用httpbin服务),若集群1和集群2中有同样的命名空间、部署了同样名为httpbin和sleep的服务,则集群1中的sleep服务对httpbin服务发起调用,默认将会轮询集群1与集群2中httpbin服务的服务端点,集群1与集群2中的服务端点都会无差别收到请求。这个能力在一定程度上提高了被服务网格纳管的数据面集群的可用性(若一个集群中的某个服务挂掉了,依赖它的其他服务可以选择调用另一个集群中的服务端点),但其的确改变了Kubernetes集群中调用流量的默认行为,并且跨集群的服务调用将会导致可预期的延迟增加。
服务网格ASM在1.15版本提供了“集群内流量保持”的能力,用户可以配置一系列的服务名(或者直接配置“*”来代表所有服务都配置流量保持),配置之后,当请求指定的服务时,服务网格将保证流量只会发送到本集群中的服务端点。根据用户的具体需求,可以灵活针对具体服务来配置“集群内流量保持”,充分利用服务网格的多集群流量纳管能力。
前提条件
- 在同一VPC下创建两个ACK集群(本例中m1c1和m1c2),详情请参见创建Kubernetes专有版集群。
- 创建一个ASM实例(本例中mesh1),详情请参见创建ASM实例。
准备工作
步骤一:配置集群的互访联通性
修改集群的安全组名称
将两个集群对应的安全组名称修改为易于辨识的名称,本例中为m1c1-sg和m1c2-sg。
- 登录ECS管理控制台。
- 在左侧导航栏,选择网络与安全>安全组。
- 在顶部菜单栏左上角处,选择地域。
- 在安全组列表页面中,找到需要修改的安全组,单击操作列下的修改。
- 在弹出的对话框中,修改安全组名称和描述。
- 单击确定。
修改后的名称,如下图所示。
添加安全组访问规则
为了使两个集群能够互相访问,需要为彼此添加安全组访问规则。
- 在m1c1-sg安全组配置界面,添加以m1c2-sg为授权对象的访问规则。详情请参见添加安全组规则。
- 在m1c2-sg安全组规则配置界面,添加以m1c1-sg为授权对象的访问规则。
步骤二:添加集群到ASM实例并部署集群的入口网关
将两个集群添加到ASM实例后,由于两个集群已实现访问互通,因此只需为一个集群部署入口网关。
- 将两个集群添加到ASM实例,详情请参见添加集群到ASM实例。
- 为m1c1集群部署入口网关,详情请参见添加入口网关服务。
步骤三:在两个集群中分别部署Bookinfo应用
为了演示ASM流量保持能力,需要在两个集群中分别部署Bookinfo应用。两个集群中服务的区别在于在m1c1中reviews组件为v1版本,在m1c2中为v2版本,其他保持一致。
- 在m1c1中部署包含v1版本的reviews Deployment的Bookinfo应用bookinfo-with-reviews-v1.yaml,详情请参见部署应用到ASM实例。
说明:v1版本的reviews Deployment在最终页面的书评部分将不展示星型评分
- 在m1c2中部署包含v2版本的reviews Deployment的Bookinfo应用bookinfo-with-reviews-v2.yaml,具体方法同上。
说明:v2版本的reviews Deployment在最终页面的书评部分将以黑白五角星的形式展示评分
步骤四:添加网关规则、虚拟服务和目标规则
- 在ASM实例的default命名空间下创建如下网格规则,详情参见https://help.aliyun.com/document_detail/150504.html
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:
- "*"
- 在ASM实例的default命名空间下创建如下虚拟服务,详情参见https://help.aliyun.com/document_detail/150502.html
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-cluster-local
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage1
rewrite:
uri: /productpage
route:
- destination:
host: productpage
port:
number: 9080
subset: m1c1
- match:
- uri:
exact: /productpage2
rewrite:
uri: /productpage
route:
- destination:
host: productpage
port:
number: 9080
subset: m1c2
- match:
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
- 在ASM实例的default命名空间下创建如下目标规则,详情参见https://help.aliyun.com/document_detail/150503.html
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: productpage-cluster-local
spec:
host: productpage
subsets:
- name: m1c1
labels:
cluster: m1c1
- name: m1c2
labels:
cluster: m1c2
- 访问productpage页面。在ASM服务网格控制台查看网关入口网关ip,具体操作可以参考https://help.aliyun.com/document_detail/150510.html ,在浏览器中访问
http://{入口网关ip}/productpage1
或http://{入口网关ip}/productpage2
,可以看到如下页面切刷新后书评区域的星型评分交替出现,说明Bookinfo应用部署成功。
为Reviews服务开启流量保持功能
在Bookinfo应用中,productpage组件会去调用reviews服务以获取书评信息。通过准备工作中的设置,当我们访问http://{入口网关ip}/productpage1
时会访问访问m1c1集群中的productpage;访问http://{入口网关ip}/productpage2
时会访问m1c2集群中的productpage。由于在m1c1和m1c2两个集群中都存在reviews服务的工作负载,默认情况下,即使我们访问的是某个特定集群如m1c1集群中的productpage,对reviews服务的请求也会在两个集群之间负载均衡,所以我们可以在productpage页面的书评区域交替看到星型评分信息。
使用ASM服务网格的流量保持功能可以将请求Reviews服务的流量保持在本集群。
- 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择网格实例 > 基本信息页面
- 在右侧界面中配置信息部分,找到并点击集群内流量保持选项右侧的编辑按钮
- 打开“开启保持集群内流量的能力”开关,选择生效范围为部分服务生效,然后点击选择服务按钮
- 点击服务选项卡,选择default命名空间后,在左侧待选框中选中reviews服务,点击>按钮移动到右侧已选择框内,最后点击右下角的确定
- 点击确定
- 等待配置生效后,在浏览器中访问
http://{入口网关ip}/productpage1
并刷新,将始终只能看到不包含评分的页面 - 同样的,在浏览器中访问
http://{入口网关ip}/productpage2
并刷新,将始终只能看到包含黑白星型评分的页面
开启了流量保持功能后,网格中流量的调用链路示意图如下:
注意:流量保持功能开启后,如果m1c1集群中的reviews-v1因故障等原因下线,productpage无法通过访问m1c2集群中的reviews-v2来提供服务。