本文档将详细阐述如何利用 Helm 这一强大的工具,快速而高效地在 K8s 集群上安装并配置一个 Kafka 集群。
实战服务器配置(架构 1:1 复刻小规模生产环境,配置略有不同)
主机名IPCPU内存系统盘数据盘用途ksp-registry192.168.9.904840200Harbor 镜像仓库ksp-control-1192.168.9.914840100KubeSphere/k8s-control-planeksp-control-2192.168.9.924840100KubeSphere/k8s-control-planeksp-control-3192.168.9.934840100KubeSphere/k8s-control-planeksp-worker-1192.168.9.9481640100k8s-worker/CIksp-worker-2192.168.9.9581640100k8s-workerksp-worker-3192.168.9.9681640100k8s-workerksp-storage-1192.168.9.974840400+ElasticSearch/Longhorn/Ceph/NFSksp-storage-2192.168.9.984840300+ElasticSearch/Longhorn/Cephksp-storage-3192.168.9.994840300+ElasticSearch/Longhorn/Cephksp-gpu-worker-1192.168.9.10141640100k8s-worker(GPU NVIDIA Tesla M40 24G)ksp-gpu-worker-2192.168.9.10241640100k8s-worker(GPU NVIDIA Tesla P100 16G)ksp-gateway-1192.168.9.1032440自建应用服务署理网关/VIP:192.168.9.100ksp-gateway-2192.168.9.1042440自建应用服务署理网关/VIP:192.168.9.100ksp-mid192.168.9.1054840100部署在 k8s 集群之外的服务节点(Gitlab 等)合计15681526002100+实战环境涉及软件版本信息
- 操作系统:openEuler 22.03 LTS SP3 x86_64
- KubeSphere:v3.4.1
- Kubernetes:v1.28.8
- KubeKey: v3.1.1
- Bitnami Kafka Helm Charts:29.3.13
- Kafka: 3.7.1
1. 条件条件
现在在 K8s 集群部署 Kafka 的主流方案有以下几种:
- 手写资源配置清单(贫苦,涉及的组件、配置多)
- Kafka Helm chart (Bitnami 出品,简单可定制,但是需要花时间本钱学习可配置参数)
颠末细致的调研、思索,本文选择接纳 Bitnami 的 Kafka Helm chart 举行部署。Bitnami 提供的 Helm chart 以其稳定性和易用性著称,是快速部署 Kafka 到 Kubernetes 集群的理想选择。
编写本文的目标是为了验证 Kafka Helm chart 的部署可行性,并评估其在实际应用中的表现。为了确保过程的顺遂和进步成功几率,以下部署配置举行了适度简化,某些配置并不符合生产环境的标准。
- 外部访问安全协议,使用了 PLAINTEXT ,关闭了访问认证,默认值为 SASL_PLAINTEXT。生产环境务必开启认证。
- 外部访问使用了 NodePort 模式
- 默认 StorageClass 使用了 NFS
- 没有考虑数据长期化的配置
对于计划在生产环境部署的用户,我建议详细参考 Bitnami 官方文档,以获取更全面的配置指导和最佳实践。我认为生产环境应该考虑的几项配置如下:
- 外部访问安全协议,选择PLAINTEXT, SASL_PLAINTEXT, SASL_SSL 和 SSL 中的哪种方式加密认证方式,
- 数据、日志长期化配置
- k8s 集群外部访问 Kafka 的方式,NodePort 是否符合?是否需要使用 LoadBalancer、Ingress
- 内否启用内置的监控 Metrics
- 是否利用 Helm 天生 Kubectl 可用的资源配置清单,离线部署
2. 使用 Helm 安装 Kafka 集群
2.1 安装 Kafka Helm Chart
- helm repo add bitnami https://charts.bitnami.com/bitnami
复制代码 2.2 安装 Kafka
- helm install my-release oci://registry-1.docker.io/bitnamicharts/kafka
复制代码- helm install opsxlab bitnami/kafka \
- --namespace opsxlab --create-namespace \
- --set replicaCount=3 \
- --set global.imageRegistry="registry.opsxlab.cn:8443" \
- --set global.defaultStorage \
- --set externalAccess.enabled=true \
- --set externalAccess.controller.service.type=NodePort \
- --set externalAccess.controller.service.nodePorts[0]='31211' \
- --set externalAccess.controller.service.nodePorts[1]='31212' \
- --set externalAccess.controller.service.nodePorts[2]='31213' \
- --set externalAccess.controller.service.useHostIPs=true \
- --set listeners.client.protocol=PLAINTEXT \
- --set listeners.external.protocol=PLAINTEXT
复制代码 自界说配置阐明:
- 指定并自动创建定名空间 opsxlab
- 设置组件的镜像地址,本文为了演示修改方法,使用了内部的镜像仓库,实际使用中请修改为自己的镜像仓库地址
- 设置默认的长期化存储类为 nfs-sc,适用于 K8s 有多种存储类,需要部署到指定存储类的场景
- 开启外部访问,并设置相关参数
- 加密认证方式选择了 PLAINTEXT
正确执行后,输出结果如下 :- $ helm install opsxlab bitnami/kafka \
- --set externalAccess.controller.service.nodePorts[1]='31212' \
- > --namespace opsxlab --create-namespace \
- > --set replicaCount=3 \
- > --set global.imageRegistry="registry.opsxlab.cn:8443" \
- > --set global.defaultStorage \
- > --set externalAccess.enabled=true \
- > --set externalAccess.controller.service.type=NodePort \
- > --set externalAccess.controller.service.nodePorts[0]='31211' \
- > --set externalAccess.controller.service.nodePorts[1]='31212' \
- > --set externalAccess.controller.service.nodePorts[2]='31213' \
- > --set externalAccess.controller.service.useHostIPs=true \
- > --set listeners.client.protocol=PLAINTEXT \
- > --set listeners.external.protocol=PLAINTEXT
- NAME: opsxlab
- LAST DEPLOYED: Wed Jul 30 22:08:38 2024
- NAMESPACE: opsxlab
- STATUS: deployed
- REVISION: 1
- TEST SUITE: None
- NOTES:
- CHART NAME: kafka
- CHART VERSION: 29.3.13
- APP VERSION: 3.7.1
- ---------------------------------------------------------------------------------------------
- WARNING
- By specifying "serviceType=LoadBalancer" and not configuring the authentication
- you have most likely exposed the Kafka service externally without any
- authentication mechanism.
- For security reasons, we strongly suggest that you switch to "ClusterIP" or
- "NodePort". As alternative, you can also configure the Kafka authentication.
- ---------------------------------------------------------------------------------------------
- ** Please be patient while the chart is being deployed **
- Kafka can be accessed by consumers via port 9092 on the following DNS name from within your cluster:
- opsxlab-kafka.opsxlab.svc.cluster.local
- Each Kafka broker can be accessed by producers via port 9092 on the following DNS name(s) from within your cluster:
- opsxlab-kafka-controller-0.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092
- opsxlab-kafka-controller-1.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092
- opsxlab-kafka-controller-2.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092
- To create a pod that you can use as a Kafka client run the following commands:
- kubectl run opsxlab-kafka-client --restart='Never' --image registry.opsxlab.cn:8443/bitnami/kafka:3.7.1-debian-12-r4 --namespace opsxlab --command -- sleep infinity
- kubectl exec --tty -i opsxlab-kafka-client --namespace opsxlab -- bash
- PRODUCER:
- kafka-console-producer.sh \
- --broker-list opsxlab-kafka-controller-0.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,opsxlab-kafka-controller-1.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,opsxlab-kafka-controller-2.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092 \
- --topic test
- CONSUMER:
- kafka-console-consumer.sh \
- --bootstrap-server opsxlab-kafka.opsxlab.svc.cluster.local:9092 \
- --topic test \
- --from-beginning
- To connect to your Kafka controller+broker nodes from outside the cluster, follow these instructions:
- Kafka brokers domain: You can get the external node IP from the Kafka configuration file with the following commands (Check the EXTERNAL listener)
- 1. Obtain the pod name:
- kubectl get pods --namespace opsxlab -l "app.kubernetes.io/name=kafka,app.kubernetes.io/instance=opsxlab,app.kubernetes.io/component=kafka"
- 2. Obtain pod configuration:
- kubectl exec -it KAFKA_POD -- cat /opt/bitnami/kafka/config/server.properties | grep advertised.listeners
- Kafka brokers port: You will have a different node port for each Kafka broker. You can get the list of configured node ports using the command below:
- echo "$(kubectl get svc --namespace opsxlab -l "app.kubernetes.io/name=kafka,app.kubernetes.io/instance=opsxlab,app.kubernetes.io/component=kafka,pod" -o jsonpath='{.items[*].spec.ports[0].nodePort}' | tr ' ' '\n')"
- WARNING: There are "resources" sections in the chart not set. Using "resourcesPreset" is not recommended for production. For production installations, please set the following values according to your workload needs:
- - controller.resources
- +info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
复制代码 2.3 查看安装结果
Helm 安装命令成功执行后,观察 Pod 运行状态。- kubectl get pods -n opsxlab
复制代码 安装成功后,输出结果如下 :- $ kubectl get pods -n opsxlab
- NAME READY STATUS RESTARTS AGE
- opsxlab-kafka-controller-0 1/1 Running 0 1m17s
- opsxlab-kafka-controller-1 1/1 Running 0 1m17s
- opsxlab-kafka-controller-2 1/1 Running 0 1m17s
复制代码 KubeSphere 管理控制台查看部署的组件信息。
3. 验证测试 Kafka 服务可用性
分别在 K8s 集群内和集群外验证 Kafka 服务的可用性。
3.1 K8s 集群内部验证
在 K8s 集群内的验证过程,可以参考 Helm 部署 Kafka 时给出的提示信息。
- kubectl run opsxlab-kafka-client --restart='Never' --image registry.opsxlab.cn:8443/bitnami/kafka:3.7.1-debian-12-r4 --namespace opsxlab --command -- sleep infinity
复制代码- kubectl exec --tty -i opsxlab-kafka-client --namespace opsxlab -- bash
复制代码- kafka-console-producer.sh \
- --broker-list opsxlab-kafka-controller-0.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,opsxlab-kafka-controller-1.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,opsxlab-kafka-controller-2.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092 \
- --topic test
复制代码 再打开一个终端后,先执行 第 2 步打开测试 Pod 终端的命令,然后再执行下面的命令。- kafka-console-consumer.sh \
- --bootstrap-server opsxlab-kafka.opsxlab.svc.cluster.local:9092 \
- --topic test \
- --from-beginning
复制代码 在生产者一侧任意输入测试数据,观察消耗者一侧是否正确收到信息。
生产者侧:- I have no name!@opsxlab-kafka-client:/$ kafka-console-producer.sh --broker-list opsxlab-kafka-controller-0.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,opsxlab-kafka-controller-1.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,opsxlab-kafka-controller-2.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092 --topic test
- >cluster kafka test 1
- >cluster kafka test 2
复制代码 消耗者侧:- I have no name!@opsxlab-kafka-client:/$ kafka-console-consumer.sh \
- --bootstrap-server opsxlab-kafka.opsxlab.svc.cluster.local:9092 \
- --topic test \
- --from-beginningcluster kafka test 1cluster kafka test 2
复制代码 3.2 k8s 集群外部验证
为了更严谨的测试 Kafka 在 K8s 集群外的可用性,我在 K8s 集群外找了一台机器,安装 JDK 和 Kafka。安装方式上 JDK 选择了 Yum 安装 openjdk,Kafka 则选用了官方提供的二进制包。
实际测试时还可以选择 Docker 镜像或是在 K8s 集群上再创建一个 Pod,测试时连接 K8s 节点的宿主机 IP 和 NodePort。
- # 安装 JDK
- yum install java-1.8.0-openjdk
- # 下载 Kafka
- cd /srv
- wget https://downloads.apache.org/kafka/3.7.1/kafka_2.13-3.7.1.tgz
- # 解压
- tar xvf kafka_2.13-3.7.1.tgz
- cd /srv/kafka_2.13-3.7.1/bin
复制代码 一共 3个 Kafka Pod,每个 Pod 的 advertised.listeners 配置不同,在 K8s 控制节点,分别执行下面的命令:- kubectl exec -n opsxlab -it opsxlab-kafka-controller-0 -- cat /opt/bitnami/kafka/config/server.properties | grep advertised.listeners
- kubectl exec -n opsxlab -it opsxlab-kafka-controller-1 -- cat /opt/bitnami/kafka/config/server.properties | grep advertised.listeners
- kubectl exec -n opsxlab -it opsxlab-kafka-controller-2 -- cat /opt/bitnami/kafka/config/server.properties | grep advertised.listeners
复制代码 正确执行后,输出结果如下 :- $ kubectl exec -n opsxlab -it opsxlab-kafka-controller-0 -- cat /opt/bitnami/kafka/config/server.properties | grep advertised.listeners
- Defaulted container "kafka" out of: kafka, kafka-init (init)
- advertised.listeners=CLIENT://opsxlab-kafka-controller-0.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,INTERNAL://opsxlab-kafka-controller-0.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9094,EXTERNAL://192.168.9.125:31211
- $ kubectl exec -n opsxlab -it opsxlab-kafka-controller-1 -- cat /opt/bitnami/kafka/config/server.properties | grep advertised.listeners
- Defaulted container "kafka" out of: kafka, kafka-init (init)
- advertised.listeners=CLIENT://opsxlab-kafka-controller-1.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,INTERNAL://opsxlab-kafka-controller-1.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9094,EXTERNAL://192.168.9.124:31212
- $ kubectl exec -n opsxlab -it opsxlab-kafka-controller-2 -- cat /opt/bitnami/kafka/config/server.properties | grep advertised.listeners
- Defaulted container "kafka" out of: kafka, kafka-init (init)
- advertised.listeners=CLIENT://opsxlab-kafka-controller-2.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9092,INTERNAL://opsxlab-kafka-controller-2.opsxlab-kafka-controller-headless.opsxlab.svc.cluster.local:9094,EXTERNAL://192.168.9.126:31213
复制代码 跟 K8s 集群内部验证测试过程一样,打开两个终端,运行生产者和消耗者脚本。执行下面的命令验证测试(细节略过,直接上结果)。
外部生产者侧:- $ ./kafka-console-producer.sh --broker-list 192.168.9.125:31211 --topic test
- >external kafka test 3
- >external kafka test 4
复制代码 外部消耗者侧:- $ ./kafka-console-consumer.sh --bootstrap-server 192.168.9.125:31211 --topic test --from-beginning
- cluster kafka test 1
- cluster kafka test 2
- external kafka test 3
- external kafka test 4
复制代码注意: 外部消耗者能消耗到所有数据,包括集群内部测试时天生的数据。
集群内消耗者侧: 集群内的消耗者,同样能获取外部生产者产生的数据。- I have no name!@opsxlab-kafka-client:/$ kafka-console-consumer.sh \
- --bootstrap-server opsxlab-kafka.opsxlab.svc.cluster.local:9092 \
- --topic test \
- --from-beginningcluster kafka test 1cluster kafka test 2external kafka test 3external kafka test 4
复制代码 免责声明:
- 笔者水平有限,尽管颠末多次验证和检查,尽力确保内容的准确性,但仍可能存在疏漏之处。敬请业界专家大佬不吝指教。
- 本文所述内容仅通过实战环境验证测试,读者可学习、鉴戒,但严禁直接用于生产环境。由此引发的任何问题,作者概不负责!
本文由博客一文多发平台 OpenWrite 发布!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |