OpenReplay 自托管 Kafka Helm Chart 部署指南:KRaft 模式、TLS 与持久化实战
2026/9/23 5:22:00 网站建设 项目流程
  • 可观测性
  • 开发工具
  • 前端
  • 后端

【免费下载链接】openreplay

Session replay, cobrowsing and product analytics you can self-host. Best for reproducing issues and iterating on your product.

项目地址:https://gitcode.com/gh_mirrors/op/openreplay
点击查看免费下载

本文是一份以 OpenReplay 仓库中 Kafka Helm Chart 为核心的技术指南。该 Chart 将 Apache Kafka 以 StatefulSet 形式部署到 Kubernetes,并默认启用 KRaft 模式(无需 ZooKeeper),支持可选 TLS 加密、持久化存储、Pod 反亲和与资源配额。读者将掌握:如何用helm install一键拉起 Kafka 集群、如何为多副本环境准备并挂载 TLS 证书、如何根据生产规模调整监听器、副本数、保留策略与资源参数,以及如何安全地扩容、卸载并清理数据卷。

一、Chart 概览与能力边界

Kafka Helm Chart 位于 scripts/helmcharts/databases/charts/kafka,是 OpenReplay 自托管数据库 Helm 体系(scripts/helmcharts/databases)中负责消息中间件的子 Chart。从 Chart.yaml 可以看到,它是一个type: application的 v2 Chart,chart 版本11.8.6appVersion: "3",对应仓库维护的 Kafka 3.x 镜像。

其核心能力(依据 IMPLEMENTATION_SUMMARY.md 与模板实现)包括:

  • KRaft 模式:不依赖 ZooKeeper,broker 与 controller 角色合并运行;
  • StatefulSet 部署:稳定网络标识 + 有序存储,天然适配 Kafka 的副本与数据语义;
  • 可选 TLS/SSL:通过 init 容器按 Pod 序号分发证书,支持客户端认证;
  • 多监听器:CLIENT(9092)、INTERNAL(9093)、SSL(9094)三套监听器可独立开关;
  • 可配置持久化:基于volumeClaimTemplates为每个 broker 生成独立 PVC;
  • 高可用调度:默认配置 Pod 反亲和,尽量将副本分散到不同节点;
  • 资源与探针:可配置 requests/limits 以及 liveness/readiness TCP 探针。

实现依据(详见dockerfiles/kafka/kube下的原生 YAML 与 statefulset.yaml),Chart 把原来分散的 Kafka KRaft 部署清单改造成标准 Helm 模板,并在 IMPLEMENTATION_SUMMARY.md 中记录了完整改造过程(删除 deployment/ingress/hpa 等不适用的模板,新增 headless 与 ssl Service)。

二、前置条件

  • Kubernetes 1.19+:StatefulSet、volumeClaimTemplates、init 容器等特性均在此版本以上稳定可用;
  • Helm 3.0+:Chart 使用 v2 API 与 Go 模板函数,需 Helm 3 渲染;
  • PV provisioner:默认启用持久化(persistence.enabled: true),底层集群必须提供可用的 StorageClass 或动态供给能力,否则 PVC 会一直处于 Pending 状态。

三、快速安装

3.1 默认安装(无 TLS)

在 Chart 目录下执行:

helm install kafka . --namespace db --create-namespace

--create-namespace会同时创建db命名空间。安装完成后,可验证部署状态:

kubectl get statefulset -n db kubectl get pods -n db -l app.kubernetes.io/name=kafka kubectl get svc -n db -l app.kubernetes.io/name=kafka

3.2 使用自定义 values 文件

helm install kafka . -f values.yaml helm install kafka . -f values-tls.yaml

其中 values-tls.yaml 是仓库内置的 TLS 示例配置,开启 SSL 监听器并指向kafka-tls-certs证书 Secret。

3.3 渲染校验

正式安装前可用helm template先行渲染,确认模板输出符合预期(见 IMPLEMENTATION_SUMMARY.md 的验证命令):

helm template test-kafka . helm template test-kafka . -f values-tls.yaml

安装后,NOTES.txt 会打印出可用的 bootstrap 地址、SSL 端点(若启用)、副本数与 KRaft 集群 ID 等概要信息。

四、关键配置参数详解

完整参数以 values.yaml 为准,下表列出文档标注的核心参数及其默认值:

