摘要
使用 Istio 可以很方便地实现微服务间的访问控制。本文演示了使用 Denier 适配器实现拒绝访问,和 Listchecker 适配器实现黑白名单两种方法。
使用场景
有时需要对微服务间的相互访问进行控制,比如使满足某些条件(比如版本)的微服务能够(或不能)调用特定的微服务。
访问控制属于策略范畴,在 Istio 中由 Mixer 组件实现。
Mixer拓扑图,来源官方文档
如上图所示,服务的外部请求会被 Envoy 拦截,每个经过 Envoy 的请求都会调用 Mixer,为 Mixer 提供一组描述请求和请求周围环境的属性。Mixer 进行前置条件检查和配额检查,调用相应的 adapter 做处理,并返回相应结果。Envoy分析结果,决定是否执行请求或拒绝请求。从而实现了策略控制。
环境准备
在 Kubernetes 集群上部署 Istio
部署 Bookinfo 示例应用
配置 Bookinfo 应用各个微服务的 destinationrule 和 virtualservice。其中 reviews 服务的 destinationrule 和 virtualservice 配置如下:
按上图配置后,对于 reviews 服务的请求,来自用户 “kokokobe” 的请求会被路由到v2 版本,其他用户的请求会被路由到 v3 版本。
使用 Denier 适配器实现简单的访问控制
使用 Istio 对微服务进行访问控制时,可以使用 Mixer 中的任何属性。这是一种简单的访问控制,实现基础是通过 Mixer 选择器拒绝某些条件下的请求。
比如,上文所述的 Bookinfo 应用中的 ratings 服务会被多个版本的 reviews 服务访问。下面的示例中我们将会切断来自 v3 版本的 reviews 服务对 ratings 服务的调用。
- 用浏览器打开 Bookinfo 的 productpage(http://$GATEWAY_URL/productpage)
如上图所示,如果用 “kokokobe” 的用户登录,能看到每条 review 下面的黑色星星,说明此时 ratings 服务被 v2 版本的 reviews 服务调用。
从上面两张图可以看出,如果使用其他用户登录(或未登录),能看到每条 review 下面的红色星星,说明此时 ratings 服务被 v3 版本的 reviews 服务调用。
- 创建 denier 适配器,拒绝来自 v3 版本的 reviews 服务对 ratings 服务的调用
编辑 mixer-rule-deny-label.yaml 内容如下:
这也是Mixer的adapter的标准配置格式,一般需要配置三种类型的资源:
- 配置一组 handler。Handler是配置好的 adapter 的实例,adapter 封装了 Mixer 和特定基础设施后端之间的接口。
- 基于 template 配置一组 instance。Instance 定义了如何将 Envoy 提供的请求属性映射到 adapter 的输入。
- 配置一组规则。这些规则描述了何时调用特定的 handler 及 instance。
在这里其中定义了一条名为 denyreviewsv3 的规则,一个 denier 类型的 handler,一个checknothing 类型的模板的实例。
在 denyreviewsv3 规则中,方框内的条件表达式匹配的条件是:来自 reviews 服务,version 为 v3 ,目标为 ratings 服务的请求。这条规则使用 denier 适配器拒绝来自 v3 版本的 reviews 服务的请求。
这个 denier 适配器会拒绝符合上述规则的请求。可以预先指定 denier 适配器的状态码和消息,如方框中所示。
然后执行如下命令创建上述规则的 denier 适配器:
- 在浏览器中刷新 productpage 页面
如果已经登出或者使用不是 “kokokobe” 的用户身份登录,不再看到红色星星,因为v3版本的 reviews 服务对 ratings 服务的访问已经被拒绝了。
相反,如果使用 “kokokobe” 用户登录,仍然能够看到黑色星星。因为该用户使用的是 v2 版本的 reviews 服务,不符合拒绝的条件。
通过listchecker适配器实现黑白名单
Istio 也支持基于属性的黑名单和白名单。下面的白名单配置和上一节的 denier 配置是等价的,拒绝来自 v3 版本的 reviews 服务的请求。
- 删除上一节配置的 denier 规则
- 在登出状态下浏览 Bookinfo 的 productpage(http://$GATEWAY_URL/productpage)
此时能看到红星图标。在完成下述步骤之后,只有在使用 “kokokobe” 的身份登录之后才能看到星形图标。
- 创建包含 v2 版本白名单的 listchecker 适配器
编辑 whitelist-handler.yaml 内容如下:
通常会在外部维护黑白名单的列表,然后指定 providerUrl 参数进行异步获取。在这个例子中,我们使用 overrides 字段提供一个静态的黑白名单列表。
然后运行如下命令创建 listchecker 适配器:
- 创建一个 listentry 模板的实例
Listentry 模板可以用来判别一个字符串是否存在于一个列表中,本例中我们使用它来判别版本标签是否存在于白名单中。
编辑 appversion-instance.yaml 内容如下:
然后运行如下命令:
- 为 ratings 服务启用 whitelist 检查功能
编辑 checkversion-rule.yaml 内容如下:
然后运行如下命令:
- 在浏览器中刷新 productpage 页面
如果已经登出或者使用不是 “kokokobe” 的用户身份登录,看不到星形图标;如果使用 “kokokobe” 用户登录,仍然能够看到黑色星星。
总结
通过上述示例,可以发现使用 Istio 实现微服务间的访问控制非常方便。既可以使用denier 适配器实现简单的访问控制,也可以通过listchecker 适配器实现较复杂的黑白名单。
相关服务请访问https://support.huaweicloud.com/cce/index.html?cce_helpcenter_2019
原文地址:http://blog.51cto.com/14051317/2348359