- 可观测性
- 开发工具
- 前端
- 后端
【免费下载链接】openreplay
Session replay, cobrowsing and product analytics you can self-host. Best for reproducing issues and iterating on your product.
本文是一份以 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.6,appVersion: "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=kafka3.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 为准,下表列出文档标注的核心参数及其默认值:
| 参数 | 说明 | 默认值 |
|---|---|---|
replicaCount | Kafka broker 副本数 | 2 |
image.repository | 镜像仓库 | ghcr.io/openreplay/kafka |
image.tag | 镜像标签 | 3 |
kraft.enabled | 启用 KRaft 模式 | true |
kraft.clusterId | KRaft 集群 ID | Sjg_Rr1iQbO9xpahgDbYpQ |
kraft.processRoles | 进程角色 | broker,controller |
kraft.controllerListenerNames | controller 监听器名 | INTERNAL |
listeners.client.port | CLIENT 监听端口(PLAINTEXT) | 9092 |
listeners.internal.port | INTERNAL 监听端口(PLAINTEXT) | 9093 |
listeners.ssl.port | SSL 监听端口 | 9094 |
tls.enabled | 启用 TLS/SSL | false |
tls.secretName | 存放证书的 Secret | kafka-tls-certs |
tls.clientAuth | 客户端认证方式 | required |
tls.endpointIdentificationAlgorithm | 主机名校验算法(空串禁用) | "" |
persistence.enabled | 启用持久化 | true |
persistence.size | 每副本 PV 大小 | 100Gi |
persistence.storageClass | 存储类(空则用默认) | "" |
persistence.accessModes | 访问模式 | ReadWriteOnce |
resources.requests.cpu | CPU 请求 | 500m |
resources.requests.memory | 内存请求 | 1Gi |
resources.limits.cpu | CPU 上限 | 2000m |
resources.limits.memory | 内存上限 | 2Gi |
podManagementPolicy | Pod 管理策略 | Parallel |
updateStrategy.type | 更新策略 | RollingUpdate |
service.type | Service 类型 | ClusterIP |
headlessService.enabled | 是否创建 headless Service | true |
注意: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_ID、KAFKA_CLUSTER_ID、KAFKA_PROCESS_ROLES、KAFKA_CONTROLLER_QUORUM_VOTERS、KAFKA_LISTENERS、KAFKA_ADVERTISED_LISTENERS等环境变量注入镜像入口脚本,从而完成 KRaft 集群的引导。Pod 的MY_POD_NAME由metadata.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.pem、KAFKA_SSL_KEY_FILE=/tls/server-key.pem、KAFKA_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:9092 | ClusterIP 客户端入口(PLAINTEXT) |
kafka-headless.db.svc.cluster.local:9092 | Headless Service,可直接访问各 Pod |
kafka-ssl.db.svc.cluster.local:9094 | SSL 端点(仅启用 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: 10000、logFlushIntervalMs: 1000,消息数或时间任一达到即触发刷盘; - 副本因子:
defaultReplicationFactor、offsetsTopicReplicationFactor、transactionStateLogReplicationFactor默认均为 1,多副本集群建议调大以提升容错; - 线程模型:
numIoThreads: 8、numNetworkThreads: 3、numPartitions: 1、numRecoveryThreadsPerDataDir: 1; - 网络缓冲:
socketReceiveBufferBytes/socketSendBufferBytes为102400,socketRequestMaxBytes为104857600(100MB); - 安全:
autoCreateTopicsEnable: true、deleteTopicEnable: false、allowEveryoneIfNoAclFound: true、superUsers: User:admin,默认允许无 ACL 访问并指定 admin 为超级用户。
上层 databases/values.yaml 将这份参数作为子 Chart 的默认覆盖值整体继承,因此通过 databases 聚合 Chart 安装时这些调优同样生效。需要额外注入自定义配置时,可用extraEnvVars(如KAFKA_CFG_CUSTOM_SETTING)、extraVolumes与extraVolumeMounts扩展。
九、扩容、升级与卸载
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 kafkaChart 卸载不会删除 PVC。Kafka 数据仍保留在持久卷中,需要彻底清理时按标签删除:
kubectl delete pvc -l app.kubernetes.io/name=kafka在 databases 聚合部署中,对应命令为helm uninstall kafka --namespace db加kubectl 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.
相关推荐
OpenReplay 自托管 Kafka Helm Chart 部署实战:KRaft 模式、TLS 加密与生产化配置全指南
OpenReplay 自托管 Kafka Helm Chart 部署实战:KRaft 模式、TLS 加密与生产化配置全指南 本文以 OpenReplay 仓库中
可观测性开发工具前端后端OpenReplay 自托管 Kafka 的 Kubernetes KRaft 快速部署指南
OpenReplay 自托管 Kafka 的 Kubernetes KRaft 快速部署指南 导读 本指南面向在 Kubernetes 上部署 OpenRepl
可观测性开发工具前端后端OpenReplay 自托管 Kafka 的 Kubernetes KRaft 部署指南:以 StatefulSet 平滑替换 Helm + ZooKeeper
OpenReplay 自托管 Kafka 的 Kubernetes KRaft 部署指南:以 StatefulSet 平滑替换 Helm + ZooKeeper
可观测性开发工具前端后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考