参数说明默认值
replicaCountKafka broker 副本数2
image.repository镜像仓库ghcr.io/openreplay/kafka
image.tag镜像标签3
kraft.enabled启用 KRaft 模式true
kraft.clusterIdKRaft 集群 IDSjg_Rr1iQbO9xpahgDbYpQ
kraft.processRoles进程角色broker,controller
kraft.controllerListenerNamescontroller 监听器名INTERNAL
listeners.client.portCLIENT 监听端口(PLAINTEXT)9092
listeners.internal.portINTERNAL 监听端口(PLAINTEXT)9093
listeners.ssl.portSSL 监听端口9094
tls.enabled启用 TLS/SSLfalse
tls.secretName存放证书的 Secretkafka-tls-certs
tls.clientAuth客户端认证方式required
tls.endpointIdentificationAlgorithm主机名校验算法(空串禁用)""
persistence.enabled启用持久化true
persistence.size每副本 PV 大小100Gi
persistence.storageClass存储类(空则用默认)""
persistence.accessModes访问模式ReadWriteOnce
resources.requests.cpuCPU 请求500m
resources.requests.memory内存请求1Gi
resources.limits.cpuCPU 上限2000m
resources.limits.memory内存上限2Gi
podManagementPolicyPod 管理策略Parallel
updateStrategy.type更新策略RollingUpdate
service.typeService 类型ClusterIP
headlessService.enabled是否创建 headless Servicetrue

注意:README 表格中镜像仓库写为rjshrjndrn/kafka,而当前仓库 values.yaml 与上层 databases/values.yaml 中实际值为ghcr.io/openreplay/kafka。部署时应以仓库实际值为准,若沿用镜像则无需修改。

4.1 安全上下文与探针

Pod 默认设置fsGroup: 1001,容器以非 root 用户(runAsUser: 1001)运行并禁止提权(allowPrivilegeEscalation: false),符合生产环境的最小权限原则。健康检查采用 TCP 探针:liveness 初始延迟 30s、readiness 初始延迟 20s,均探测kafka-client端口,readiness 的failureThreshold为 6,给足 broker 启动时间。

五、KRaft 模式:从模板到原理

5.1 KRaft 配置项

KRaft 是 Kafka 2.8+ 引入、3.x 起生产可用的元数据管理模式,用内部 KRaft 协议取代 ZooKeeper 存储 topic、分区与 broker 元数据。本 Chart 中由kraft.*一组参数驱动:

kraft: enabled: true # Cluster ID(可用 kafka-storage.sh random-uuid 生成) clusterId: "Sjg_Rr1iQbO9xpahgDbYpQ" processRoles: "broker,controller" controllerListenerNames: "INTERNAL"
  • processRoles: broker,controller:每个 broker 同时承担 broker 与 controller 职责(combined 模式),无需单独部署 controller 节点;
  • controllerListenerNames: INTERNAL:controller 通信复用 9093 端口的 INTERNAL 监听器;
  • clusterId:集群唯一 ID,需为合法的 base64 UUID。若更换或清空数据卷,建议用kafka-storage.sh random-uuid重新生成,避免多集群冲突(见 values.yaml 注释)。

5.2 动态 Quorum Voters 生成

KRaft 需要每个 broker 知道 controller 仲裁成员的完整地址。模板 _helpers.tpl 中的kafka.controllerQuorumVoters函数会按replicaCount动态生成id@host:port列表:

1@<release>-kafka-0.<release>-kafka-headless.<namespace>.svc.cluster.local:9093, 2@<release>-kafka-1.<release>-kafka-headless.<namespace>.svc.cluster.local:9093

节点 ID 从 1 开始按序分配,主机名基于 StatefulSet 的稳定 Pod 名与 headless Service 拼接。这意味着扩容副本数后需重新执行helm upgrade,让 quorum 列表随之更新。

5.3 监听器与通告地址

_helpers.tpl中还包含三个关键渲染函数:

  • kafka.listeners:生成KAFKA_LISTENERS,形如CLIENT://:9092,INTERNAL://:9093[,SSL://:9094]
  • kafka.advertisedListeners:生成KAFKA_ADVERTISED_LISTENERS,使用${MY_POD_NAME}.<fullname>-headless.<namespace>.svc.cluster.local的通告地址,保证集群内任意节点都能按 Pod 名直达目标 broker;
  • kafka.listenerSecurityProtocolMap:生成CLIENT:PLAINTEXT,INTERNAL:PLAINTEXT,SSL:SSL的安全协议映射。

在 statefulset.yaml 中,这些值通过KAFKA_NODE_IDKAFKA_CLUSTER_IDKAFKA_PROCESS_ROLESKAFKA_CONTROLLER_QUORUM_VOTERSKAFKA_LISTENERSKAFKA_ADVERTISED_LISTENERS等环境变量注入镜像入口脚本,从而完成 KRaft 集群的引导。Pod 的MY_POD_NAMEmetadata.name字段注入,因此通告地址天然跟随每个 Pod 的唯一名称。

