今天,我们很高兴地宣布Supertubes的1.0版本发布,这是Banzai Cloud通过利用云原生技术栈在Kubernetes上建立和运营生产就绪的Kafka集群的工具。
除了在Kubernetes上操作生产就绪的Kafka集群外,Supertubes还提供了一些便于在Kubernetes上采用Kafka的功能,如声明式ACL管理、模式注册表以及通过服务账户对应用程序进行认证和授权。在这篇文章中,我们将探讨1.0版本发布后增加的一些新功能。
supertubes install -a --no-demo-cluster --kubeconfig <path-to-k8s-cluster-kubeconfig-file>
我们将讨论的两个主要功能是。
- 支持设置和管理**Kafka Connect**集群
- 仪表盘,提供对用Supertubes管理的Kafka集群的可见性
Kafka Connect 🔗︎
Kafka Connect是一个工具,它允许在Apache Kafka和其他系统之间进行可扩展和可靠的数据流。Supertubes在部署Kafka Connect时包含了Confluent的社区连接器,并支持通过Schema Registry使用模式。
用Supertubes管理Kafka Connect集群和连接器 🔗︎
Supertubes可以自动部署Kafka Connect集群,并分别通过KafkaConnect自定义资源实例和KafkaConnector自定义资源实例创建连接器。
Imperative CLI 🔗︎
Supertubes CLI提供了部署Kafka Connect集群的命令,然后将连接器部署到这些集群。快速建立Kafka Connect集群的最简单方法是运行:
命令,这将建立一个具有默认设置的Kafka Connect集群,并链接到已配置的演示Kafka集群和已部署的Schema Registry实例。
其他的Kafka Connect集群可以通过以下命令创建,或者更新现有的集群。
supertubes cluster kafka-connect [command]
命令创建额外的Kafka Connect集群或更新现有的集群。
在Kafka Connect集群内运行的连接器可以通过:管理。
supertubes cluster kafka-connector [command]
这些create 和update 子命令需要采取KafkaConnect和KafkaConnector自定义资源规范形式的描述符。我们将在下一节中详细探讨这些自定义资源。
声明式Kafka Connect集群管理 🔗︎
正如我们已经简单介绍过的,一个Kafka Connect集群由一个KafkaConnect自定义资源来代表。Supertubes会根据这些自定义资源的规格,部署建立Kafka Connect集群所需的Kubernetes资源。因此,在自定义资源中做出的任何Kafka Connect配置变更都会自动传播到相应的Kafka Connect集群中。
apiVersion: kafka.banzaicloud.io/v1beta1
kind: KafkaConnect
metadata:
name: my-kafka-connect
spec:
clusterRef:
# Name of the KafkaCluster custom resource that signifies the Kafka cluster this Kafka Connect instance will connect to
name: kafka
schemaRegistryRef:
# (optional) Name of the SchemaRegistry custom resource that represents the Schema Registry to be made available for connectors
name: kafka
# The port Kafka Connect listens at for API requests (default: 8083)
servicePort:
# (optional) Annotations to be applied to Kafka Connect pods
podAnnotations:
# (optional) Annotations to be applied to the service that exposes Kafka Connect API on port `servicePort`
serviceAnnotations:
# (optional) Labels to be applied to Kafka Connect pods
podLabels:
# (optional) Labels to be applied to the service that exposes the Kafka Connect API on port `servicePort`
serviceLabels:
# (optional) Affinity settings for Kafka Connect pods https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
affinity:
# Service account for Kafka Connect pods (default: default)
serviceAccountName:
# The compute resource requirements
# requests:
# cpu: 1
# memory: 2.2Gi
# limits:
# cpu: 2
# memory: 2.5Gi
resources:
# (optional) Node selector setting for Kafka Connect pods https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector
nodeSelector:
# (optional) Tolerations setting for Kafka Connect pods (https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)
tolerations:
# (optional) Volume mounts for Kafka Connect pods (https://kubernetes.io/docs/concepts/storage/volumes/)
volumeMounts:
# (optional): Volumes for Kafka Connect pods (https://kubernetes.io/docs/concepts/storage/volumes/)
volumes:
# (optional): Jmx Exporter configuration
jmxExporter:
# Heap settings for Kafka Connect (default: -Xms512M -Xmx2048M)
heapOpts:
# Minimum number of replicas (default: 1)
minReplicas:
# Maximum number of replicas (default: 5)
maxReplicas:
# Controls whether mTLS is enforced between Kafka Connect and client applications (default: true)
MTLS:
# Defines the config values for Kafka Connect in key - value pairs format
kafkaConnectConfig:
# Additional environment variables to launch Kafka Connect with. The following list of environment variables CAN NOT be
# set through this field as these are either set through a specific field (e.g. `HeapOpts`) or are dynamically computed: KAFKA_HEAP_OPTS, KAFKA_OPTS, CONNECT_REST_ADVERTISED_HOST_NAME,
# CONNECT_BOOTSTRAP_SERVERS, CONNECT_GROUP_ID, CONNECT_CONFIG_STORAGE_TOPIC, CONNECT_OFFSET_STORAGE_TOPIC, CONNECT_STATUS_STORAGE_TOPIC,
# CONNECT_KEY_CONVERTER_SCHEMA_REGISTRY_URL, CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_URL
envVars:
有几个KafkaConnect配置是由Supertubes计算和维护的,因此不能被终端用户所覆盖。
- bootstrap.services
- group.id
- config.storage.topic
- offset.storage.topic
- 状态.存储.主题
- key. converter.schema.registry.url
- 转换器.模式.注册表.网址的值。
声明式管理Kafka Connect连接器 🔗︎
管理连接器的模式与Kafka Connect的模式类似。有一个KafkaConnector自定义资源,它代表了连接器的类型,被Supertubes用来在Kafka Connect集群上实例化连接器。
apiVersion: kafka.banzaicloud.io/v1beta1
kind: KafkaConnector
metadata:
name: my-connector
spec:
# The connector class name (e.g. io.confluent.connect.s3.S3SinkConnector)
class:
# The maximum number of tasks the Kafka Connector can create
tasksMax:
# References the Kafka Connect cluster where this connector is to run
clusterRef:
name: my-kafka-connect
# Defines the config values for Kafka Connector in key - value pairs format
config:
# Whether to pause or resume the connector execution
pause:

