默认情况下,服务网格内的工作负载可以互相访问。当您需要对集群中的工作负载进行访问控制和权限管理时,可以使用授权策略设置工作负载的访问条件(例如限制请求路径、方法和客户端IP等),确保只有符合要求的请求才能访问对应工作负载,提高网格安全和资源保护。
前提条件
功能介绍
授权策略支持CUSTOM(自定义)、DENY(拒绝)和ALLOW(允许)策略类型。规则的判断存在优先级关系,当CUSTOM、DENY和ALLOW策略同时用于同一个工作负载时,将首先验证CUSTOM策略,然后验证DENY策略,最后验证ALLOW策略,并且存在以下关系:
- 如果任何一个CUSTOM策略匹配了请求并验证结果为拒绝,则拒绝此请求。 
- 如果任何一个DENY策略匹配了请求并验证结果为拒绝,则拒绝此请求。 
- 如果此工作负载上没有配置ALLOW策略,允许此请求(默认允许)。 
- 如果该工作负载配置了ALLOW策略,并且ALLOW策略匹配此请求,允许此请求。 
- 如果都不满足以上要求,则拒绝此请求。 
本文提供以下四个示例,帮助您快速了解和使用授权策略。
示例一:限制访问工作负载的请求路径
本示例中,foo命名空间下的应用可以访问本命名空间下的httpbin应用的/headers路径,访问其他路径都将失败;其它命名空间下的应用无法访问httpbin应用。
步骤一:为default和foo命名空间注入Sidecar代理
步骤二:部署测试应用
- 在default和foo命名空间部署sleep应用。 - 使用以下内容,创建sleep.yaml。 
- 执行以下命令,在default命名空间部署sleep应用。 - kubectl apply -f sleep.yaml -n default
- 执行以下命令,在foo命名空间部署sleep应用。 - kubectl apply -f sleep.yaml -n foo
 
- 在foo命名空间部署httpbin应用。 - 使用以下内容,创建httpbin.yaml。 
- 执行以下命令,在foo命名空间部署httpbin应用。 - kubectl apply -f httpbin.yaml -n foo
 
步骤三:创建授权策略
- 登录ASM控制台,在左侧导航栏,选择。 
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择,然后单击创建。 
- 在创建页面,配置相关信息,然后单击创建。 - 配置项 - 说明 - 名称 - 自定义授权策略名称。 - 策略类型 - 设置为允许。 - 命名空间 - 在工作负载生效页签,设置命名空间为foo。 - 生效范围 - 选择Service。 - 工作负载 - 选择httpbin。 - 请求匹配规则 - 在添加请求来源区域,打开命名空间(Namespaces)开关,设置值为foo,使foo命名空间下的应用都能访问httpbin应用。 
- 在添加请求目标区域,打开HTTP路径(Paths)开关,设置值为/headers,使所有命名空间下的应用仅支持访问foo命名空间下的httpbin应用的/headers路径。 
 
步骤四:验证限制访问请求路径是否成功
- 使用default命名空间下的sleep应用访问foo命名空间下的httpbin应用。 - 登录容器服务管理控制台,在左侧导航栏选择集群列表。 
- 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。 
- 在容器组页面顶部,设置命名空间为default,在操作列,单击sleep容器对应的。 
- 在sleep容器终端中执行以下命令,访问httpbin应用的/headers路径。 - curl httpbin.foo.svc.cluster.local:8000/headers- 返回403,提示访问被拒绝。 
- 在sleep容器终端中执行以下命令,访问httpbin应用的/ip路径。 - curl httpbin.foo.svc.cluster.local:8000/ip- 返回403,提示访问被拒绝。 
 
- 使用foo命名空间下的sleep应用访问foo命名空间下的httpbin应用。 - 在集群管理页左侧导航栏,选择。 
- 在容器组页面顶部设置命名空间为foo,在操作列,单击sleep容器对应的。 
- 在sleep容器终端中执行以下命令,访问httpbin应用的/headers路径。 - curl httpbin.foo.svc.cluster.local:8000/headers- 预期输出: - { "headers": { "Accept": "*/*", "Host": "httpbin.foo.svc.cluster.local:8000", "User-Agent": "curl/7.82.0-DEV", "X-Envoy-Attempt-Count": "1", "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=f7ab4985563b5b1986314d5a36c6e46819213e2f38301f534f00afb7cd4b9164;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep" } }
- 在sleep容器终端中执行以下命令,访问httpbin应用的/ip路径。 - curl httpbin.foo.svc.cluster.local:8000/ip- 返回403,提示访问被拒绝。 
 - 可以看到default命名空间中的应用无法访问foo命名空间下的httpbin应用的任何路径,foo命名空间中的应用可以访问httpbin的/headers路径。 
