Knative Apache Kafka 代理,隔离数据平面 ¶
发布时间:2023-02-07, 修订时间:2024-01-17
Knative Apache Kafka 代理,隔离数据平面¶
作者:Ali Ok,Red Hat 首席软件工程师
在本博文中,您将了解如何配置 Knative 的 Apache Kafka 代理以隔离数据平面模式。
用于 Apache Kafka 的 Knative 代理实现 是 Knative 代理 API 的 Kafka 本地实现,它提供了一些比使用基于通道的 Knative 代理实现更好的改进,例如减少网络跳跃、支持任何 Kafka 版本以及与 Apache Kafka 更好地集成,以便更好地适应代理和触发器模型。
此外,此代理类支持两种数据平面模式:共享和隔离。
什么是数据平面?¶
为了更好地概述,了解什么是数据平面非常重要。
Knative 的 Apache Kafka 代理具有两个平面,类似于许多其他 Knative 和 Kubernetes 组件。
控制平面是控制器组件的集合。这些控制器基于用户创建的自定义对象来管理数据平面。在这种情况下,控制平面管理的自定义对象是 Broker
和 Trigger
。
数据平面是与 Apache Kafka 和订阅者(触发的目标)通信的组件的集合,它们基于控制平面提供的配置进行通信。Knative Kafka 代理数据平面中有两个组件
- Ingress 是通过打开 HTTP 端点来监听事件的组件。然后,它将事件转发到 Apache Kafka 主题以进行持久化以及同步消费和生成事件的节奏。
- Dispatcher 是从 Apache Kafka 主题接收事件并将其调度到使用
Trigger
API 订阅的订阅者的组件。
共享数据平面¶
当使用 Kafka
的代理类时,控制平面不会创建新的数据平面。相反,它会配置现有数据平面以完成已创建代理的 ingress 和 dispatch 任务。
共享数据平面模式下的 Knative Kafka 代理在 这篇 博文中进行了演示。
如果您按照这篇文章操作,您将看到 Kafka 代理的数据平面是在 knative-eventing
命名空间中创建的
kubectl get pods -n knative-eventing
NAME READY STATUS RESTARTS AGE
eventing-controller-7b95f495bf-dkqtl 1/1 Running 0 2h4m
eventing-webhook-8db49d6cc-4f847 1/1 Running 0 2h4m
kafka-broker-dispatcher-859d684d7d-frw6p 1/1 Running 0 2h4m **<-- Dispatcher**
kafka-broker-receiver-67b7ff757-rk9b6 1/1 Running 0 2h4m **<-- Ingress**
kafka-controller-7cd9bd8649-d62dh 1/1 Running 0 2h4m
kafka-webhook-eventing-f8c975b99-vc969 1/1 Running 0 2h4m
具体来说,Knative Kafka 代理数据平面包含 kafka-broker-dispatcher
和 kafka-broker-receiver
pod,它们在所有代理自定义对象之间共享。当创建另一个 Broker
时,控制平面不会创建任何新的部署。
如果您 kubectl get
Broker
对象,您将看到它们的地址使用 knative-eventing
命名空间中的名为 kafka-broker-ingress
的 Kubernetes Service
。两个代理的地址都使用主机名 kafka-broker-ingress.knative-eventing.svc.cluster.local
。
kubectl get brokers.eventing.knative.dev -A
NAMESPACE NAME URL AGE READY REASON
default my-demo-kafka-broker http://kafka-broker-ingress.knative-eventing.svc.cluster.local/default/my-demo-kafka-broker 2h6m True
other other-kafka-broker http://kafka-broker-ingress.knative-eventing.svc.cluster.local/other/other-kafka-broker 2h6m True
由于使用相同的 ingress 服务和相同的 ingress 部署,因此 URL 路径用于识别发布到服务的任何事件的目标代理。对于 default
命名空间中的 my-demo-kafka-broker
代理,使用 /default/my-demo-kafka-broker
。对于 other
命名空间中的 other-kafka-broker
代理,使用 /other/other-kafka-broker
。
隔离数据平面¶
在按照 这篇 博文中的说明创建开发环境 Apache Kafka 和 Knative Kafka 代理之后,您就可以开始尝试 Knative Kafka 代理的隔离数据平面模式,因为此模式默认受支持。
首先,您需要创建一个包含代理配置的 configmap。在这种情况下,我们不能依赖于之前博文中在 knative-eventing
命名空间中创建的集群级 configmap。
与该教程中创建的全局 kafka-broker-config
configmap 类似,我们将创建一个 configmap,但它在用户命名空间 default
中。在隔离数据平面模式下,我们需要在与代理相同的命名空间中拥有代理的配置。
cat <<-EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: kafka-broker-config
namespace: default
data:
default.topic.partitions: "10"
default.topic.replication.factor: "1"
bootstrap.servers: "my-cluster-kafka-bootstrap.kafka:9092"
EOF
现在,我们创建代理,它使用类 KafkaNamespaced
,并且也使用我们刚刚创建的配置
cat <<-EOF | kubectl apply -f -
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
annotations:
eventing.knative.dev/broker.class: KafkaNamespaced
name: broker-isolated-data-plane
namespace: default
spec:
config:
apiVersion: v1
kind: ConfigMap
name: kafka-broker-config
namespace: default
EOF
当我们检查创建 Broker
对象的用户命名空间时,我们将看到创建的数据平面 pod
kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
kafka-broker-dispatcher-8497dd6fb6-h8kdg 1/1 Running 0 15s
kafka-broker-receiver-84ff47fcd9-cv8j8 1/1 Running 0 15s
与数据平面部署类似,我们还将看到用于 Broker
对象的不同服务。因此,代理的地址将使用与 knative-eventing
命名空间中的 kafka-broker-ingress
服务不同的服务。
kubectl get brokers.eventing.knative.dev broker-isolated-data-plane -n default
NAME URL AGE READY REASON
broker-isolated-data-plane http://kafka-broker-ingress.default.svc.cluster.local/default/broker-isolated-data-plane 37s True
在隔离数据平面模式下,每个命名空间都会创建一个新的数据平面,而不是每个 Broker
对象。如果我们在同一个命名空间中创建另一个 Broker
对象,它将使用相同的数据平面
cat <<-EOF | kubectl apply -f -
apiVersion: eventing.knative.dev/v1
kind: Broker
metadata:
annotations:
eventing.knative.dev/broker.class: KafkaNamespaced
name: other-broker-isolated-data-plane
namespace: default
spec:
config:
apiVersion: v1
kind: ConfigMap
name: kafka-broker-config
namespace: default
EOF
不会创建新的数据平面 pod
kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
kafka-broker-dispatcher-8497dd6fb6-h8kdg 1/1 Running 0 72s
kafka-broker-receiver-84ff47fcd9-cv8j8 1/1 Running 0 72s
最后,当命名空间中 所有 使用类 KafkaNamespaced
的 Broker
对象都被删除时,数据平面将被删除
kubectl delete brokers.eventing.knative.dev -n default --all
kubectl get pods -n default
No resources found in default namespace.
用例¶
虽然共享数据平面方法适用于大多数情况,但在某些情况下您可能希望数据平面不被共享。
一个用例是,您可能不希望位于 knative-eventing
命名空间中的调度器与其他命名空间中的订阅者进行通信,或者类似地,您可能不希望单个 ingress 部署与多个 Apache Kafka 系统进行通信。显然,隔离数据平面模式在用户命名空间中创建调度器和接收器,因此通信仅限于命名空间。
另一种情况是当你发现潜在的 noisy neighbor 问题。可能会有一些代理实例接收了大量的负载,这会降低其他代理的性能。由于数据平面是按命名空间创建的,你可以创建多个命名空间并在每个命名空间中部署代理。这样,你就可以隔离每个代理实例的负载。
最后,另一个用例是当你想使用 Istio 以自助方式限制流量时。正如使用 JSON Web Token (JWT) 和 Istio 来保护 Knative 代理中所述,你可以使用 Istio 根据代理地址的 URL 路径来限制流量。但是,对于共享数据平面方法,需要在 knative-eventing
命名空间中添加 Istio 注射标签 istio-injection=enabled
。类似地,需要在 knative-eventing
命名空间中创建 AuthorizationPolicy
对象,因为代理服务是在那里创建的。用户可能没有权限修改 knative-eventing
命名空间。而在隔离数据平面模式下,用户可以在自己的命名空间中以自助方式执行必要的标记和对象创建。
结论¶
在这篇博文中,我们了解了如何使用新的 KafkaNamespaced
代理类,使 Knative 的 Apache Kafka 代理能够为每个命名空间创建隔离的数据平面。我们已经看到了隔离数据平面模式可能在某些情况下有用。
同样重要的是要注意,尽管隔离数据平面方法在某些情况下很有用,但它更消耗资源。因此,建议使用共享数据平面方法,除非你有充分的理由使用隔离数据平面方法。
有关 KafkaNamespaced
代理类、其限制和配置选项的更多信息,请参阅文档。