默认情况下,服务网格内的工作负载可以互相访问。当您需要对集群中的工作负载进行访问控制和权限管理时,可以使用授权策略设置工作负载的访问条件(例如限制请求路径、方法和客户端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下的服务成功,说明通过授权策略控制跨命名空间服务访问成功。