如何从Istio应用连接Kubernetes集群内的RabbitMQ服务?
这个问题的核心原因其实很明确:你看到的{bad_header,<<22,3,1,0,222,1,0,0>>}错误,其中的二进制数据是TLS Client Hello握手包的起始标识。这说明Istio Sidecar自动对发往RabbitMQ的流量启用了mTLS加密,但你的RabbitMQ并没有配置TLS支持,所以无法解析这个加密的请求头,导致连接被关闭。
之前你配置的ServiceEntry其实不是问题的关键——因为RabbitMQ在同一个Kubernetes集群内,Istio默认应该能发现跨命名空间的服务,问题出在流量被加密而RabbitMQ不识别。下面是具体的解决方案:
1. 禁用到RabbitMQ的mTLS流量
你需要告诉Istio Sidecar,不对发往RabbitMQ的流量做加密处理,有两种方式可以实现:
方式一:在应用命名空间配置DestinationRule
针对应用所在的命名空间,创建一个DestinationRule,指定所有RabbitMQ相关的服务/ Pod使用明文流量:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: rabbitmq-disable-mtls namespace: <你的应用命名空间> spec: host: "*.rabbitmq.svc.cluster.local" trafficPolicy: tls: mode: DISABLE
这个配置会匹配所有rabbitmq命名空间下的服务FQDN,让Sidecar发送明文TCP/AMQP流量。
方式二:在RabbitMQ命名空间配置PeerAuthentication
如果希望全局豁免RabbitMQ的mTLS要求,可以在RabbitMQ所在的rabbitmq命名空间创建PeerAuthentication(Istio 1.1.9使用v1alpha1版本API):
apiVersion: security.istio.io/v1alpha1 kind: PeerAuthentication metadata: name: rabbitmq-no-mtls namespace: rabbitmq spec: mtls: mode: DISABLE
这个配置会让Istio不对rabbitmq命名空间内的任何服务要求mTLS认证。
2. 优化应用连接方式(可选)
建议你的应用使用RabbitMQ的Service FQDN(比如rabbitmq-rabbitmq-ha.rabbitmq.svc.cluster.local,这是helm stable/rabbitmq-ha默认创建的Service)来连接,而不是直接连接单个Pod的FQDN。这样既可以利用Kubernetes Service的负载均衡能力,也能让Istio更顺畅地处理流量路由。
3. 验证修复效果
应用重启后,查看RabbitMQ的日志,如果看到类似以下内容,说明连接成功:
2019-06-19 09:40:39.538 [info] <0.32110.48> accepting AMQP connection <0.32110.48> (10.233.122.234:47530 -> 10.233.122.85:5672) 2019-06-19 09:40:39.539 [info] <0.32110.48> connection <0.32110.48> (10.233.122.234:47530 -> 10.233.122.85:5672): connection established
内容的提问来源于stack exchange,提问作者Naphta

