和其他的 Istio 配置一样,可以用 .yaml 文件的形式来编写认证策略,然后使用 Istioctl 二进制工具进行部署。如下图的配置,通过配置Policy文件,对reviews服务进行了传输身份认证的配置,要求其必须使用双向TLS做认证。
apiVersion: "authentication.Istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "reviews"
spec:
targets:
- name: reviews
peers:
- mtls: {}
3.2 授权Istio 的授权功能,也称为基于角色的访问控制(RBAC),为 Istio 服务网格中的服务提供命名空间级别,服务级别和方法级别的访问控制。它的特点是:
l 基于角色的语义,简单易用。
l 包含服务到服务和终端用户到服务两种授权模式。
l 通过自定义属性灵活定制授权策略,例如条件,角色和角色绑定。
l 高性能,因为 Istio 授权功能是在 Envoy 里执行的。
3.2.1 授权架构
上图显示了基本的 Istio 授权架构。和认证的生效过程一样,运维人员使用.yaml文件指定 Istio 授权策略。部署后,Istio 将策略保存在Istio Config Store中。Pilot 会一直监视 Istio 授权策略的变更,如果发现任何更改,它将获取更新的授权策略,并将 Istio 授权策略分发给与服务实例位于同一 pod 内的 Envoy 代理。
每个 Envoy 代理都运行一个授权引擎,该引擎在运行时授权请求。当请求到达代理时,授权引擎根据当前授权策略评估请求上下文,并返回授权结果ALLOW或DENY。
3.2.2 授权策略配置我们可以使用 RbacConfig 启用授权策略,并使用ServiceRole和ServiceRoleBinding配置授权策略。
RbacConfig是一个网格维度的单例,其固定名称值为default,也就是说我们只能在网格中配置一个RbacConfig实例。与其他 Istio 配置对象一样,RbacConfig被定义为Kubernetes CustomResourceDefinition (CRD)对象。
在RbacConfig中,运算符可以指定mode值,它可以是:
l OFF:禁用 Istio 授权。
l ON:为网格中的所有服务启用了 Istio 授权。
l ON_WITH_INCLUSION:仅对包含字段中指定的服务和命名空间启用 Istio 授权。
l ON_WITH_EXCLUSION:除了排除字段中指定的服务和命名空间外,网格中的所有服务都启用 Istio 授权。
在以下示例中,为default命名空间启用了 Istio 授权,。
apiVersion: "rbac.Istio.io/v1alpha1"
kind: RbacConfig
metadata:
name: default
namespace: Istio-system
spec:
mode: 'ON_WITH_INCLUSION'
inclusion:
namespaces: ["default"]
针对服务和命名空间启用授权后,我们还需要配置具体的授权策略,这通过配置ServiceRole和ServiceRoleBinding实现。与其他 Istio 配置对象一样,它们同样被定义为CRD对象。
ServiceRole定义了一组访问服务的权限。ServiceRoleBinding向特定对象授予 ServiceRole,例如用户,组或服务。
ServiceRole 和 ServiceRoleBinding 组合规定了: 允许谁在哪些条件下做什么,具体而言:
l 谁指的是 ServiceRoleBinding 中的 subject 部分。
l 做什么指的是 ServiceRole 中的 rule 部分。
l 哪些条件指的是我们可以在 ServiceRole 或 ServiceRoleBinding 中使用Istio Attributes指定的 condition 部分。
让我们再举一个简单的例子,如下图,ServiceRole和 ServiceRoleBinding的配置规定:将所有用户(user=“*”)绑定为(products-viewer)角色,这个角色可以对products这个服务发起GET或HEAD请求,但是其限制条件是请求头必须包含version,且值为v1或v2。
apiVersion: "rbac.Istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: products-viewer
namespace: default
spec:
rules:
- services: ["products"]
methods: ["GET", "HEAD"]
constraints:
- key: request.headers[version]
values: ["v1", "v2"]
---
apiVersion: "rbac.Istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: binding-products-allusers
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "products-viewer"
至此,我们做个简单的总结:单体应用程序拆分成成千上百个服务后,带来了安全问题,Istio尝试在由服务组成的服务网格里,加入了一套全栈解决方案。这套方案里,Istio默默处理了大部分安全基础设施,但也暴露了认证和授权两个功能让用户进行自定义配置。我们通过Policy、MeshPolicy以及RbacConfig、ServiceRole、ServiceRoleBinding就可以完成对认证和授权环节所有功能的配置,而不需要侵入地改动任何服务的代码。