六、TLS 加密配置实战

6.1 证书与 Secret 结构

开启 TLS 前,需要为每个 broker 单独签发证书,并将它们放进同一个 Secret。Secret 键名规则(见 values.yaml 注释)为:

  • ca-cert.pem:集群 CA 证书;
  • kafka-<N>-cert.pem:第 N 个 broker 的服务端证书;
  • kafka-<N>-key.pem:第 N 个 broker 的服务端私钥。

其中<N>从 0 开始,对应 StatefulSet 的 Pod 序号。以 2 副本为例,创建命令:

kubectl create secret generic kafka-tls-certs \ --from-file=ca-cert.pem=./certs/ca-cert.pem \ --from-file=kafka-0-cert.pem=./certs/kafka-0-cert.pem \ --from-file=kafka-0-key.pem=./certs/kafka-0-key.pem \ --from-file=kafka-1-cert.pem=./certs/kafka-1-cert.pem \ --from-file=kafka-1-key.pem=./certs/kafka-1-key.pem \ -n db

证书签发可复用仓库dockerfiles/kafka目录下的generate-certs.sh脚本,也可用openssl req -new -x509 -keyout ca-key.pem -out ca-cert.pem -days 365 -nodes -subj "/CN=kafka-ca"手工生成 CA(详见 QUICKSTART.md)。

6.2 启用 TLS

在 values 中开启 TLS 并激活 SSL 监听器:

tls: enabled: true secretName: kafka-tls-certs listeners: ssl: enabled: true port: 9094

也可以直接使用仓库提供的 values-tls.yaml 整体覆盖。

6.3 init 容器分发证书

tls.enabled为 true 时,StatefulSet 会注入名为setup-certs的 init 容器(busybox 镜像)。它从metadata.name提取当前 Pod 序号,将kafka-<N>-cert.pem/kafka-<N>-key.pem重命名为通用的server-cert.pem/server-key.pem写入空目录,并设置server-key.pem权限为 600(见 statefulset.yaml):