示例二:限制访问工作负载的请求路径和方法
本示例中,所有命名空间下的应用仅支持通过GET请求访问foo命名空间下的httpbin应用的/status路径,访问其他路径或使用其他请求方法都将失败。
步骤一:为default和foo命名空间注入Sidecar代理
步骤二:部署测试应用
- 在default和foo命名空间部署sleep应用。 - 使用以下内容,创建sleep.yaml。 
- 执行以下命令,在default命名空间部署sleep应用。 - kubectl apply -f sleep.yaml -n default
- 执行以下命令,在foo命名空间部署sleep应用。 - kubectl apply -f sleep.yaml -n foo
 
- 在foo命名空间部署httpbin应用。 - 使用以下内容,创建httpbin.yaml。 
- 执行以下命令,在foo命名空间部署httpbin应用。 - kubectl apply -f httpbin.yaml -n foo
 
步骤三:创建授权策略
- 登录ASM控制台,在左侧导航栏,选择。 
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择,然后单击创建。 
- 在创建页面,配置相关信息,然后单击创建。 
- 打开HTTP方法(Methods)开关,设置值为GET。 
- 打开HTTP路径(Paths)开关,设置值为/status/*,使所有命名空间下的应用仅支持使用GET方法访问foo命名空间下的httpbin应用的/status路径。 
| 配置项 | 说明 | 
| 名称 | 自定义授权策略名称。 | 
| 策略类型 | 选择允许。 | 
| 命名空间 | 在工作负载生效页签,设置命名空间为foo。 | 
| 生效范围 | 选择Service。 | 
| 工作负载 | 选择httpbin。 | 
| 请求匹配规则 | 在添加请求目标区域,进行如下配置: | 
步骤四:验证限制访问工作负载的请求路径和方法是否成功
- 登录容器服务管理控制台,在左侧导航栏选择集群列表。 
- 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。 
- 在容器组页面顶部,设置命名空间为default,在操作列,单击sleep容器对应的。 
- 在sleep容器终端中执行以下命令,使用POST的方式访问httpbin应用的/status路径。 - curl -I -X POST "httpbin.foo.svc.cluster.local:8000/status/200" -H "accept: text/plain"- 返回403,访问httpbin应用失败。 
- 执行以下命令,使用GET的方式访问httpbin应用的/IP路径。 - curl -I -X GET "httpbin.foo.svc.cluster.local:8000/IP/200" -H "accept: text/plain"- 返回403,访问httpbin应用失败。 
- 执行以下命令,使用GET的方式访问httpbin应用的/status路径。 - curl -I -X GET "httpbin.foo.svc.cluster.local:8000/status/200" -H "accept: text/plain"- 预期输出: - HTTP/1.1 200 OK server: envoy date: Fri, 29 Apr 2022 03:01:16 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 5- 可以看到default命名空间下的应用只有使用GET方式访问httpbin应用的/status路径才能成功,说明限制访问工作负载的请求路径和方法成功。 
示例三:限制访问工作负载的客户端IP
限制foo命名空间中的httpbin应用只能被许可的客户端IP访问。
步骤一:为foo命名空间注入Sidecar代理
步骤二:创建ASM网关
- 登录ASM控制台,在左侧导航栏,选择。 
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择。 
- 在入口网关页面,单击创建,配置相关信息,然后单击创建。 - 配置项 - 说明 - 名称 - 自定义网关的名称。 - 部署集群 - 选择网关部署的集群。 - 负载均衡 - 选择CLB(可以根据需要使用NLB,此处以CLB为例),公网访问。 - 新建负载均衡 - 选择负载均衡,可选: - 使用已有负载均衡:从已有负载均衡列表中选择。 
- 新建负载均衡:单击新建负载均衡,从下拉列表中选择所需的负载均衡规格。 
 - 端口映射 - 按需选择协议,输入服务端口。 - 外部流量策略 - 单击高级选项,设置外部流量策略为Local。 
步骤三:创建虚拟服务和网关规则
- 使用以下内容,在foo命名空间中创建虚拟服务。具体操作,请参见管理虚拟服务。 - apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin spec: gateways: - httpbin-gateway hosts: - '*' http: - match: - uri: prefix: /headers route: - destination: host: httpbin port: number: 8000
- 使用以下内容,在foo命名空间创建网关规则。具体操作,请参见管理网关规则。 - apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: httpbin-gateway spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: http number: 80 protocol: HTTP
步骤四:创建授权策略
- 获取ASM网关IP。具体操作,请参见创建入口网关服务。 
- 获取客户端IP。 - 在浏览器地址栏中输入http://{ASM网关IP}/headers,获取X-Envoy-External-Address右侧的IP。  
- 创建授权策略。 
步骤五:验证限制访问工作负载的客户端IP是否成功
在浏览器地址栏中输入http://{ASM网关IP}/headers,返回RBAC:access denied,访问httpbin应用失败,说明限制访问工作负载的客户端IP成功。
示例四:限制跨命名空间的服务访问
步骤一:为demo-frontend和demo-server命名空间注入Sidecar代理
- 创建demo-frontend和demo-server命名空间。具体操作,请参见新建命名空间。 
- 为demo-frontend和demo-server命名空间注入Sidecar代理。具体操作,请参见启用自动注入。 
步骤二:部署测试服务
在demo-frontend命名空间下创建发起请求的sleep服务,在demo-server命名空间下创建被访问的httpbin服务。
- 在demo-frontend命名空间下创建sleep服务。 - 使用以下内容,创建sleep.yaml。 
- 在ACK集群对应的KubeConfig环境下,执行以下命令,创建sleep服务。 - kubectl apply -f sleep.yaml -n demo-frontend
 
- 在demo-server命名空间下创建httpbin服务。 - 使用以下内容,创建httpbin.yaml。 
- 在ACK集群对应的KubeConfig环境下,执行以下命令,创建httpbin服务。 - kubectl apply -f httpbin.yaml -n demo-server
 
- 验证测试服务是否成功注入Sidecar。 - 登录容器服务管理控制台,在左侧导航栏选择集群列表。 
- 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。 
- 在容器组页面上方,命名空间选择demo-frontend,单击sleep服务的容器组名称。 - 在容器页签下可以看到istio-proxy容器,说明sleep服务注入Sidecar成功。 
- 在容器组页面上方,命名空间选择demo-server,单击httpbin服务的容器组名称。 - 在容器页签下可以看到istio-proxy容器,说明httpbin服务注入Sidecar成功。 
 
步骤三:使用授权策略实现对跨命名空间服务访问的控制
通过修改授权策略的动作,您可以禁止或允许demo-frontend命名空间下的服务访问demo-server下的服务,实现对跨命名空间服务访问的控制。
- 创建授权策略,禁止来自demo-frontend命名空间的访问请求。 - 登录ASM控制台,在左侧导航栏,选择。 
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择,然后单击创建。 
- 配置授权策略相关信息,然后单击创建。 - 配置项 - 说明 - 名称 - 输入授权策略的名称。 - 策略类型 - 选择拒绝。 - 命名空间 - 在工作负载生效页签,设置命名空间为demo-server。 - 生效范围 - 选择命名空间生效。 - 请求匹配规则 - 在添加请求来源区域,打开命名空间(Namespaces)开关,设置值为demo-frontend。 
 
- 访问httpbin服务。 - 登录容器服务管理控制台,在左侧导航栏选择集群列表。 
- 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。 
- 在容器组页面上方,命名空间选择demo-frontend,然后在操作列,单击sleep容器对应的。 
- 在容器组终端中执行以下命令,访问httpbin服务。 - curl -I httpbin.demo-server.svc.cluster.local:8000- 预期输出: - HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Wed, 11 Oct 2023 08:15:25 GMT server: envoy x-envoy-upstream-service-time: 4- 返回以上结果,说明demo-frontend命名空间下的服务访问demo-server下的服务失败。 
 
- 修改授权策略动作为ALLOW,允许来自demo-frontend命名空间的访问请求。 - 登录ASM控制台,在左侧导航栏,选择。 
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择。 
- 在授权策略页面,单击目标策略右侧操作列下的查看YAML。 
- 在编辑对话框,修改action参数值为ALLOW,然后单击确定。 
 
- 在sleep容器组终端中执行以下命令,访问httpbin服务。 - curl -I httpbin.demo-server.svc.cluster.local:8000- 预期输出: - HTTP/1.1 200 OK server: envoy date: Wed, 11 Oct 2023 08:21:40 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 13- 返回以上结果,说明demo-frontend命名空间下的服务成功访问demo-server下的服务。 - 可以看到,创建动作为Deny的授权策略后,demo-frontend命名空间下的服务访问demo-server下的服务失败。修改授权策略的动作为ALLOW,demo-frontend命名空间下的服务访问demo-server下的服务成功,说明通过授权策略控制跨命名空间服务访问成功。