在一些安全要求下,集群内的应用服务必须加密所有外部流量。使用Istio,只需通过配置即可实现此要求,而无需更改应用程序中的任何代码。应用程序可以发送未加密的HTTP请求,然后Istio将为应用程序加密它们。从源发送未加密的HTTP请求并让Istio执行TLS升级的另一个好处是,Istio可以产生更好的遥测并为未加密的请求提供更多路由控制。
按照前面章节介绍的方式部署sleep应用程序,并创建ServiceEntry与VirtualService以转发HTTP请求端口并添加一个DestinationRule以执行TLS发起:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: istio-io
spec:
hosts:
- istio.io
ports:
- number: 80
name: http-port
protocol: HTTP
- number: 443
name: http-port-for-tls-origination
protocol: HTTP
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: istio-io
spec:
hosts:
- istio.io
http:
- match:
- port: 80
route:
- destination:
host: istio.io
port:
number: 443
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: istio-io
spec:
host: istio.io
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE # initiates HTTPS
VirtualService将端口80上的HTTP请求重定向到端口443,同时DestinationRule定义了相应的端口执行TLS发起。请注意,与ServiceEntry上一节不同,这次端口433上的协议是HTTP,而不是HTTPS。这是因为客户端只会发送HTTP请求,而Istio会将连接升级到HTTPS。
验证上述配置是否已正确生效。发送HTTP请求到http://istio.io:
kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://istio.io HTTP/1.1 200 OK cache-control: public, max-age=0, must-revalidate content-type: text/html; charset=UTF-8 date: Wed, 23 Jan 2019 08:12:16 GMT etag: "660e4bd7ded5a3a85a24118433d3f4b2-ssl" strict-transport-security: max-age=31536000 x-nf-srv-version: 45aaffea081549dd03a2dfff644cc25cf522edbd age: 128961 content-length: 25833 server: envoy x-nf-request-id: f6a3e5cf-9f20-4983-9a91-d0e319e89bcd-10296610 x-envoy-upstream-service-time: 850
可以看到200 OK是第一个和唯一的回复。Istio为curl执行TLS创建,因此原始HTTP请求被转发为HTTPS。服务器直接返回内容,无需重定向。这样就减少了客户端和服务器之间的双重往返,并且请求经过网格加密。因此,通过配置Istio,就可以获得TLS发起的好处,而无需更改代码行。