创建sleep客户端
apiVersion: v1 kind: ServiceAccount metadata: name: sleep --- apiVersion: v1 kind: Service metadata: name: sleep labels: app: sleep spec: ports: - port: 80 name: http selector: app: sleep --- apiVersion: apps/v1 kind: Deployment metadata: name: sleep spec: selector: matchLabels: app: sleep template: metadata: labels: app: sleep spec: serviceAccountName: sleep containers: - name: sleep image: pstauffer/curl imagePullPolicy: IfNotPresent ports: - containerPort: 80 command: - "/bin/sleep" - "3650d"
|
创建ServiceEntry
创建一个ServiceEntry,允许流量直接访问外部服务
apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: cnn spec: hosts: - edition.cnn.com ports: - number: 80 name: http protocol: HTTP resolution: DNS
|
我们通过在sleep客户端发送请求验证下ServiceEntry是否正确应用
kubectl exec -it sleep-f67b89b64-t42hv -- sh curl -sL -o /dev/null -D - http://edition.cnn.com/politics
|

我们可以看下访问egress pod的日志,发现是没有这个访问日志的输出的
kubectl log -f istio-egressgateway-7c9f7d5bd6-hcf2x -n istio-system
|

配置egress Gateway和destination rule
我们为edition.cnn.com端口80创建一个egress gateway ,并且为egress gateway指向一个destination rule
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-egressgateway spec: selector: istio: egressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - edition.cnn.com --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egressgateway-for-cnn spec: host: istio-egressgateway.istio-system.svc.cluster.local subsets: - name: cnn
|
配置VirtualService
将流量从sidercar引导到egress gateway,在从egress gateway引导到外部
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: direct-cnn-through-egress-gateway spec: hosts: - edition.cnn.com gateways: - istio-egressgateway - mesh # 内置 Gateway,代表网格中的所有 Sidecar http: - match: # 这一条规格匹配的是 “mesh” Gateway的流量 - gateways: - mesh port: 80 route: # 如果是 “mesh” Gateway 的流量,则转发到egress网关服务 - destination: host: istio-egressgateway.istio-system.svc.cluster.local subset: cnn - match: - gateways: - istio-egressgateway port: 80 route: - destination: host: edition.cnn.com port: number: 80 weight: 100
|
测试
通过sleep客户端访问 http://edition.cnn.com/politics
kubectl exec -it sleep-f67b89b64-t42hv -- sh curl -sL -o /dev/null -D - http://edition.cnn.com/politics
|

可以看到egress pod的日志中有访问输出
kubectl log -f istio-egressgateway-7c9f7d5bd6-hcf2x -n istio-system
|

会有人疑问,我直接通过ServiceEntry也可以直接访问外部服务,为什么还要如此麻烦将出站流量都经过egress gateway呢?其实,我个人觉得有以下原因:第一,并不是所有节点都可以访问外网的,如果pod所在的节点无法访问外网,直接通过ServerEntry是无法访问外网的,那么egress gateway可以统一管理出站流量,所有出站流量都经由egress gateway发送;第二,通过egress gateway管理出站流量,可以配置一些网络策略,例如Kubernetes网络策略可以禁止所有不是从 egress gateway 发起的出站流量。