Kafka Connect的API端点 🔗︎
已部署的Kafka Connect集群可从Kubernetes集群内的kafka-connect-svc-<kafka-connect-name>.<namespace>.svc:<servicePort> 端点进行访问。
安全性 🔗︎
连接到Kafka Connect的用户默认使用mTLS进行认证。这可以通过KafkaConnect自定义资源中的MTLS 字段来禁用。
Kafka Connect和连接器的ACL 🔗︎
Supertubes负责为Kafka Connect本身设置所有必要的ACL。另一方面,连接器的ACL必须由用户单独设置。通常情况下,一个连接器的 水槽类型的连接器需要READ ,以访问它所读取的主题和名为connect-{connector-name} 的消费者组,而 源类型的连接器需要对它所写的主题进行WRITE 访问。一个Kafka Connect集群和它所承载的连接器是由服务账户认证的。Kafka Connect的部署是用这个账户运行的,而且连接器的特定ACL必须在配置时考虑到这一点。
试用Kafka Connect 🔗︎
让我们通过一个例子来看看我们如何部署Amazon的S3水槽连接器。
设置 🔗︎
-
你可能知道,思科最近收购了Banzai Cloud。目前我们正处于过渡期,正在转移我们的基础设施。联系我们,我们可以讨论你的需求和要求,并组织一次现场演示。
-
创建一个Kubernetes集群。
-
将
KUBECONFIG指向你的集群。 -
安装Supertubes。
评估下载暂时停止。联系我们,讨论你的需求和要求,并组织一次现场演示。
注意:你可以在非生产环境中测试Supertubes并评估它。如果你有兴趣在生产中使用Supertubes,请联系我们。
这一步通常需要几分钟时间,安装一个2个经纪人的演示Kafka集群和一个Kafka Connect集群。
S3凭证 🔗︎
S3 Sink连接器需要AWS凭证,以便能够将消息从一个主题写入S3桶。AWS凭证可以通过挂载到托管Kafka Connect集群的文件传递给连接器。
通过存储AWS凭证 🔗︎创建一个Kubernetes秘密。
echo "aws_access_key_id=<my-aws-access-key-id>" >> aws_creds.txt
echo "aws_secret_access_key=<my-aws-access-key" >> aws_creds.txt
cat aws_creds.txt | base64
apiVersion: v1
kind: Secret
metadata:
name: aws-s3-secret
namespace: kafka
data:
aws-s3-creds.properties: # base64 encoded AWS credentials (creds.txt)
将该秘密挂载到Kafka Connect中 🔗︎
修改KafkaConnect的自定义资源,如下所示,将AWS的秘密挂载到Kafka Connect pods中。
apiVersion: kafka.banzaicloud.io/v1beta1
kind: KafkaConnect
metadata:
name: kafka
namespace: kafka
...
spec:
...
volumeMounts:
- name: aws-s3-creds
readOnly: true
mountPath: /etc/secrets
volumes:
- name: aws-s3-creds
secret:
secretName: aws-s3-secret
创建S3 Sink连接器 🔗︎
apiVersion: kafka.banzaicloud.io/v1beta1
kind: KafkaConnector
metadata:
name: my-s3-sink
spec:
class: "io.confluent.connect.s3.S3SinkConnector"
tasksMax: 6
clusterRef:
name: <
config:
aws.access.key.id: ${file:/etc/secrets/aws-s3-creds.properties:aws_access_key_id}
aws.secret.access.key: ${file:/etc/secrets/aws-s3-creds.properties:aws_secret_access_key}
flush.size: "10000"
format.class: io.confluent.connect.s3.format.bytearray.ByteArrayFormat
key.converter: org.apache.kafka.connect.converters.ByteArrayConverter
locale: en-US
partition.duration.ms: "30000"
partitioner.class: io.confluent.connect.storage.partitioner.TimeBasedPartitioner
path.format: "'year'=YYYY/'month'=MM/'day'=dd/'hour'=HH"
rotate.schedule.interval.ms: "180000"
s3.bucket.name: my-test-s3-bucket
s3.region: eu-central-1
schema.compatibility: NONE
schema.generator.class: io.confluent.connect.storage.hive.schema.DefaultSchemaGenerator
storage.class: io.confluent.connect.s3.storage.S3Storage
timezone: UTC
topics: my-example-topic
value.converter: org.apache.kafka.connect.converters.ByteArrayConverter
如果启用了Kafka ACL,除了Supertubes为Kafka Connect创建的ACL外,还必须为S3 Sink连接器创建以下ACL。
apiVersion: kafka.banzaicloud.io/v1beta1
kind: KafkaACL
metadata:
name: my-s3-sink-kafkaacl
namespace: kafka
spec:
kind: User
name: CN=kafka-kafka-kafka-connect
clusterRef:
name: kafka
namespace: kafka
roles:
- name: consumer
resourceSelectors:
- name: my-example-topic
namespace: kafka
- name: connector-groups
namespace: kakfa
apiVersion: kafka.banzaicloud.io/v1beta1
kind: KafkaResourceSelector
metadata:
name: my-example-topic
namespace: kafka
spec:
type: topic
name: example-topic
pattern: literal
apiVersion: kafka.banzaicloud.io/v1beta1
kind: KafkaResourceSelector
metadata:
name: connector-groups
namespace: kafka
spec:
type: group
name: connect-
pattern: prefixed
Supertubes dashboard 🔗︎
下一个合乎逻辑的步骤是为Supertubes提供一个仪表盘组件,同时支持Kafka Connect。现在它的初始版本终于来了。
随着Supertubes的功能越来越丰富,它本身也变得越来越复杂,虽然使用Supertubes CLI或kubectl进行交互给了我们一个简单而精确的方法来管理kafka集群,但从长远来看,它有可能变得繁琐、容易出错和适得其反。在同一个Kubernetes集群上使用多个Kafka集群,使你在不同的集群上重复相同的命令,从而使这个问题成倍增加,即使你只想了解它们的状态。Kafka本身也有很多组件,所以检查你的代理日志大小、主题偏移量或消费者组日志意味着额外的复杂性。

