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"
作者简介:季向远,北京神舟航天软件技术有限公司。本文版权归原作者所有。