5.5.5 出口流量的TLS发起

在一些安全要求下,集群内的应用服务必须加密所有外部流量。使用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发起的好处,而无需更改代码行。