使用Gateway API访问Kafka - Strimzi
背景
访问 Kafka
在之前的博客中,Jakub Scholz 介绍了 Strimzi 如何通过以下方式实现从 Kubernetes 集群外部访问 Kafka:
- 使用
NodePort服务 - OpenShift 的
Route LoadBalancer服务Ingress资源
然而,这些方法存在一些限制:
- Kafka 客户端需要直接访问特定的代理,因此简单地通过负载均衡器将请求分散到 Kafka 集群可能导致错误的结果。
- Kafka 协议并非基于 HTTP,这意味着需要一些特殊的处理才能与简单的
Ingress配合使用。
网关 API
网关 API 是一种比传统 Ingress 更灵活、可扩展的南北流量解决方案。虽然完整的 Gateway API 讨论超出了本文范围,但以下两种资源与 Kafka 的集成尤为重要:
- TCPRoute:用于代理未加密的 TCP 流量。
- TLSRoute:用于控制加密的 TCP 流量。
需要注意的是,HTTPRoute 和 GRPCRoute 并不适用于 Kafka,因为 Kafka 不使用基于 HTTP 或 gRPC 的协议。
本文将重点介绍 TLSRoute,特别是使用 passthrough TLS 模式,其中 TLS 连接不会在网关控制器处终止,而是直接在 Kafka 代理处终止。
实践操作
如果您希望快速上手,可以克隆以下 GitHub 仓库,其中包含所有相关代码:GitHub 仓库。
本地环境配置
在本示例中,我们将通过一些技巧使 KIND 集群支持本地开发,并通过 TLS 加密连接访问 Kafka。以下是主要步骤:
- 为 Kafka 代理创建一个包含主机名的证书。
- 在
TLSRoute网关控制器能够路由流量到 Kafka 之前,设置主机名到 KIND 集群的流量重定向。
配置步骤
- 创建一个自签名证书,适用于
*.strimzi.gateway.api.test,并配置 Kafka 客户端信任该证书。 - 在本地的
/etc/hosts文件中,将以.strimzi.gateway.api.test结尾的 URL 映射到本地主机。 - 将本地终端的端口
9092映射到 KIND 节点的端口30992(这是运行在本地的 Docker 容器)。 - 部署 Envoy 网关 Pod,并通过 Kubernetes 的
NodePort服务将端口30992映射到 Envoy 网关 Pod 的端口9092。
通过以上配置,流量可以像在公共网络中运行一样被路由到 KIND 集群。网络架构如下图所示:
流量路径如下:
- 从本地终端向
boostrap.strimzi.gateway.api.test:9092发出请求。 /etc/hosts文件将请求重定向到localhost。- KIND 集群的 Docker 容器将主机端口
9092映射到容器端口30992。 - Kubernetes 的
NodePort服务将流量从端口30992路由到 Envoy 网关 Pod。 - 使用
TLSRoute配置 Envoy,将流量路由到 Kafka 代理。
KIND 集群设置
首先,创建一个 KIND 集群,使用以下 kind-config.yaml 文件:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30992
hostPort: 9092
在该配置中,hostPort: 9092 被映射到 containerPort: 30992,这意味着本地端口 9092 会通过 Docker 转发到 Kubernetes 节点的端口 30992。
安装 Envoy Gateway
接下来,使用 helm 安装 Envoy Gateway。注意,Envoy Gateway 的工具(如 egctl)通常要求安装在 envoy-gateway-system 命名空间中。
安装完成后,需要部署一个具有特定 GatewayClass 的 Gateway,以监听正确的 NodePort。在创建 Gateway 之前,需先配置 GatewayClass,类似于 IngressClass,它定义了网关控制器可以协调的网关类型。
安装 Strimzi 和证书管理器
安装 Strimzi 和证书管理器后,创建一个自签名的证书和相关的 CA。以下是主要步骤:
-
在
/etc/hosts中添加以下内容:127.0.0.1 bootstrap.strimzi.gateway.api.test
127.0.0.1 broker-0.strimzi.gateway.api.test
127.0.0.1 broker-1.strimzi.gateway.api.test
127.0.0.1 broker-2.strimzi.gateway.api.test -
确保流量能够到达 Envoy Gateway Pod,并配置 Kafka 集群通告上述端点。
部署 Kafka 集群
在 KRaft 模式下创建 Kafka 集群,配置如下:
- 集群包含 1 个控制器和 3 个代理。
- 使用
scram-sha-512身份验证保护监听器。 - 使用证书管理器生成的自签名证书,而非 Strimzi 自动生成的证书。
以下是 Kafka 集群的资源定义:
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-cluster
spec:
kafka:
version: 3.9.0
replicas: 3
listeners:
- name: external
port: 9092
type: external
tls: true
authentication:
type: scram-sha-512
创建 KafkaNodePool
为控制器和代理创建 KafkaNodePool,确保控制器节点 ID 从 0 开始,代理从 10 开始。
创建 TLSRoute
为 Kafka 集群创建以下 TLSRoute:
- 一个指向引导服务的
TLSRoute。 - 每个代理对应一个
TLSRoute。
以下是 TLSRoute 的示例定义:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: kafka-bootstrap
spec:
rules:
- backendRefs:
- name: kafka-bootstrap-service
创建 Kafka 客户端配置
为了访问 Kafka,需要以下配置:
- 从
KafkaUser的Secret中下载sasl.jaas.config。 - 下载由证书管理器生成的 CA 公共证书。
- 将 CA 证书转换为 JKS 格式。
以下脚本可帮助生成客户端配置文件:
#!/bin/bash
# 下载 Kafka 配置和证书
kubectl get secret kafka-user-secret -o jsonpath='{.data.sasl.jaas.config}' | base64 -d > /tmp/sasl.jaas.config
kubectl get secret kafka-ca-cert -o jsonpath='{.data.ca.crt}' | base64 -d > /tmp/ca.crt
keytool -import -trustcacerts -file /tmp/ca.crt -keystore /tmp/kafka-client.jks -storepass changeit
访问 Kafka
最后,使用 Strimzi 提供的 Docker 镜像和脚本访问 Kafka:
-
在一个终端中启动消费者:
kafka-console-consumer.sh --bootstrap-server bootstrap.strimzi.gateway.api.test:9092 --topic test-topic -
在另一个终端中启动生产者:
kafka-console-producer.sh --bootstrap-server bootstrap.strimzi.gateway.api.test:9092 --topic test-topic
结论
本文展示了如何利用 Envoy Gateway 和 Gateway API 安全地访问 Kafka 集群。这种方法可能在未来成为 Kubernetes 网络的标准。虽然目前 Strimzi 对 Gateway API 的支持仍需手动配置,但未来可能会实现原生支持。
原文链接: https://strimzi.io/blog/2024/08/16/accessing-kafka-with-gateway-api/
最新文章
- OWASP API安全十大风险简介 – Graylog
- 使用Gateway API访问Kafka – Strimzi
- 如何测试实时视频流API性能 – FastPix
- 如何用 OpenAPI 在 Express 中构建更好的 API
- 使用 Intersection Observer API 实现懒加载 – LogRocket 博客
- API在社交媒体中的应用
- 实战拆解:如何使用 ChatGPT Agent 实现自动化多步骤任务
- 使用AI进行API设计
- 深入解析API Gateway:微服务架构中的关键组件及其重要功能
- 如何获取巴法云开放平台 API Key 密钥(分步指南)
- 没有中国银行卡怎么用微信支付?探索国际用户的支付新思路
- Python字典(dict)完全指南