idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

摘要
使用 Istio 可以很方便地实现微服务间的访问控制。本文演示了使用 Denier 适配器实现拒绝访问,和 Listchecker 适配器实现黑白名单两种方法。

使用场景

有时需要对微服务间的相互访问进行控制,比如使满足某些条件(比如版本)的微服务能够(或不能)调用特定的微服务。

访问控制属于策略范畴,在 Istio 中由 Mixer 组件实现。

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

Mixer拓扑图,来源官方文档

如上图所示,服务的外部请求会被 Envoy 拦截,每个经过 Envoy 的请求都会调用 Mixer,为 Mixer 提供一组描述请求和请求周围环境的属性。Mixer 进行前置条件检查和配额检查,调用相应的 adapter 做处理,并返回相应结果。Envoy分析结果,决定是否执行请求或拒绝请求。从而实现了策略控制。

环境准备

在 Kubernetes 集群上部署 Istio

部署 Bookinfo 示例应用

配置 Bookinfo 应用各个微服务的 destinationrule 和 virtualservice。其中 reviews 服务的 destinationrule 和 virtualservice 配置如下:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

按上图配置后,对于 reviews 服务的请求,来自用户 “kokokobe” 的请求会被路由到v2 版本,其他用户的请求会被路由到 v3 版本。

使用 Denier 适配器实现简单的访问控制

使用 Istio 对微服务进行访问控制时,可以使用 Mixer 中的任何属性。这是一种简单的访问控制,实现基础是通过 Mixer 选择器拒绝某些条件下的请求。

比如,上文所述的 Bookinfo 应用中的 ratings 服务会被多个版本的 reviews 服务访问。下面的示例中我们将会切断来自 v3 版本的 reviews 服务对 ratings 服务的调用。

  1. 用浏览器打开 Bookinfo 的 productpage(http://$GATEWAY_URL/productpage

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

如上图所示,如果用 “kokokobe” 的用户登录,能看到每条 review 下面的黑色星星,说明此时 ratings 服务被 v2 版本的 reviews 服务调用。

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

从上面两张图可以看出,如果使用其他用户登录(或未登录),能看到每条 review 下面的红色星星,说明此时 ratings 服务被 v3 版本的 reviews 服务调用。

  1. 创建 denier 适配器,拒绝来自 v3 版本的 reviews 服务对 ratings 服务的调用

编辑 mixer-rule-deny-label.yaml 内容如下:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

这也是Mixer的adapter的标准配置格式,一般需要配置三种类型的资源:

  1. 配置一组 handler。Handler是配置好的 adapter 的实例,adapter 封装了 Mixer 和特定基础设施后端之间的接口。

  2. 基于 template 配置一组 instance。Instance 定义了如何将 Envoy 提供的请求属性映射到 adapter 的输入。

  3. 配置一组规则。这些规则描述了何时调用特定的 handler 及 instance。

在这里其中定义了一条名为 denyreviewsv3 的规则,一个 denier 类型的 handler,一个checknothing 类型的模板的实例。

在 denyreviewsv3 规则中,方框内的条件表达式匹配的条件是:来自 reviews 服务,version 为 v3 ,目标为 ratings 服务的请求。这条规则使用 denier 适配器拒绝来自 v3 版本的 reviews 服务的请求。

这个 denier 适配器会拒绝符合上述规则的请求。可以预先指定 denier 适配器的状态码和消息,如方框中所示。

然后执行如下命令创建上述规则的 denier 适配器:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

  1. 在浏览器中刷新 productpage 页面

如果已经登出或者使用不是 “kokokobe” 的用户身份登录,不再看到红色星星,因为v3版本的 reviews 服务对 ratings 服务的访问已经被拒绝了。

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

相反,如果使用 “kokokobe” 用户登录,仍然能够看到黑色星星。因为该用户使用的是 v2 版本的 reviews 服务,不符合拒绝的条件。

通过listchecker适配器实现黑白名单

Istio 也支持基于属性的黑名单和白名单。下面的白名单配置和上一节的 denier 配置是等价的,拒绝来自 v3 版本的 reviews 服务的请求。

  1. 删除上一节配置的 denier 规则

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

  1. 在登出状态下浏览 Bookinfo 的 productpage(http://$GATEWAY_URL/productpage

此时能看到红星图标。在完成下述步骤之后,只有在使用 “kokokobe” 的身份登录之后才能看到星形图标。

  1. 创建包含 v2 版本白名单的 listchecker 适配器

编辑 whitelist-handler.yaml 内容如下:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

通常会在外部维护黑白名单的列表,然后指定 providerUrl 参数进行异步获取。在这个例子中,我们使用 overrides 字段提供一个静态的黑白名单列表。

然后运行如下命令创建 listchecker 适配器:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

  1. 创建一个 listentry 模板的实例

Listentry 模板可以用来判别一个字符串是否存在于一个列表中,本例中我们使用它来判别版本标签是否存在于白名单中。

编辑 appversion-instance.yaml 内容如下:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

然后运行如下命令:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

  1. 为 ratings 服务启用 whitelist 检查功能

编辑 checkversion-rule.yaml 内容如下:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

然后运行如下命令:

idou老师教你学Istio 16:如何用 Istio 实现微服务间的访问控制

  1. 在浏览器中刷新 productpage 页面

如果已经登出或者使用不是 “kokokobe” 的用户身份登录,看不到星形图标;如果使用 “kokokobe” 用户登录,仍然能够看到黑色星星。

总结

通过上述示例,可以发现使用 Istio 实现微服务间的访问控制非常方便。既可以使用denier 适配器实现简单的访问控制,也可以通过listchecker 适配器实现较复杂的黑白名单。

相关服务请访问https://support.huaweicloud.com/cce/index.html?cce_helpcenter_2019

猜你喜欢

转载自blog.51cto.com/14051317/2348359