当把一个单体应用拆分为许多微服务时,会带来很多好处,比如单个服务的开发会更简单,服务更容易扩缩容,能更好地实现服务重用。但这也会带来很多安全问题,需要加强安全方面的管理,例如:
·为了抵御中间人攻击,需要服务间的通信加密。
·为了使服务间的通信控制更灵活,需要双向TLS加密以及更细粒度的访问控制。
·需要审核谁在什么时候做了什么,需要审计工具。
Istio尝试提供一个通用的安全解决方案来解决上述问题。本章主要介绍如何使服务间的通信更安全,以及如何控制服务间的访问权限。
Istio安全功能架构如图10-1所示。
其中:
·Citadel提供密钥和证书管理。
·Envoy代理实现客户端和服务端之间的安全通信。
·Pilot负责将认证策略和安全命名信息分发给Envoy代理。
·Mixer负责管理授权和审计。
图10-1 Istio安全功能架构(图片来源:Istio官方网站)
外部流量通过Ingress代理进入网格内,可以在Ingress代理上设置认证和加密策略。Ingress代理与网格内部Envoy代理以及网格内部Enovy代理之间,通过mTLS认证和加密通信。需要访问外部服务的网格内的服务使用Envoy代理与Egress代理通过mTLS认证加密通信,Egress代理代替服务访问外部服务。Egress代理是可选的配置项,也可以不使用Egress代理,直接使用Envoy代理访问外部服务。上面这些认证加密规则是用户通过Istio的控制平面提供的API接口进行配置的。
【实验前的准备】
进行本章实验前,需要先执行如下的前置步骤。
1)下载实验时使用的源码仓库:
$ sudo yum install -y git $ git clone https://github.com/mgxian/istio-lab Cloning into 'istio-lab'... remote: Enumerating objects: 247, done. remote: Counting objects: 100% (247/247), done. remote: Compressing objects: 100% (173/173), done. remote: Total 774 (delta 153), reused 164 (delta 73), pack-reused 527 Receiving objects: 100% (774/774), 283.00 KiB | 229.00 KiB/s, done. Resolving deltas: 100% (447/447), done. $ cd istio-lab
2)开启default命名空间的自动注入功能:
$ kubectl label namespace default istio-injection=enabled namespace/default labeled
3)部署用于测试的服务:
$ kubectl apply -f service/go/service-go.yaml $ kubectl apply -f service/node/service-node.yaml $ kubectl get pod NAME READY STATUS RESTARTS AGE service-go-v1-7cc5c6f574-pd87x 2/2 Running 0 29s service-go-v2-7656dcc478-5xdwc 2/2 Running 0 29s service-node-v1-d44b9bf7b-vtzhq 2/2 Running 0 25s service-node-v2-86545d9796-pxtsx 2/2 Running 0 25s