• 【云原生】详解 Zookeeper + Kafka on K8S 环境部署


    一、概述

    • Apache ZooKeeper 是一个集中式服务,用于维护配置信息、命名、提供分布式同步和提供组服务,ZooKeeper 致力于开发和维护一个开源服务器,以实现高度可靠的分布式协调,其实也可以认为就是一个分布式数据库,只是结构比较特殊,是树状结构。官网文档:

    https://zookeeper.apache.org/doc/r3.8.0/

    • Kafka是最初由 Linkedin 公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于 zookeeper 协调的分布式消息系统。官方文档:

      https://kafka.apache.org/documentation/

    二、Zookeeper on k8s 部署

    1)添加源

    部署包地址:

    https://artifacthub.io/packages/helm/zookeeper/zookeeper

    1. helm repo add bitnami https://charts.bitnami.com/bitnami
    2. helm pull bitnami/zookeeper
    3. tar -xf zookeeper-10.2.1.tgz

    2)修改配置

    • 修改zookeeper/values.yaml

    1. image:
    2. #如果有私有镜像仓库,需要配置仓库地址
    3. registry: myharbor.com
    4. repository: bigdata/zookeeper
    5. tag: 3.8.0-debian-11-r36
    6. ...
    7. replicaCount: 3
    8. ...
    9. service:
    10. type: NodePort
    11. nodePorts:
    12. #NodePort 默认范围是 30000-32767
    13. client: "32181"
    14. tls: "32182"
    15. ...
    16. persistence:
    17. storageClass: "zookeeper-local-storage"
    18. size: "10Gi"
    19. # 目录需要提前在宿主机上创建
    20. local:
    21. - name: zookeeper-0
    22. host: "k8s-master"
    23. path: "/opt/bigdata/servers/zookeeper/data/data1"
    24. - name: zookeeper-1
    25. host: "k8s-node-1"
    26. path: "/opt/bigdata/servers/zookeeper/data/data1"
    27. - name: zookeeper-2
    28. host: "k8s-node-2"
    29. path: "/opt/bigdata/servers/zookeeper/data/data1"
    30. ...
    31. # Enable Prometheus to access ZooKeeper metrics endpoint
    32. metrics:
    33. enabled: true
    • 添加zookeeper/templates/pv.yaml

    1. {{- range .Values.persistence.local }}
    2. ---
    3. apiVersion: v1
    4. kind: PersistentVolume
    5. metadata:
    6. name: {{ .name }}
    7. labels:
    8. name: {{ .name }}
    9. spec:
    10. storageClassName: {{ $.Values.persistence.storageClass }}
    11. capacity:
    12. storage: {{ $.Values.persistence.size }}
    13. accessModes:
    14. - ReadWriteOnce
    15. local:
    16. path: {{ .path }}
    17. nodeAffinity:
    18. required:
    19. nodeSelectorTerms:
    20. - matchExpressions:
    21. - key: kubernetes.io/hostname
    22. operator: In
    23. values:
    24. - {{ .host }}
    25. ---
    26. {{- end }}
    • 添加zookeeper/templates/storage-class.yaml(如果环境当中已经存在sc,则无需再创建)

    1. kind: StorageClass
    2. apiVersion: storage.k8s.io/v1
    3. metadata:
    4. name: {{ .Values.persistence.storageClass }}
    5. provisioner: kubernetes.io/no-provisioner

    3)开始安装

    1. # 先准备好镜像
    2. docker pull docker.io/bitnami/zookeeper:3.8.0-debian-11-r36
    3. docker tag docker.io/bitnami/zookeeper:3.8.0-debian-11-r36 myharbor.com/bigdata/zookeeper:3.8.0-debian-11-r36
    4. docker push myharbor.com/bigdata/zookeeper:3.8.0-debian-11-r36
    5. # 开始安装
    6. helm install zookeeper ./zookeeper -n zookeeper --create-namespace

    NOTES 

    1. NAME: zookeeper
    2. LAST DEPLOYED: Sun Sep 18 18:24:03 2022
    3. NAMESPACE: zookeeper
    4. STATUS: deployed
    5. REVISION: 1
    6. TEST SUITE: None
    7. NOTES:
    8. CHART NAME: zookeeper
    9. CHART VERSION: 10.2.1
    10. APP VERSION: 3.8.0
    11. ** Please be patient while the chart is being deployed **
    12. ZooKeeper can be accessed via port 2181 on the following DNS name from within your cluster:
    13. zookeeper.zookeeper.svc.cluster.local
    14. To connect to your ZooKeeper server run the following commands:
    15. export POD_NAME=$(kubectl get pods --namespace zookeeper -l "app.kubernetes.io/name=zookeeper,app.kubernetes.io/instance=zookeeper,app.kubernetes.io/component=zookeeper" -o jsonpath="{.items[0].metadata.name}")
    16. kubectl exec -it $POD_NAME -- zkCli.sh
    17. To connect to your ZooKeeper server from outside the cluster execute the following commands:
    18. export NODE_IP=$(kubectl get nodes --namespace zookeeper -o jsonpath="{.items[0].status.addresses[0].address}")
    19. export NODE_PORT=$(kubectl get --namespace zookeeper -o jsonpath="{.spec.ports[0].nodePort}" services zookeeper)
    20. zkCli.sh $NODE_IP:$NODE_PORT

    查看 pod 状态

    kubectl get pods,svc -n zookeeper -owide

    4)测试验证

    1. # 登录zookeeper pod
    2. kubectl exec -it zookeeper-0 -n zookeeper -- zkServer.sh status
    3. kubectl exec -it zookeeper-1 -n zookeeper -- zkServer.sh status
    4. kubectl exec -it zookeeper-2 -n zookeeper -- zkServer.sh status
    5. kubectl exec -it zookeeper-0 -n zookeeper -- bash

    5)Prometheus 监控

    Prometheus:https://prometheus.k8s.local/targets?search=zookeeper

    修改values.yaml

    1. #修改配置如下:
    2. serviceMonitor:
    3. enabled: true #开启
    4. namespace: zookeeper #命名空间
    5. interval: 10s #采集间隔
    6. selector: #匹配endpoint
    7. app.kubernetes.io/name: zookeeper
    8. ---
    9. prometheusRule:
    10. enabled: true
    11. namespace: zookeeper
    12. rules:
    13. - alert: ZooKeeperSyncedFollowers
    14. annotations:
    15. message: The number of synced followers for the leader node in ZooKeeper deployment my-release is less than 2. This usually means that some of the ZooKeeper nodes aren't communicating properly. If it doesn't resolve itself you can try killing the pods (one by one).
    16. expr: max(synced_followers{service="my-release-metrics"}) < 2
    17. for: 5m
    18. labels:
    19. severity: critical
    20. - alert: ZooKeeperOutstandingRequests
    21. annotations:
    22. message: The number of outstanding requests for ZooKeeper pod {{ $labels.pod }} is greater than 10. This can indicate a performance issue with the Pod or cluster a whole.
    23. expr: outstanding_requests{service="my-release-metrics"} > 10
    24. for: 5m
    25. labels:
    26. severity: critical

     helm升级zookeeper:

    helm upgrade zookeeper -n zookeeper ./zookeeper

    检查资源是否创建:

    1. [root@k8s-master][16:03:41][OK] ~/zookeeper
    2. #kubectl get servicemonitor,prometheusrule -n zookeeper
    3. NAME AGE
    4. servicemonitor.monitoring.coreos.com/zookeeper 14m
    5. NAME AGE
    6. prometheusrule.monitoring.coreos.com/zookeeper 14m

     添加标签,关联kube-prometheus-stack(我的环境prometheus是用的这个)

    1. kubectl edit prometheusrules.monitoring.coreos.com -n zookeeper zookeeper
    2. #添加如下
    3. labels:
    4. release: kube-prometheus-stack
    5. kubectl edit prometheusrules.monitoring.coreos.com -n zookeeper zookeeper
    6. #添加如下
    7. labels:
    8. release: kube-prometheus-stack

    登录prometheus页面,查看targets是否正常: 

    可以通过命令查看采集数据

    1. kubectl get --raw http://10.164.140.90:9141/metrics
    2. kubectl get --raw http://10.161.201.39:9141/metrics
    3. kubectl get --raw http://10.172.82.223:9141/metrics

    Grafana:https://grafana.k8s.local/账号:admin,密码通过下面命令获取

    kubectl get secret --namespace grafana grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

    导入 grafana 模板,集群资源监控:10465
    官方模块下载地址:

    https://grafana.com/grafana/dashboards/

    6)卸载

    1. helm uninstall zookeeper -n zookeeper
    2. kubectl delete pod -n zookeeper `kubectl get pod -n zookeeper|awk 'NR>1{print $1}'` --force
    3. kubectl patch ns zookeeper -p '{"metadata":{"finalizers":null}}'
    4. kubectl delete ns zookeeper --force

    三、Kafka on k8s 部署

    1)添加源

    部署包地址:

    https://artifacthub.io/packages/helm/bitnami/kafka

    1. helm repo add bitnami https://charts.bitnami.com/bitnami
    2. helm pull bitnami/kafka
    3. tar -xf kafka-18.4.2.tgz

    2)修改配置

    • 修改kafka/values.yaml

    1. image:
    2. registry: myharbor.com
    3. repository: bigdata/kafka
    4. tag: 3.2.1-debian-11-r16
    5. ...
    6. replicaCount: 3
    7. ...
    8. service:
    9. type: NodePort
    10. nodePorts:
    11. client: "30092"
    12. external: "30094"
    13. ...
    14. externalAccess
    15. enabled: true
    16. service:
    17. type: NodePort
    18. nodePorts:
    19. - 30001
    20. - 30002
    21. - 30003
    22. useHostIPs: true
    23. ...
    24. persistence:
    25. storageClass: "kafka-local-storage"
    26. size: "10Gi"
    27. # 目录需要提前在宿主机上创建
    28. local:
    29. - name: kafka-0
    30. host: "local-168-182-110"
    31. path: "/opt/bigdata/servers/kafka/data/data1"
    32. - name: kafka-1
    33. host: "local-168-182-111"
    34. path: "/opt/bigdata/servers/kafka/data/data1"
    35. - name: kafka-2
    36. host: "local-168-182-112"
    37. path: "/opt/bigdata/servers/kafka/data/data1"
    38. ...
    39. metrics:
    40. kafka:
    41. enabled: true
    42. image:
    43. registry: myharbor.com
    44. repository: bigdata/kafka-exporter
    45. tag: 1.6.0-debian-11-r8
    46. jmx:
    47. enabled: true
    48. image:
    49. registry: myharbor.com
    50. repository: bigdata/jmx-exporter
    51. tag: 0.17.1-debian-11-r1
    52. annotations:
    53. prometheus.io/path: "/metrics"
    54. ...
    55. zookeeper:
    56. enabled: false
    57. ...
    58. externalZookeeper
    59. servers:
    60. - zookeeper-0.zookeeper-headless.zookeeper
    61. - zookeeper-1.zookeeper-headless.zookeeper
    62. - zookeeper-2.zookeeper-headless.zookeeper
    • 添加kafka/templates/pv.yaml

    1. {{- range .Values.persistence.local }}
    2. ---
    3. apiVersion: v1
    4. kind: PersistentVolume
    5. metadata:
    6. name: {{ .name }}
    7. labels:
    8. name: {{ .name }}
    9. spec:
    10. storageClassName: {{ $.Values.persistence.storageClass }}
    11. capacity:
    12. storage: {{ $.Values.persistence.size }}
    13. accessModes:
    14. - ReadWriteOnce
    15. local:
    16. path: {{ .path }}
    17. nodeAffinity:
    18. required:
    19. nodeSelectorTerms:
    20. - matchExpressions:
    21. - key: kubernetes.io/hostname
    22. operator: In
    23. values:
    24. - {{ .host }}
    25. ---
    26. {{- end }}
    • 添加kafka/templates/storage-class.yaml

    1. kind: StorageClass
    2. apiVersion: storage.k8s.io/v1
    3. metadata:
    4. name: {{ .Values.persistence.storageClass }}
    5. provisioner: kubernetes.io/no-provisioner

    3)开始安装

    1. # 先准备好镜像
    2. docker pull docker.io/bitnami/kafka:3.2.1-debian-11-r16
    3. docker tag docker.io/bitnami/kafka:3.2.1-debian-11-r16 myharbor.com/bigdata/kafka:3.2.1-debian-11-r16
    4. docker push myharbor.com/bigdata/kafka:3.2.1-debian-11-r16
    5. # node-export
    6. docker pull docker.io/bitnami/kafka-exporter:1.6.0-debian-11-r8
    7. docker tag docker.io/bitnami/kafka-exporter:1.6.0-debian-11-r8 myharbor.com/bigdata/kafka-exporter:1.6.0-debian-11-r8
    8. docker push myharbor.com/bigdata/kafka-exporter:1.6.0-debian-11-r8
    9. # JXM
    10. docker.io/bitnami/jmx-exporter:0.17.1-debian-11-r1
    11. docker tag docker.io/bitnami/jmx-exporter:0.17.1-debian-11-r1 myharbor.com/bigdata/jmx-exporter:0.17.1-debian-11-r1
    12. docker push myharbor.com/bigdata/jmx-exporter:0.17.1-debian-11-r1
    13. #开始安装
    14. helm install kafka ./kafka -n kafka --create-namespace

    NOTES

    1. NAME: kafka
    2. LAST DEPLOYED: Sun Sep 18 20:57:02 2022
    3. NAMESPACE: kafka
    4. STATUS: deployed
    5. REVISION: 1
    6. TEST SUITE: None
    7. NOTES:
    8. CHART NAME: kafka
    9. CHART VERSION: 18.4.2
    10. APP VERSION: 3.2.1
    11. ---------------------------------------------------------------------------------------------
    12. WARNING
    13. By specifying "serviceType=LoadBalancer" and not configuring the authentication
    14. you have most likely exposed the Kafka service externally without any
    15. authentication mechanism.
    16. For security reasons, we strongly suggest that you switch to "ClusterIP" or
    17. "NodePort". As alternative, you can also configure the Kafka authentication.
    18. ---------------------------------------------------------------------------------------------
    19. ** Please be patient while the chart is being deployed **
    20. Kafka can be accessed by consumers via port 9092 on the following DNS name from within your cluster:
    21. kafka.kafka.svc.cluster.local
    22. Each Kafka broker can be accessed by producers via port 9092 on the following DNS name(s) from within your cluster:
    23. kafka-0.kafka-headless.kafka.svc.cluster.local:9092
    24. kafka-1.kafka-headless.kafka.svc.cluster.local:9092
    25. kafka-2.kafka-headless.kafka.svc.cluster.local:9092
    26. To create a pod that you can use as a Kafka client run the following commands:
    27. kubectl run kafka-client --restart='Never' --image docker.io/bitnami/kafka:3.2.1-debian-11-r16 --namespace kafka --command -- sleep infinity
    28. kubectl exec --tty -i kafka-client --namespace kafka -- bash
    29. PRODUCER:
    30. kafka-console-producer.sh \
    31. --broker-list kafka-0.kafka-headless.kafka.svc.cluster.local:9092,kafka-1.kafka-headless.kafka.svc.cluster.local:9092,kafka-2.kafka-headless.kafka.svc.cluster.local:9092 \
    32. --topic test
    33. CONSUMER:
    34. kafka-console-consumer.sh \
    35. --bootstrap-server kafka.kafka.svc.cluster.local:9092 \
    36. --topic test \
    37. --from-beginning
    38. To connect to your Kafka server from outside the cluster, follow the instructions below:
    39. Kafka brokers domain: You can get the external node IP from the Kafka configuration file with the following commands (Check the EXTERNAL listener)
    40. 1. Obtain the pod name:
    41. kubectl get pods --namespace kafka -l "app.kubernetes.io/name=kafka,app.kubernetes.io/instance=kafka,app.kubernetes.io/component=kafka"
    42. 2. Obtain pod configuration:
    43. kubectl exec -it KAFKA_POD -- cat /opt/bitnami/kafka/config/server.properties | grep advertised.listeners
    44. 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:
    45. echo "$(kubectl get svc --namespace kafka -l "app.kubernetes.io/name=kafka,app.kubernetes.io/instance=kafka,app.kubernetes.io/component=kafka,pod" -o jsonpath='{.items[*].spec.ports[0].nodePort}' | tr ' ' '\n')"

    查看 pod 状态

    kubectl get pods,svc -n kafka -owide

    4)测试验证

    1. # 登录kafka的pod
    2. kubectl exec -it kafka-0 -n kafka -- bash

    1、创建 Topic(一个副本一个分区)

    1. --create: 指定创建topic动作
    2. --topic:指定新建topic的名称
    3. --bootstrap-server: 指定kafka连接地址
    4. --config:指定当前topic上有效的参数值,参数列表参考文档为: Topic-level configuration
    5. --partitions:指定当前创建的kafka分区数量,默认为1个
    6. --replication-factor:指定每个分区的复制因子个数,默认1个
    1. kafka-topics.sh --create --topic test001 --bootstrap-server kafka.kafka:9092 --partitions 1 --replication-factor 1
    2. # 查看
    3. kafka-topics.sh --describe --bootstrap-server kafka.kafka:9092 --topic test001

    2、查看 Topic 列表

    kafka-topics.sh --list --bootstrap-server kafka.kafka:9092

    3、生产者/消费者测试

    【生产者】

    1. kafka-console-producer.sh --broker-list kafka.kafka:9092 --topic test001
    2. {"id":"1","name":"n1","age":"20"}
    3. {"id":"2","name":"n2","age":"21"}
    4. {"id":"3","name":"n3","age":"22"}

    【消费者】

    1. # 从头开始消费
    2. kafka-console-consumer.sh --bootstrap-server kafka.kafka:9092 --topic test001 --from-beginning
    3. # 指定从分区的某个位置开始消费,这里只指定了一个分区,可以多写几行或者遍历对应的所有分区
    4. kafka-console-consumer.sh --bootstrap-server kafka.kafka:9092 --topic test001 --partition 0 --offset 100 --group test001

    4、查看数据积压

    kafka-consumer-groups.sh --bootstrap-server kafka.kafka:9092 --describe --group test001

    5、删除 topic

    kafka-topics.sh --delete --topic test001 --bootstrap-server kafka.kafka:9092
    

    5)Prometheus 监控

    Prometheus:

    https://prometheus.k8s.local/targets?search=kafka

    可以通过命令查看采集数据

    kubectl get --raw http://10.244.2.165:9308/metrics

    Grafana:https://grafana.k8s.local/
    账号:admin,密码通过下面命令获取

    kubectl get secret --namespace grafana grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

    导入 grafana 模板,集群资源监控:11962
    官方模块下载地址:

    https://grafana.com/grafana/dashboards/

    6)卸载

    1. helm uninstall kafka -n kafka
    2. kubectl delete pod -n kafka `kubectl get pod -n kafka|awk 'NR>1{print $1}'--force
    3. kubectl patch ns kafka  -'{"metadata":{"finalizers":null}}'
    4. kubectl delete ns kafka  --force
  • 相关阅读:
    使用vue-cli来搭建vue项目
    基于Python实现的Alpha-Beta剪枝算法
    react hook: useLayoutEffect
    黑马程序员Docker快速入门到项目部署(学习笔记)
    Javascript笔记(七)之函数、闭包、生成器、箭头函数
    【编程题】【Scratch四级】2021.12 聪明的小猫
    秋招每日一题T32——安排电影院座位
    假期如何控制孩子视力?推荐视力康复师分享的护眼灯
    智能机器人云控平台
    使用Resnet网络对人脸图像分类识别出男女性别(包含数据集制作+训练+测试)
  • 原文地址:https://blog.csdn.net/zfw_666666/article/details/126933020