我们的观点是,直接从命令行做这些事情是很困难的,容易出错,而且很慢。当你的集群和应用程序继续增长时,这种缓慢会扩展到你的集群和应用程序,这意味着更多的事情必须被跟踪和记住。 当灾难来临时,这些问题是你不能忽视的。在生产环境中断期间,时间是宝贵的,而你最不想处理的是一套与你作对的工具。
我们在最近的博文中也写到了这一点,我们认为操作人员是创建Kubernetes环境的关键,这种环境容易出错,但如果出现问题(而且是在一天中的任何时候),随时准备自我修复。记住,最好的支持是你甚至不需要拿起电话,这样,当你注意到一个问题时,它已经自己修复了。
幸运的是,作为开发者,我们每天都在使用IDE来帮助隐藏无意义的复杂性,并在工作中自动处理一些最常见的任务。 最近,甚至Kubernetes也受益于一些社区驱动的解决方案,以解决这个确切的问题--在使用kubectl时增加复杂性和重复性--所以我们认为现在可能是时候创建一些帮助我们的客户解决这个问题了。

在一个已经包含Supertubes的集群上运行下面的简单命令来试试。
supertubes dashboard show
它应该在你的浏览器中直接打开。
仪表盘可以帮助你在一个地方监控Kafka集群的所有关键指标,一目了然。你可以在主题、经纪人和消费者组的标签下观察集群的核心组件,并深入了解每个组件的进一步信息--比如消息数量、分区大小、高低水印偏移、同步复制等。

在经纪人的情况下,检查底层持久性卷索赔中还剩下多少空间是个好主意--所以当它达到极限时,你不会得到任何令人讨厌的惊喜--或者看看特定消费者组的每个成员目前处于哪个偏移量,或者他们在多少滞后下运行。哦,我们还增加了一个黑暗模式!

我们非常渴望向大家展示我们为仪表盘规划的更多功能,比如Kafka ACL处理、高级异常预测和检测、Kafka Connect和Schema Registry支持,以及只有Istio才能提供的功能,这样我们就可以提供关于Kafka集群状态的数据和遥测,这在以前是不可能的。
总结 🔗︎
自从我们推出Supertubes的第一个版本以来,这是一个漫长的旅程。 我们最初的想法是将Kafka移到Istio网状结构内,结果证明这是一个很好的想法,为我们打开了许多对接的可能性。 将Istio与Kafka一起使用有很多好处,如果你想阅读更多的内容,请查看我们关于这个问题的帖子。 我们要感谢在过去一年中试用过Supertubes,甚至只是阅读过我们的博文的每一个人。 我们可以肯定地说,这只是漫长旅程中的第一个里程碑,我们计划提供各种新的功能,旨在让Supertubes的用户生活更轻松,并在Kubernetes上操作Kafka方面达到新的水平,所以敬请关注。