Kubernetes 集群上的 Kafka 与 Istio

Posted

技术标签:

【中文标题】Kubernetes 集群上的 Kafka 与 Istio【英文标题】:Kafka on kubernetes cluster with Istio 【发布时间】:2020-10-30 05:01:31 【问题描述】:

我有带有 Istio v1.6.4 的 k8s 集群。 Sidecar 注入默认是禁用的。 我在这个 k8s 上运行了 Kafka 集群,并安装了 strimzi kafka 操作员。 当 kafka 和客户端 pod 没有注入 Istio-proxy 时,Kafka 集群可以正常工作。 我的问题: 当我使用 kafka 客户端创建一个 pod 并注入 Istio-proxy 时,我无法连接到 Kafka 集群。 客户端日志:

java.io.IOException: Connection reset by peer

在服务器端: org.apache.kafka.common.network.InvalidReceiveException: Invalid receive (size = 369295616 larger than 104857600)

在谷歌搜索和检查 Istio-proxy 日志后,发现问题在于 Istio-proxy 使用 TLS 连接到 kafka 明文端点。 我可以通过使用mtls.mode: DISABLED 设置默认 PeerAuthentication 来解决此问题,但我不想为其设置全局设置。

如果我创建一个简单的 k8s 服务并在运行 kafka 服务器的 pod 上运行 netcat“服务器”并在运行 kafka 客户端的 pod 上运行 netcat“客户端”,这有什么奇怪的 - 一切正常。

我有两个问题:

    为什么 kafka Istio-proxy 在连接到 Kafka 时表现不同 集群而不是其他 TCP 连接(比如使用 nc)? 如何只为一台主机禁用 mtls?我在玩 PeerAuthentication 但没有运气...

【问题讨论】:

据我了解,您需要为这台主机添加带有trafficPolicy: tls: mode: SIMPLE 的目标规则。查看文档here。让我知道这是否能解决问题。 感谢您的帮助!不幸的是,它没有帮助。我尝试了简单模式和禁用模式。对我有用的唯一选项是使用spec.mtls.mode: DISABLE 的全局 PeerAuthentication。 1.您部署的所有内容都在默认命名空间中? 2.可以显示客户端服务和目标规则yaml吗? 3. 如documentation 中提到的那样,对某个命名空间下的所有工作负载进行对等身份验证,而不是全局进行呢? 4.Kafka服务是否暴露为headless service? 问题 4. 指出了解决方案。 Strimzi kafka 创建了 2 个服务:kafka-bootstrap 是常规服务(带有 IP)和 kafka-brokers 是无头服务。我使用bootstrap 并切换到brokers(与DestinationRule 一起)解决了这个问题。谢谢!会写一个详细的答案。 【参考方案1】:

在jt97 的帮助下,我能够解决这个问题。

正如我所写,我正在使用Strimzi Operator 在 k8s 上安装 kafka 集群。它创建了 2 个服务:

kafka-bootstrap - ClusterIP 的常规服务 kafka-brokers - 无头服务。

在我的例子中,服务的全名分别是 kafka-kafka-operated-kafka-bootstrapkafka-kafka-operated-kafka-brokers

我创建了一个 DestinationRule:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: kafka-no-tls
spec:
  host: "kafka-kafka-operated-kafka-brokers"
  trafficPolicy:
    tls:
      mode: DISABLE

并在连接kafka时使用了无头服务:

kafka-topics --bootstrap-server kafka-kafka-operated-kafka-brokers:9092 --list
__consumer_offsets
_schemas

它按预期工作。

顺便说一句,将 tls.mode 设置为 SIMPLE 没有帮助。

说实话,我仍然不明白为什么在这种特殊情况下,Istio-proxy 默认(没有 DestinationRule)会尝试连接 TLS - 根据documentation:

默认情况下,Istio 会跟踪迁移到 Istio 代理的服务器工作负载,并将客户端代理配置为自动向这些工作负载发送双向 TLS 流量,并向没有 Sidecar 的工作负载发送纯文本流量。

【讨论】:

对于使用bitnami/kafka的用户,上面DestinationRule中你想要的服务是kafka-headless.<namespace>.svc.cluster.local

以上是关于Kubernetes 集群上的 Kafka 与 Istio的主要内容,如果未能解决你的问题,请参考以下文章

使用 SSL 的 Kubernetes 上的 Kafka

Kubernetes 多节点上的 Kafka

Kafka核心技术与实战——06 | Kafka线上集群部署方案怎么做?

Kubernetes 集群中的 Kafka - 如何从 Kubernetes 集群外部发布/使用消息

远程访问运行在 kubernetes 中的 Kafka

如何在kubernetes上构建kafka集群后公开kafka以进行外部访问?