1.14. 管理服务网格中的流量
Red Hat OpenShift Service Mesh 可让您控制服务间的流量和 API 调用流。服务网格中的一些服务可能需要在网格内进行通信,其他服务则需要隐藏。您可以管理流量来隐藏特定后端服务、公开服务、创建测试或版本部署,或者在一组服务中添加安全层。
1.14.1. 使用网关
您可以使用网关来管理入站和出站流量,以指定您想要进入或离开网格的流量。网关配置适用于在网格边缘运行的独立的 Envoy 代理,而不是与您的服务负载一同运行的 sidecar Envoy 代理。
与控制进入系统的其他流量的机制不同,如 Kubernetes Ingress API,Red Hat OpenShift Service Mesh 网关可让您获得流量路由的全部功能和灵活性。Red Hat OpenShift Service Mesh 网关资源可层 4-6 负载均衡属性,如端口,以公开和配置 Red Hat OpenShift Service Mesh TLS 设置。您可以将常规 Red Hat OpenShift Service Mesh 虚拟服务绑定到网关,并像服务网格中的其它数据平面流量一样管理网关流量,而不将应用程序层流量路由(L7)添加到相同的 API 资源中。
网关主要用于管理入口流量,但您也可以配置出口网关。出口网关可让您为离开网格的流量配置专用退出节点。这可让您限制哪些服务可以访问外部网络,这会为您的服务网格增加安全控制。您还可以使用网关配置纯内部代理。
网关示例
网关资源描述了在网格边缘运行的负载均衡器,接收进入或传出的 HTTP/TCP 连接。该规范描述应当公开的一组端口,要使用的协议类型,以及负载均衡器的 SNI 配置等。
以下示例显示了外部 HTTPS 入口流量的网关配置示例:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: ext-host-gwy spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 443 name: https protocol: HTTPS hosts: - ext-host.example.com tls: mode: SIMPLE serverCertificate: /tmp/tls.crt privateKey: /tmp/tls.key
这个网关配置允许来自 ext-host.example.com
的 HTTPS 流量通过端口 443 进入网格,但没有为流量指定路由。
要指定路由并让网关按预期工作,还必须将网关绑定到虚拟服务。您可以使用虚拟服务的网关字段进行此操作,如下例所示:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: virtual-svc spec: hosts: - ext-host.example.com gateways: - ext-host-gwy
然后,您可以使用外部流量的路由规则配置虚拟服务。
1.14.1.1. 管理入口流量
在 Red Hat OpenShift Service Mesh 中,Ingress Gateway 允许监控、安全性和路由规则等功能应用到进入集群的流量。使用 Service Mesh 网关在服务网格外公开服务。
1.14.1.1.1. 决定入口 IP 和端口
入口配置根据您的环境是否支持外部负载均衡器而有所不同。在集群的入口 IP 和端口中设置一个外部负载均衡器。要确定是否为外部负载均衡器配置了集群的 IP 和端口,请运行以下命令。在本例中,istio-system
是 Service Mesh control plane 项目的名称。
$ oc get svc istio-ingressgateway -n istio-system
该命令会返回命名空间中每个项目的 NAME
、TYPE
、CLUSTER-IP
、EXTERNAL-IP
、PORT(S)
和 AGE
。
如果设置了 EXTERNAL-IP
值,您的环境会有一个外部负载均衡器,供您用于入口网关。
如果 EXTERNAL-IP
值是 <none>
,或 <pending>
,则您的环境不会为入口网关提供外部负载均衡器。您可以使用服务的节点端口访问网关。
1.14.1.1.1.1. 使用负载均衡器确定入口端口
如果您的环境有外部负载均衡器,请按照以下步骤操作。
流程
运行以下命令来设置入口 IP 和端口。此命令在终端中设置变量。
$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
运行以下命令来设置入口端口。
$ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
运行以下命令来设置安全入口端口。
$ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
运行以下命令来设置 TCP 入口端口。
$ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].port}')
在某些情况下,负载均衡器可能会使用主机名而不是 IP 地址公开。在这种情况下,入口网关的 EXTERNAL-IP
值不是一个 IP 地址。相反,这是一个主机名,上一命令无法设置 INGRESS_HOST
环境变量。
在这种情况下,使用以下命令更正 INGRESS_HOST
值:
$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
1.14.1.1.1.2. 确定没有负载均衡器的入口端口
如果您的环境没有外部负载均衡器,请确定入口端口并改用节点端口。
流程
设置入口端口。
$ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
运行以下命令来设置安全入口端口。
$ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
运行以下命令来设置 TCP 入口端口。
$ export TCP_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="tcp")].nodePort}')
1.14.1.2. 配置入口网关
入口网关是在网格边缘运行的负载均衡器,接收传入的 HTTP/TCP 连接。它配置公开的端口和协议,但不包括任何流量路由配置。入口流量的流量路由改为使用路由规则配置,这与内部服务请求相同。
以下步骤演示了如何创建网关并配置 VirtualService
,以在 Bookinfo 示例应用程序中将服务公开给路径 /productpage
和 /login
的外部流量。
流程
创建网关以接受流量。
创建 YAML 文件,并将以下 YAML 复制到其中:
网关 gateway.yaml 示例
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
应用 YAML 文件。
$ oc apply -f gateway.yaml
创建
VirtualService
对象来重写主机标头。创建 YAML 文件,并将以下 YAML 复制到其中:
虚拟服务示例
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage port: number: 9080
应用 YAML 文件。
$ oc apply -f vs.yaml
测试网关和 VirtualService 已正确设置。
设置网关 URL。
export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}')
设置端口号。在本例中,
istio-system
是 Service Mesh control plane 项目的名称。export TARGET_PORT=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.port.targetPort}')
测试已明确公开的页面。
curl -s -I "$GATEWAY_URL/productpage"
预期的结果为
200
。