随着近年来大数据的快速发展和人工智能技术的不断普及,消息队列已经成为了大量企业和机构中不可或缺的关键组件。其中,Kafka 由于其高性能、高可用以及可扩展性等特点而备受青睐,成为了流行的分布式消息系统之一。而在云环境中部署 Kubernetes Kafka 集群,可以大幅度简化 Kafka 部署和管理,从而提高生产力、便捷可靠地进行Kafka 开发。本篇文章将从多个方面讲解如何打造高可用的Kubernetes Kafka 集群,包括集群架构、存储、网络等,以满足实际业务需求。
一、集群架构
Kafka 可以在 Kubernetes 上部署成为一个分布式的结构,这里的部署方式有不同的选择。下面,我们介绍一种主要的架构方式:
spec: replicas: 3 # 设置3个副本形成一个 Kafka 集群 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 template: metadata: labels: app: kafka spec: containers: - name: kafka image: wurstmeister/kafka:2.13-2.8.1 ports: - containerPort: 9092 # 配置 Kafka 端口,服务监听端口 env: - name: KAFKA_ADVERTISED_HOST_NAME # 配置 hostname value: kafka-lb.example.com - name: KAFKA_ADVERTISED_PORT value: "9092" - name: KAFKA_ZOOKEEPER_CONNECT # 配置 ZooKeeper value: "zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181"
通过上述代码部署了一个 Kubernetes Kafka 集群,其中 Kafka 节点数量为 3 台,支持节点的水平扩展。同时,使用 Rolling Update 策略能够保证 Kafka 集群的正常运转,并且在节点平滑升级时不会影响生产环境服务的持续提供。使用 KAFKA_ZOOKEEPER_CONNECT 指向 Zookeeper 节点,这里采用 3 台机器作为 Zookeeper 集群,保证了数据的高可用。
二、存储
Kafka 数据存储使用本地磁盘进行存储,这种方式会面临磁盘容量不足,或者节点宕机的风险。为了解决这些问题,我们可以使用 Kubernetes 的 PV 和 PVC 技术,来对 Kafka 数据进行持久化存储。
通过下方代码示例创建 Kafka 集群所需的这个 PersistentVolumeClaim:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: kafka-pvc spec: resources: requests: storage: 10Gi # 申请10GB的存储容量 accessModes: - ReadWriteOnce storageClassName: standard
此代码部分定义了一个名为 kafka-pvc 的 PersistenceVolumeClaim 对象,用于在系统中申请10 GB 的存储空间。同时,定义 storageClassName 手动连接 Kubernetes 集群中的 StorageClass,从而完成集群存储的自动化配置。
三、网络
与大部分微服务中的网络解决方案不同,Kafka 的协议是默认使用明文 socket 方式传输的,考虑到网络传输中的数据安全问题,建议采用 HTTPS 进行数据保护。此时,需要使用 Kubernetes 的 ingress 和 HTTPS 协议。其配置方式如下:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: kafka-ingress annotations: cert-manager.io/cluster-issuer: "letsencrypt" spec: tls: - hosts: - kafka-lb.example.com secretName: kafka-tls-secret rules: - host: kafka-lb.example.com http: paths: - backend: serviceName: kafka-svc servicePort: 443
通过以上代码部署,我们定义了一个基于 TLS 的安全数据传输方案,以解决网络传输中的安全性问题。可以看到,这里采用的是 Nginx Ingress Controller ,当环境中租户对访问服务的域名进行 HTTPS 请求时,用户请求会首先被 Nginx 实例负载 IP 转发至内部 Kafka 服务,并且将协议转变为对应的 HTTP。
四、监控
Kafka 集群的监控是保障其高可用的前提。在 Kubernetes 环境中,我们通常使用 Prometheus 和 Grafana 来实现 Kafka 集群的监控
以下为采用标准的 Prometheus Operator 方式实现监控的代码:
apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: kafka-prometheus labels: app: prometheus spec: replicas: 1 storage: volumeClaimTemplate: metadata: name: prometheus-data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi volumeMode: Filesystem serviceAccountName: prometheus serviceMonitorSelector: matchLabels: app: kafka namespaceSelector: matchNames: - kafka ruleSelector: matchLabels: app: kafka matchExpressions: - key: job operator: In values: - kafka-exporter alerting: alertmanagers: - namespace: monitoring name: alertmanager-main port: web
使用 Prometheus Operator 可以自动化进行 Kafka 集群的监控数据收集,而且在 Prometheus collect 的时候,还可以使用 Kafka Exporter 从 Kafka node 获取应用指标数据。除此之外,我们可以通过 Grafana 显示出收集到的 Kafka 相关数据,如下所示:
五、实现各节点的高可用
为了实现 Kafka 集群的高可用,我们需要在集群中设置 leader 和 follower 节点,从而实现 Kafka 副本之间数据的复制,以实现高可用。
对于服务器故障等单点问题,我们可以使用热备节点的方式来解决,具体代码如下所示:
apiVersion: v1 kind: Pod metadata: name: kafka-0 labels: broker.id: "0" spec: containers: - name: kafka image: wurstmeister/kafka:2.13-2.8.1 env: - name: KAFKA_BROKER_ID value: "0" - name: KAFKA_ADVERTISED_HOST_NAME value: kafka.example.com - name: KAFKA_META_BROKER_LIST value: "kafka-0:9092,kafka-1:9092,kafka-2:9092" - name: KAFKA_ZOOKEEPER_CONNECT value: "zk-0:2181,zk-1:2181,zk-2:2181/kafka" ports: - containerPort: 9092 volumeMounts: - name: kafka-data mountPath: /var/lib/kafka - name: config-volume mountPath: /opt/kafka/config/kafka-0.properties subPath: kafka-0.properties volumes: - name: kafka-data persistentVolumeClaim: claimName: pvc-kafka-0 - name: config-volume configMap: name: kafka-config-map items: - key: kafka-0.properties path: kafka-0.properties defaultMode: 420
上述代码中定义了一个名为 kafka-0 的副本,用于备份 Kafka 集群中的数据。如此一来,当 Kafka 集群中某一台主节点宕机时,副本节点会接替主节点的职责,实现高可用。
六、总结
本文介绍了如何在 Kubernetes 环境下打造高可用的 Kafka 集群,分别从高可用架构、存储、网络、监控以及实现各节点的高可用等方面进行了详细讲解,是初学者学习 Kubernetes Kafka 集群的一篇不可多得的好文章。