本系列文章讲讲述阿里云服务网格ASM的一些扩展能力:
- 阿里云服务网格ASM之扩展能力(1):在ASM中通过EnvoyFilter添加HTTP请求头
- 阿里云服务网格ASM之扩展能力(2):在ASM中支持自定义外部授权
- 阿里云服务网格ASM之扩展能力(3):在ASM中使用开放策略代理OPA
- 阿里云服务网格ASM之扩展能力(4):在ASM中实现分布式跟踪
欢迎扫码入群进一步交流:
前面的系列文档中介绍了如何创建服务网格ASM实例,并介绍了如何将一个应用示例部署到 ASM 实例中,本文在此基础上介绍如何在ASM中使用开放策略代理OPA定义细粒度访问控制。
前提条件
- 已创建至少一个 ASM 实例,并已添加至少一个 ACK 集群到该实例中。
- 已通过 Kubernetes 命令行客户端 kubectl 连接到 ASM 实例中新添加的 ACK 集群,详情参见通过 kubectl 连接 Kubernetes 集群。
- 已通过 Kubernetes 命令行客户端 kubectl 连接到 ASM 实例,详情参见通过 kubectl 连接 ASM 实例。
开放策略代理OPA
作为由CNCF托管的一个孵化项目,开放策略代理(OPA)是一个策略引擎,可用于为您的应用程序实现细粒度的访问控制。例如,可以使用OPA 跨微服务实现授权等。如图所示,OPA作为通用策略引擎,可以与微服务一起部署为独立服务。为了保护应用程序,必须先授权对微服务的每个请求,然后才能对其进行处理。为了检查授权,微服务对OPA进行API调用,以确定请求是否被授权。
在ASM中启用OPA
服务网格ASM集成了开放策略代理OPA,可用于为您的应用程序实现细粒度的访问控制。例如,可以使用OPA 跨微服务实现授权等。启用后,如同Istio Envoy代理容器一样,OPA代理容器也会随之被注入到业务Pod中。然后,在ASM中就可以使用OPA定义访问控制策略,为分布式应用的开发者提供了开箱可用的能力,可以帮助开发者快速定义使用策略,提升开发效率。
其中,如图所示在创建服务网格实例时,可以通过设置是否启用OPA插件。
功能设置
如果在创建服务网格ASM实例时没有勾选启用OPA插件,可以通过如下方式重启开启。
- 登录服务网格控制台,在ASM实例详情页的右上角,点击功能设置按钮。
- 在弹出的窗口中,可以重新勾选启用OPA插件。
注意:部署业务Pod之前,必须确保已经部署了OPA配置文件和策略的配置项Configmap,具体如下。
部署OPA配置
部署OPA配置文件。通过 kubectl 连接到 ASM 实例中新添加的 ACK 集群,执行如下命令:
kubectl apply -n {替换成实际的namespace} -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: opa-istio-config
data:
config.yaml: |
plugins:
envoy_ext_authz_grpc:
addr: :9191
path: istio/authz/allow
EOF
部署OPA策略
当前在ASM中已经支持使用Rego定义的OPA策略,后续会支持基于WebAssembly的OPA扩展能力。
通过 kubectl 连接到 ASM 实例中新添加的 ACK 集群,替换成实际的策略定义,执行如下命令:
kubectl apply -n {替换成实际的namespace} -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: opa-policy
data:
policy.rego: | ###以下为示例策略定义,需要替换成实际的策略定义
package istio.authz
import input.attributes.request.http as http_request
default allow = false
allow {
roles_for_user[r]
required_roles[r]
}
roles_for_user[r] {
r := user_roles[user_name][_]
}
required_roles[r] {
perm := role_perms[r][_]
perm.method = http_request.method
perm.path = http_request.path
}
user_name = parsed {
[_, encoded] := split(http_request.headers.authorization, " ")
[parsed, _] := split(base64url.decode(encoded), ":")
}
user_roles = {
"guest1": ["guest"],
"admin1": ["admin"]
}
role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
],
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
],
}
EOF
注入OPA代理容器
按照部署应用到 ASM 实例重新部署示例应用到 ASM 实例,并定义相应的Istio虚拟服务和入口网关,详情参见管理 Istio 资源定义。
- 登录容器服务管理控制台,单击左侧导航栏中的应用->容器组;
- 在右侧打开的页面中,选择对应的集群及命名空间(如default),此时Bookinfo应用Pod应为运行中,并且每一个Pod内都被注入了Sidecar代理(istio-proxy)和OPA代理(opa-istio),类似如下图所示:
执行结果
上述策略限制对BookInfo的访问,定义如下:
- guest1被授予guest角色,并且可以访问
/productpage
但不能访问/v1/api/products
。 - admin1被授予admin角色,并且可以访问
/productpage
和/v1/api/products
。
curl -i --user guest1:password http://{入口网关服务的IP地址}/productpage
HTTP/1.1 200 OK
......
curl -i --user guest1:password http://{入口网关服务的IP地址}/api/v1/products
HTTP/1.1 403 Forbidden
......
curl -i --user admin1:password http://{入口网关服务的IP地址}/productpage
HTTP/1.1 200 OK
......
curl -i --user admin1:password http://{入口网关服务的IP地址}/api/v1/products
HTTP/1.1 200 OK
......