将通过Egress gateway进行HTTPS流量透传(由应用程序发起的TLS)。在相应的ServiceEntry、Egress gateway以及VirtualService中指定端口443,协议TLS。
修改ServiceEntry定义如下:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: test
spec:
hosts:
- istio.io
ports:
- number: 80
name: http-port
protocol: HTTP
- number: 443
name: tls
protocol: TLS
resolution: DNS
验证ServiceEntry是否已正确生效。发送HTTPS请求到https://istio.io:
kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - https://istio.io HTTP/2 200 cache-control: public, max-age=0, must-revalidate content-type: text/html; charset=UTF-8 date: Mon, 21 Jan 2019 20:22:55 GMT etag: "660e4bd7ded5a3a85a24118433d3f4b2-ssl" strict-transport-security: max-age=31536000 x-nf-srv-version: 45aaffea081549dd03a2dfff644cc25cf522edbd age: 120442 content-length: 25833 server: Netlify x-nf-request-id: f6a3e5cf-9f20-4983-9a91-d0e319e89bcd-9606565
为istio.io创建端口443、TLS协议的Egress gateway。除此之外还创建了一个DestinationRule和VirtualService来引导流量通过Egress gateway与外部服务通信。
如果在Istio中启用了双向TLS认证,请按照如下定义进行更新:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: https
protocol: HTTPS
hosts:
- istio.io
tls:
mode: MUTUAL
serverCertificate: /etc/certs/cert-chain.pem
privateKey: /etc/certs/key.pem
caCertificates: /etc/certs/root-cert.pem
- port:
number: 443
name: tls
protocol: TLS
hosts:
- istio.io
tls:
mode: MUTUAL
serverCertificate: /etc/certs/cert-chain.pem
privateKey: /etc/certs/key.pem
caCertificates: /etc/certs/root-cert.pem
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-test
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: test
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 80
tls:
mode: ISTIO_MUTUAL
sni: istio.io
- port:
number: 443
tls:
mode: ISTIO_MUTUAL
sni: istio.io
如果没有启用双向TLS认证:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- istio.io
- port:
number: 443
name: tls
protocol: TLS
hosts:
- istio.io
tls:
mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-sample
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: test
将HTTP请求重新发送到https://istio.io,输出应与之前相同。此时检查Egress gateway代理的统计信息,并查看与我们对istio.io的请求相对应的计数器。如果Istio部署在istio-system命名空间中,则打印计数器的命令是:
kubectl exec -it $(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='
{.items[0].metadata.name}') -c istio-proxy -n istio-system -- curl -s localhost:
15000/stats | grep istio.io.upstream_cx_total
cluster.outbound|443||istio.io.upstream_cx_total: 5
cluster.outbound|80||istio.io.upstream_cx_total: 4
如果再执行几个额外的请求,应该会看到每次请求之后上面的计数器都会加1。
最后,清除上述定义的Egress gateway:
kubectl delete -f egressgateway/serviceentry.yaml kubectl delete -f egressgateway/gw-dr.yaml kubectl delete -f egressgateway/vs.yaml kubectl delete -f egressgateway/sleep.yaml
在Istio中定义的Egress gateway,本身并不会对运行Egress gateway服务的节点进行任何特殊处理。集群管理员或云提供商可以在专用节点上部署Egress gateway,并引入额外的安全措施,使这些节点比网格的其余部分更安全。
另外要注意的是,实际上Istio本身无法安全地强制将所有Egress流量流经Egress gateway,Istio仅通过其Sidecar代理启用此类流量。攻击者只要绕过Sidecar代理,就可以不经Egress gateway直接与网格外面的服务进行通信,从而逃避了Istio的控制和监控。集群管理员或云供应商必须确保所有外发流量都从Egress gateway途径发起。
需要用Istio之外的机制来满足这一需求,例如:
·使用防火墙拒绝所有来自Egress gateway以外的流量。
·通过Kubernetes网络策略也能禁止所有不是从Egress gateway发起的Egress流量。
·管理员或者云供应商还可以对网络进行限制,让运行应用的节点只能通过Gateway来访问外部网络。要完成这一限制,可以只给Gateway pod分配公网IP,或者可以配置NAT设备,丢弃来自Egress gateway以外pod的流量。