POD_ID=$(echo $POD_NAME | sed 's/<fullname>-//') cp /tls-secret/ca-cert.pem /tls/ca-cert.pem cp /tls-secret/kafka-${POD_ID}-cert.pem /tls/server-cert.pem cp /tls-secret/kafka-${POD_ID}-key.pem /tls/server-key.pem chmod 644 /tls/*.pem chmod 600 /tls/server-key.pem

随后主容器通过KAFKA_SSL_CERT_FILE=/tls/server-cert.pemKAFKA_SSL_KEY_FILE=/tls/server-key.pemKAFKA_SSL_CA_FILE=/tls/ca-cert.pem环境变量启用 SSL。tls.clientAuth: required表示强制要求客户端证书(双向 TLS),endpointIdentificationAlgorithm默认留空以禁用主机名校验——在证书不包含 Pod DNS 名称的场景下这是必要的,若希望启用主机名校验需自行设置该参数。

6.4 客户端验证 TLS 连接

将 CA 证书导出并构造 client.properties 后,即可验证 SSL 端点:

kubectl get secret kafka-tls-certs -n db -o jsonpath='{.data.ca-cert\.pem}' | base64 -d > ca-cert.pem cat > client.properties << EOL security.protocol=SSL ssl.truststore.location=ca-cert.pem ssl.truststore.type=PEM EOL kubectl run kafka-client --rm -it --image=confluentinc/cp-kafka:latest --namespace db -- bash # 容器内执行: kafka-topics --bootstrap-server kafka-ssl.db.svc.cluster.local:9094 --command-config client.properties --list

七、集群内访问 Kafka

安装后会在db命名空间生成三类 Service(详见 service.yaml、service-headless.yaml、service-ssl.yaml):

端点说明
kafka.db.svc.cluster.local:9092ClusterIP 客户端入口(PLAINTEXT)
kafka-headless.db.svc.cluster.local:9092Headless Service,可直接访问各 Pod
kafka-ssl.db.svc.cluster.local:9094SSL 端点(仅启用 TLS 时创建)

headless Service 设置了publishNotReadyAddresses: true,即使 broker 尚未 Ready 也会发布 Pod 地址,这对 Kafka 集群引导阶段至关重要(controller 需要先互相发现)。快速验证连通性:

kubectl run test-pod --rm -it --image=busybox --namespace db -- sh # 容器内执行: nc -zv kafka.db.svc.cluster.local 9092 nc -zv kafka-0.kafka-headless.db.svc.cluster.local 9092

八、Kafka 运行参数调优

除了部署形态,Chart 还通过kafka.*段透传了大量 server 属性(以KAFKA_CFG_*环境变量注入,见 statefulset.yaml):

  • 消息与副本messageMaxBytes/replicaFetchMaxBytes默认3145728(3MB),对应单条消息与副本拉取上限;
  • 保留策略logRetentionHours: 168(7 天)、logRetentionBytes: 1073741824(1GB)、logSegmentBytes: 1073741824(1GB),时间与大小双维度保留;
  • 刷盘logFlushIntervalMessages: 10000logFlushIntervalMs: 1000,消息数或时间任一达到即触发刷盘;
  • 副本因子defaultReplicationFactoroffsetsTopicReplicationFactortransactionStateLogReplicationFactor默认均为 1,多副本集群建议调大以提升容错;
  • 线程模型numIoThreads: 8numNetworkThreads: 3numPartitions: 1numRecoveryThreadsPerDataDir: 1
  • 网络缓冲socketReceiveBufferBytes/socketSendBufferBytes102400socketRequestMaxBytes104857600(100MB);
  • 安全autoCreateTopicsEnable: truedeleteTopicEnable: falseallowEveryoneIfNoAclFound: truesuperUsers: User:admin,默认允许无 ACL 访问并指定 admin 为超级用户。

上层 databases/values.yaml 将这份参数作为子 Chart 的默认覆盖值整体继承,因此通过 databases 聚合 Chart 安装时这些调优同样生效。需要额外注入自定义配置时,可用extraEnvVars(如KAFKA_CFG_CUSTOM_SETTING)、extraVolumesextraVolumeMounts扩展。

九、扩容、升级与卸载

9.1 扩容与调参

helm upgrade kafka . --namespace db --set replicaCount=3

扩容后 quorum voters 列表由模板动态重建,新 Pod 会自动加入仲裁;同时应为新副本补充对应的kafka-2-cert.pem/kafka-2-key.pem到 TLS Secret(若启用 TLS)。缩容需谨慎——小于最小 ISR 的副本数会破坏数据冗余。

9.2 卸载与清理

helm uninstall kafka

Chart 卸载不会删除 PVC。Kafka 数据仍保留在持久卷中,需要彻底清理时按标签删除:

kubectl delete pvc -l app.kubernetes.io/name=kafka

在 databases 聚合部署中,对应命令为helm uninstall kafka --namespace dbkubectl delete pvc -n db -l app.kubernetes.io/name=kafka(见 QUICKSTART.md 清理章节)。

十、生产化检查清单

综合 QUICKSTART.md 与仓库模板,生产部署至少应确认:

  • 启用持久化,并确认 StorageClass 可动态供给;
  • 设置合理的资源 requests/limits;
  • 3 副本以上并开启 Pod 反亲和,保障跨节点高可用;
  • 启用 TLS 并妥善管理证书轮换;
  • 配置监控(JMX、Prometheus)与告警;
  • 制定备份与灾难恢复方案;
  • 明确保留策略(时间/大小)并文档化。

常见故障排查:Pod 无法启动时kubectl describe pod kafka-0 -n db查看事件,重点排查资源不足、PVC 未绑定、证书缺失三类问题(QUICKSTART.md);TLS 连接失败时用kubectl get secret kafka-tls-certs -n db -o yaml核对 Secret 键名,并用openssl x509 -noout -dates检查证书有效期。

十一、与 OpenReplay 数据库体系的集成

该 Kafka Chart 并非孤立组件,而是被 databases/values.yaml 以enabled: false的子 Chart 形式收纳。启用方式是在 databases 聚合部署时打开开关:

kafka: enabled: true fullnameOverride: kafka replicaCount: 3 ...

启用后,OpenReplay 的 sink 等服务即可通过kafka.db.svc.cluster.local:9092消费会话事件流。仓库 IMPLEMENTATION_SUMMARY.md 记录的验证命令make db-template可整体渲染 databases 聚合 Chart,确保 Kafka 子 Chart 与其他数据库组件协同无误。

参考资料

  • Kafka Helm Chart README:本指南对应的原始文档
  • QUICKSTART.md:完整部署、验证与故障排查命令
  • IMPLEMENTATION_SUMMARY.md:Chart 实现细节与设计取舍
  • values.yaml:全部可配置项与默认值
  • statefulset.yaml:StatefulSet、init 容器与环境变量注入
  • _helpers.tpl:quorum voters、监听器与通告地址生成逻辑
  • 可观测性
  • 开发工具
  • 前端
  • 后端

【免费下载链接】openreplay

Session replay, cobrowsing and product analytics you can self-host. Best for reproducing issues and iterating on your product.

项目地址:https://gitcode.com/gh_mirrors/op/openreplay
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询