如何通过Istio出口网关路由mssql流量



我正在尝试在Istio服务网格(AKS集群中的Istio 1.16.1)中运行。net 6演示应用程序。此应用程序使用位于集群外部的sqlserver 2019,我想通过出口网关路由所有出站流量,包括mssql。请注意,这个应用程序也使用OpenId Connect和keytab (Kerberos流量),我已经成功地通过出口网关路由了这些请求,但没有通过mssql流量。

我已经用istioctl和以下配置文件创建了服务网格

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: default
meshConfig:
accessLogFile: /dev/stdout
enableTracing: true
defaultConfig:
tracing:
sampling: 100
outboundTrafficPolicy:
mode: REGISTRY_ONLY
components:
pilot:
k8s:
nodeSelector:
agentpool: svcmaster
ingressGateways:
- name: istio-ingressgateway
enabled: true
k8s:
nodeSelector:
kubernetes.io/os: linux
egressGateways:
- name: istio-egressgateway
enabled: true
k8s:
nodeSelector:
kubernetes.io/os: linux  

下面是数据库的ServiceEntry

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: mssql-contoso-com
namespace: linux
spec:
hosts:
- mssql.contoso.com
addresses:
- 10.1.0.5
ports:
- number: 1433
name: mssql
protocol: TLS
- number: 443
name: tls
protocol: TLS
location: MESH_EXTERNAL
resolution: DNS

这是网关(它包括主机

)
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: egress-gateway
namespace: linux
spec:
selector:
istio: egressgateway
servers:
- port:
number: 443
name: tls
protocol: TLS
hosts:
- "adfs.contoso.com"
- "mssql.contoso.com"
tls:
mode: "PASSTHROUGH"
- port:
number: 80
name: tcp
protocol: TCP
hosts:
- "controller.contoso.com"

最后是VirtualService。我没有定义DestinationRule,因为它实际上是无用的,OIDC和Kerberos流量在没有它们的情况下可以正确路由,我在没有解决问题的情况下绝望地尝试添加它。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: "outgoing-mssql-traffic"
namespace: linux
spec:
hosts:
- mssql.contoso.com
gateways:
- egress-gateway
- mesh
tls:
- match:
- gateways:
- mesh
port: 1433
sniHosts:
- mssql.contoso.com
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 443
weight: 100
- match:
- gateways:
- egress-gateway
port: 443
sniHosts:
- mssql.contoso.com
route:
- destination:
host: mssql.contoso.com
port:
number: 1433
weight: 100

关于应用程序调用SQL Server的详细信息,我使用常规的SQLConnection与以下连接字符串:

Server=mssql.contoso.com;Initial Catalog=Demonstration;Integrated Security=true;TrustServerCertificate=true
结果,我在应用程序日志中得到以下错误:
Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)
---> System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer.
---> System.Net.Sockets.SocketException (104): Connection reset by peer
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count)

TLS握手失败。在查询sidecar容器和出口网关的日志时,无法看到数据库的流量。我还用Wireshark监视了SQLServer机器上的流量,但在端口1433上看不到TCP流量。

当虚拟服务被删除时,应用程序工作正常,因此问题实际上与通过出口网关的路由有关。

任何帮助或见解将不胜感激。

所以我在尝试不同的配置和检查Envoy日志时偶然发现了原因。Istio出口网关服务只公开两个端口(至少默认情况下):80和443。似乎每个端口只能服务一个VirtualService,并且是先到先得。我最后为mssql声明了VirtualService,所以它没有被服务。

此外,我必须切换到TCP路由。我无法使用TLS路由使其工作。

这是ServiceEntry:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: mssql-contoso-com
namespace: linux
spec:
hosts:
- mssql.contoso.com
addresses:
- 10.1.0.5
ports:
- number: 1433
name: mssql
protocol: TCP
- number: 80
name: tls
protocol: TCP
location: MESH_EXTERNAL
resolution: DNS

下面是VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: "outgoing-mssql-traffic"
namespace: linux
spec:
hosts:
- mssql.contoso.com
gateways:
- egress-gateway
- mesh
tcp:
- match:
- gateways:
- mesh
port: 1433
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 80
weight: 100
- match:
- gateways:
- egress-gateway
port: 80
route:
- destination:
host: mssql.contoso.com
port:
number: 1433
weight: 100

我想我将不得不部署几个出口网关或找到一种方法来添加端口到现有的。

最新更新