istio-访问授权

Istio授权功能是基于角色的访问控制(RBAC),支持在Istio Mesh中,为服务提供名称空间级别,服务级别和方法级别的访问控制。它具有以下特点:

  • 基于角色的语义,简单易用。
  • 支持服务到服务,以及终端用户到服务授权
  • 灵活性的自定义属性支持,例如角色和角色绑定中的条件。
  • 高性能,Istio授权在Envoy上本地执行。
  • 高兼容性,本地支持HTTP,HTTPS和HTTP2,以及任何普通的TCP协议。

1. 授权架构

Istio授权架构

上图显示了基本的Istio授权架构。运营商使用.yaml文件指定Istio授权策略。部署后,Istio将策略保存在中Istio Config Store。

Pilot监视Istio授权策略的更改。如果看到任何更改,它将获取更新的授权策略。Pilot将Istio授权策略分发给与服务实例位于同一位置的Envoy代理。

每个Envoy代理都运行一个授权引擎,该引擎在运行时对请求进行授权。当请求到达代理时,授权引擎根据当前的授权策略评估请求上下文,并返回授权结果ALLOW或DENY。

2.  启用授权

可以使用ClusterRbacConfig对象启用Istio授权。该ClusterRbacConfig 对象是集群范围内的单例,其固定名称值为default。在网格中只能使用ClusterRbacConfig一个实例。与其他Istio配置对象一样,ClusterRbacConfig被定义为Kubernetes CustomResourceDefinition (CRD)对象。

在ClusterRbacConfig对象中,操作员可以指定一个mode值,该值可以是:

  • OFF:Istio授权已禁用。
  • ON:已为网格中的所有服务启用Istio授权。
  • ON_WITH_INCLUSION:仅对inclusion字段中指定的服务和名称空间启用Istio授权。
  • ON_WITH_EXCLUSION注意:除在exclusion字段中指定的服务和名称空间外,将为网格中的所有服务启用Istio授权。

在以下示例中,为default 名称空间启用了Istio授权。

apiVersion: "rbac.istio.io/v1alpha1"
kind: ClusterRbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'
  inclusion:
    namespaces: ["default"]

3.  授权策略

通过指定ServiceRole和 ServiceRoleBinding 来配置Istio授权策略。与其他Istio配置对象一样,它们是Kubernetes CustomResourceDefinition (CRD)对象。

  • ServiceRole :定义一组访问服务的权限。
  • ServiceRoleBinding:将ServiceRole授予特定主题,例如用户,组或服务。

ServiceRole和ServiceRoleBinding组合规定:在什么条件下,被允许做什么。特别:

  • Who:参考ServiceRoleBinding中的subjects。
  • What参考permissions的ServiceRole。
  • Which condition:参考ServiceRole和ServiceRoleBinding是指conditions您可以在或中使用Istio属性指定的部分。

3.1.  ServiceRole

ServiceRole规范包括的rules的,AKA权限。每个规则都有以下标准字段:

  • services:服务名称列表。可以将值设置为*,这样会包括指定名称空间中的所有服务。
  • methods:HTTP方法列表。可以将值设置为*,这样会包括所有HTTP方法。不应为TCP和gRPC服务设置此字段。
  • paths:HTTP路径或gRPC方法。gRPC方法必须采用/packageName.serviceName/methodName且区分大小写。

ServiceRole规格只适用于指定的命名空间。规格services字段是必须的,其他字段是可选的。如果未指定字段或将其值设置为*,则Istio将该字段应用于所有实例。

下面的示例显示一个简单的角色:service-admin,该角色对default名称空间中所有服务的具有完全访问权限。

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: service-admin
  namespace: default
spec:
  rules:
  - services: ["*"]

这里是另一个角色:products-viewer,对default命名空间下的products.default.svc.cluster.local服务,具有”GET”和”HEAD”访问权限。

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: products-viewer
  namespace: default
spec:
  rules:
  - services: ["products.default.svc.cluster.local"]
    methods: ["GET", "HEAD"]

