コンテンツへスキップ

分離されたデータプレーンを持つ Knative Apache Kafka Broker

公開日: 2023-02-07 、  改訂日: 2024-01-17

分離されたデータプレーンを持つ Knative Apache Kafka Broker

著者: Ali Ok, Red Hat のプリンシパルソフトウェアエンジニア

このブログ投稿では、分離されたデータプレーンモードで Knative の Apache Kafka Broker を構成する方法を学びます。

Apache Kafka 用の Knative Broker の実装は、Knative Broker API の Kafka ネイティブ実装であり、ネットワークホップの削減、任意の Kafka バージョンのサポート、Broker および Trigger モデル用の Apache Kafka とのより優れた統合など、チャネルベースの Knative Broker 実装の使用と比較して改善点を提供します。

さらに、このブローカークラスは、共有と分離の 2 つのデータプレーンモードをサポートしています。

データプレーンとは何ですか?

より良い概要を説明するために、データプレーンとは何かを理解することが重要です。

Knative の Apache Kafka Broker には、他の多くの Knative および Kubernetes コンポーネントと同様に、2 つのプレーンがあります。

コントロールプレーンは、コントローラーであるコンポーネントの集合です。これらのコントローラーは、ユーザーが作成したカスタムオブジェクトに基づいてデータプレーンを管理します。この場合、コントロールプレーンによって管理されるカスタムオブジェクトは、BrokerTrigger です。

データプレーンは、コントロールプレーンによって与えられた構成に基づいて、Apache Kafka およびサブスクライバー (トリガーのターゲット) と通信するコンポーネントの集合です。Knative Kafka Broker データプレーンには 2 つのコンポーネントがあります

  • Ingress は、HTTP エンドポイントを開いてイベントをリッスンするコンポーネントです。次に、イベントを Apache Kafka トピックに転送して、永続化とイベントの消費と生成のペースの同期を行います。
  • Dispatcher は、Apache Kafka トピックからイベントを受信し、Trigger API を使用してサブスクライブされたサブスクライバーにディスパッチするコンポーネントです。

共有データプレーン

Kafka のブローカークラスを使用する場合、コントロールプレーンは新しいデータプレーンを作成しません。代わりに、作成されたブローカーのイングレスおよびディスパッチの役割を果たすように既存のデータプレーンを構成します。

共有データプレーンモードの Knative Kafka Broker は、このブログ投稿で実証されています。

この記事に従うと、Kafka Broker のデータプレーンが 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 Broker データプレーンは、kafka-broker-dispatcher ポッドと kafka-broker-receiver ポッドで構成されており、これらはすべてのブローカーカスタムオブジェクト間で共有されます。別の Broker が作成されると、コントロールプレーンは新しいデプロイメントを作成しません。

Broker オブジェクトを kubectl get すると、そのアドレス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

同じイングレスサービスとイングレスデプロイメントが使用されているため、サービスにポストされたイベントのターゲットブローカーを識別するために URL パスが使用されます。default 名前空間の my-demo-kafka-broker ブローカーの場合、/default/my-demo-kafka-broker が使用されます。other 名前空間の other-kafka-broker ブローカーの場合、/other/other-kafka-broker が使用されます。

分離されたデータプレーン

このブログ投稿で説明されているように、開発環境の Apache Kafka と Knative Kafka Broker を作成した後、このモードはすぐにサポートされているため、分離されたデータプレーンモードで Knative Kafka Broker を試すことができます。

まず、ブローカーの構成を含む 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 オブジェクトが作成されたユーザー名前空間を確認すると、データプレーンポッドが作成されていることがわかります

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

新しいデータプレーンポッドは作成されません

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.

ユースケース

共有データプレーンのアプローチはほとんどの場合に適していますが、データプレーンを共有したくない場合もいくつかあります。

1つのユースケースは、knative-eventing名前空間にあるディスパッチャが、他の名前空間のサブスクライバーと通信することを望まない場合や、同様に、単一のイングレスデプロイメントが複数のApache Kafkaシステムと通信することを望まない場合です。明らかに、分離されたデータプレーンモードでは、ユーザーの名前空間にディスパッチャとレシーバーが作成されるため、通信は名前空間に制限されます。

もう1つのケースは、うるさい隣人問題の可能性が見られる場合です。膨大な量の負荷を受け取るブローカーインスタンスがあり、これが他のブローカーのパフォーマンスを低下させる可能性があります。データプレーンは名前空間ごとに作成されるため、複数の名前空間を作成し、各名前空間にブローカーをデプロイできます。これにより、各ブローカーインスタンスの負荷を分離できます。

最後に、もう1つのユースケースは、Istioを使用してセルフサービス方式でトラフィックを制限したい場合です。JSON Web Token (JWT)とIstioを使用してKnativeブローカーを保護するで説明されているように、Istioを使用してブローカーアドレスのURLパスに基づいてトラフィックを制限できます。ただし、共有データプレーンのアプローチでは、Istioインジェクションラベルistio-injection=enabledknative-eventing名前空間に追加する必要があります。同様に、ブローカーサービスが作成されるため、AuthorizationPolicyオブジェクトをknative-eventing名前空間に作成する必要があります。ユーザーはknative-eventing名前空間を変更する権限を持っていない可能性があります。ただし、分離されたデータプレーンモードでは、ユーザーは必要なラベリングとオブジェクト作成を自分の名前空間でセルフサービス方式で行うことができます。

結論

このブログ記事では、KnativeのApache Kafkaブローカーが名前空間ごとに分離されたデータプレーンを作成する新しいKafkaNamespacedブローカークラスの使用方法を見てきました。分離されたデータプレーンモードが役立つ可能性のあるユースケースをいくつか見てきました。

また、分離されたデータプレーンのアプローチは一部のケースで役立ちますが、より多くのリソースを消費することも理解しておくことが重要です。したがって、分離されたデータプレーンのアプローチを使用する正当な理由がない限り、共有データプレーンのアプローチを使用することをお勧めします。

KafkaNamespacedブローカークラス、その制限、および構成オプションの詳細については、ドキュメントをご覧ください。

サイトのトラフィックを理解するために、分析とクッキーを使用しています。当サイトの利用に関する情報は、その目的のためにGoogleと共有されます。詳細はこちら。