介绍Kubernetes设计的初衷是运行无状态的工作负载。这些工作负载,通常是微服务架构,轻量级、水平可扩展、遵循十二因素应用程序,并且可以处理环中断和随机猴子测试。另一方面,Kafka本质上是一个分布式数据库。这意味着你必须处理状态,它比微服务更重量级。Kubernetes支持有状态的工作负载,但你必须小心使用它,正如KelseyHightower在最近的两条推文中指出的那样:你现在应该在Kubernetes上运行Kafka吗?我的反问:没有它Kafka会跑得更好吗?这就是为什么我要指出Kafka和Kubernetes之间的互补性以及您可能会遇到的陷阱。运行时让我们首先看一下基础知识——运行时本身。进程Kafka代理对CPU友好。TLS可能会引入一些开销。如果Kafka客户端使用加密,则需要更多CPU,但这不会影响代理。内存Kafka代理是内存大消费者。JVM堆通常可以限制在4-5GB,但由于Kafka大量使用页面缓存,因此也需要足够的系统内存。在Kubernetes中,可以相应地设置容器资源限制和请求。存储容器中的存储是短暂的——数据将在重启后丢失。可以为Kafka数据使用emptyDir卷,这将产生相同的效果:代理的数据将在停机后丢失。您的消息在其他经纪商处仍可作为副本使用。因此,重启后,失败的代理必须复制其所有数据,这是一个耗时的过程。这就是您应该使用持久存储的原因。使用XFS或ext4的非原生持久块存储更适合。我警告你:不要使用NFS。NFSv3和v4都不起作用。简而言之,由于NFS“愚蠢的重命名”问题,Kafka代理将在无法删除数据目录的情况下自行终止。如果您仍然不相信我,请仔细阅读这篇博文。存储必须是非本地的,以便Kubernetes在重新启动或迁移时可以更灵活地选择另一个节点。网络与大多数分布式系统一样,Kafka的性能在很大程度上取决于低网络延迟和高带宽。不要试图将所有代理放在同一个节点上,因为这会降低可用性。如果一个Kubernetes节点发生故障,那么整个Kafka集群都会发生故障。不要跨数据中心扩展Kafka集群。这同样适用于Kubernetes集群。不同的可用性区域是一个很好的权衡。配置清单Kubernetes网站包含关于如何使用清单设置ZooKeeper的非常好的教程。由于ZooKeeper是Kafka的一部分,您可以使用它来了解这里应用了哪些Kubernetes概念。一旦理解,您也可以将相同的概念用于Kafka集群。Pod:Pod是Kubernetes中最小的可部署单元。它包含您的工作负载,代表集群中的一个进程。一个Pod包含一个或多个容器。ensemble中的每个ZooKeeper服务器和Kafka集群中的每个Kafka代理都将在单独的Pod中运行。StatefulSet:StatefulSet是一个Kubernetes对象,用于处理需要协调的多个有状态工作负载。StatefulSets保证Pod的顺序和唯一性。无头服务:服务通过逻辑名称将Pod与客户端分开。Kubernetes负责负载均衡。但是,对于ZooKeeper和Kafka等有状态工作负载,客户端必须与特定实例进行通信。这就是无头服务发挥作用的地方:作为客户端,您仍然可以获得逻辑名称,但不必直接访问pod。PersistentVolumes:如前所述,需要配置非本地持久块存储。Yolean提供了一套全面的清单来帮助您开始在Kubernetes上使用Kafka。HelmChartsHelm是Kubernetes的包管理器,类似于yum、apt、Homebrew或Chocolatey等操作系统包管理器。它允许您安装HelmCharts中描述的预定义包。精心设计的HelmCharts简化了正确配置所有参数以在Kubernetes上运行Kafka的复杂任务。Kafka有几种可用的图表:一种是处于不断发展状态的官方图表,一种来自Confluent,另一种来自Bitnami,仅举几例。Operators由于Helm的一些限制,另一种工具变得非常流行:KubernetesOperators。运维人员不仅可以为Kubernetes打包软件,还可以为Kubernetes部署和管理一个软件。在高度评价的Operators列表中提到了两个Kafka,其中一个是Strimzi,Strimzi使得在几分钟内启动Kafka集群变得非常容易,几乎不需要任何配置,并且它添加了一些漂亮的功能,例如集群间点到-点TLS加密。Confluent还宣布即将推出新的Operator。性能运行性能测试以对您的Kafka安装进行基准测试非常重要。它会在您遇到麻烦之前为您提供有关可能的瓶颈的信息。幸运的是,Kafka已经提供了两个性能测试工具:kafka-producer-perf-test.sh和kafka-consumer-perf-test.sh。请记住经常使用它们。作为参考,请使用JayKreps的博客结果或StéphaneMaarek在AmazonMSK上的评论。运营监控可见性非常重要,否则您将不知道发生了什么。今天,有一个很好的工具可以以云原生方式监控指标。Prometheus和Grafana是两个流行的工具。Prometheus可以直接从JMX导出器收集所有Java进程(Kafka、ZooKeeper、KafkaConnect)的指标。添加cAdvisor指标可提供有关Kubernetes资源使用情况的额外信息。Strimzi为Kafka提供了一个优雅的Grafana仪表板示例。它以非常直观的方式可视化关键指标,如未复制和离线分区。它通过资源使用、性能和稳定性指标来补充这些指标。所以,免费获得基本的Kafka集群监控!来源:https://strimzi.io/docs/master/#kafka_dashboard可以通过clientside(consumerandproducermetrics)进行监控,使用Burrowlag监控,使用KafkaMonitor做端到端的监控,完成这个任务的日志记录日志记录是另一个关键部分。确保Kafka安装中的所有容器都记录到标准输出(stdout)和标准错误输出(stderr),并确保Kubernetes集群将所有日志聚合到一个中央日志记录工具中,例如Elasticsearch。健康检查Kubernetes使用活跃度和就绪度探测来确定Pod是否健康。如果liveness探测失败,Kubernetes将终止容器并在相应设置重启策略的情况下自动重启它。如果就绪探测失败,那么Kubernetes将通过服务从服务请求中移除Pod。这意味着在这种情况下不再需要人为干预,这是一大优势。滚动更新StatefulSets支持自动更新:滚动更新策略将一次更新一个KafkaPod。这样就可以实现零宕机,这是Kubernetes带来的又一大优势。扩展Kafka集群并非易事。但是,Kubernetes可以轻松地将Pod扩展到一定数量的副本,这意味着可以以声明方式定义所需数量的Kafka代理。困难的部分是在放大或缩小之前重新分配这些部分。同样,Kubernetes可以帮助您完成这项任务。管理通过在Pod中打开一个shell,可以使用现有的shell脚本来完成Kafka集群管理任务,例如创建主题和重新分配分区。这不是一个很好的解决方案。Strimzi支持使用另一个Operator管理主题。这留下了改进的余地。备份和恢复现在Kafka的可用性也依赖于Kubernetes的可用性。如果Kubernetes集群失败,那么在最坏的情况下Kafka集群也会失败。墨菲定律告诉我们,这也会发生在你身上,你会丢失数据。为降低这种风险,请确保您有备用想法。MirrorMaker是一种选择,另一种可能性是利用S3进行连接备份,如Zalando的博客文章中所述。结论对于中小型Kafka集群,我肯定会选择Kubernetes,因为它提供了更多的灵活性和易操作性。如果您在延迟和/或吞吐量方面有非常高的非功能性要求,则不同的部署选项可能会更有利。