此外,支持规则中所有字段的前缀匹配和后缀匹配。例如,可以tester在default名称空间中定义具有以下权限的角色:

  • 访问所有前缀为”test-*”的服务,例如:test-bookstore,test-performance,test-api.default.svc.cluster.local。
  • (”GET”)访问后缀为”*/reviews”的所有路径,例如:在default.svc.cluster.local服务中的/books/reviews,/events/booksale/reviews,/reviews。
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: tester
  namespace: default
spec:
  rules:
  - services: ["test-*"]
    methods: ["*"]
  - services: ["bookstore.default.svc.cluster.local"]
    paths: ["*/reviews"]
    methods: ["GET"]

在ServiceRole,组合namespace+ services+ paths+ methods定义了服务或服务如何被访问。在某些情况下,可能需要为规则指定其他条件。例如,规则可能仅适用于某个版本的服务,或仅适用于带有特定标签的服务(例如”foo”)。可以通过使用约束来实现上述的条件。

例如,以下ServiceRole定义添加了一个约束,该约束 request.headers[version]:”v1″或”v2″。约束和属性页面key中列出了约束的支持值。

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: products-viewer-version
  namespace: default
spec:
  rules:
  - services: ["products.default.svc.cluster.local"]
    methods: ["GET", "HEAD"]
    constraints:
    - key: request.headers[version]
      values: ["v1", "v2"]

3.2.  ServiceRoleBinding

ServiceRoleBinding规范包括两个部分:

  • roleRef:引用相同名称空间中的ServiceRole资源。
  • subjects:分配给角色的列表。

可以明确地为subjects指定一个user或带有一组属性的user。ServiceRoleBinding subjects的属性是类似于ServiceRole规范中的约束。可以通过属性使用条件来为角色分配帐户。属性它包含一个 key及其允许的值。

以下示例显示了一个名称为test-binding-products 的ServiceRoleBinding,它将两个主题绑定到名称为”product-viewer”的ServiceRole。

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: test-binding-products
  namespace: default
spec:
  subjects:
  - user: "service-account-a"
  - user: "istio-ingress-service-account"
    properties:
      request.auth.claims[email]: "a@foo.com"
  roleRef:
    kind: ServiceRole
    name: "products-viewer"

如果要使服务可以被公开访问,可以在subjects设置user: “*”。此值将分配ServiceRole给所有(经过身份验证和未经身份验证的)用户和服务,例如:

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: binding-products-allusers
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "products-viewer"

要将ServiceRole分配给仅通过身份验证的用户和服务,请source.principal: “*” 改用,例如:

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: binding-products-all-authenticated-users
  namespace: default
spec:
  subjects:
  - properties:
    source.principal: "*"
  roleRef:
    kind: ServiceRole
    name: "products-viewer"

4.  在纯TCP协议上使用Istio授权

服务角色和服务角色绑定的示例显示在服务上使用HTTP协议进行Istio授权的典型方法。在这些示例中,支持服务角色和服务角色绑定中的所有字段。Istio授权支持任何使用普通TCP协议(例如MongoDB)的服务,服务角色配置和服务角色绑定都是与HTTP协议一样。区别在于使用某些仅适用于HTTP服务的字段,约束和属性。这些字段包括:

  • 服务角色配置对象中的paths和methods字段。
  • 服务角色绑定配置对象中的group字段。

如果对TCP服务使用了仅支持HTTP的字段,则Istio会完全忽略服务角色或服务角色绑定自定义资源和策略。假设在端口27017上具有MongoDB服务,下面的示例仅允许bookinfo-ratings-v2访问MongoDB服务。

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: mongodb-viewer
namespace: default
spec:
rules:
- services: ["mongodb.default.svc.cluster.local"]
constraints:
- key: "destination.port"
values: ["27017"]
---

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: bind-mongodb-viewer
  namespace: default
spec:
  subjects:
  - user: "cluster.local/ns/default/sa/bookinfo-ratings-v2"
  roleRef:
    kind: ServiceRole
    name: "mongodb-viewer"

 

作者简介:季向远,北京神舟航天软件技术有限公司。本文版权归原作者所有。

K8S中文社区微信公众号

评论 抢沙发

登录后评论

立即登录