草庐IT

k8s部署kafka集群

MssGuo 2023-09-04 原文

前言

环境:centos 7.9 k8s集群、zookeeper集群

本篇将在k8s中部署kafka集群,kafka依赖zookeeper集群,zookeeper集群我们已经搭建好了,可以参考https://blog.csdn.net/MssGuo/article/details/127773132

制作对应版本的kafka镜像

由于k8s官网没有kafka的相关集群安装说明,所以只好手动制作对应版本的kafka镜像。

#kafka需要jdk,所以需要下载jdk,JDK的tar包官网:`https://www.oracle.com/java/technologies/downloads/`  自行下载;
#这里直接使用dockerhub上的jkd8镜像
docker pull ascdc/jdk8
docker tag ascdc/jdk8:latest jdk8:latest

#下载官网的kafka安装包
wget https://downloads.apache.org/kafka/3.3.1/kafka_2.13-3.3.1.tgz
mkdir /root/kafka-cluster && cd /root/kafka-cluster && touch Dockerfile
[root@matser kafka-cluster]# ll
总用量 102604
-rw-r--r-- 1 root root       190 1110 22:09 Dockerfile
-rw-r--r-- 1 root root 105053134 1110 01:31 kafka_2.13-3.3.1.tgz
-rw-r--r-- 1 root root      7448 1110 23:12 kafka-sts.yaml
[root@matser kafka-cluster]# 
 
#开始编写Dockerfile文件,制作kafka镜像
vim Dockerfile
FROM jdk8:latest
COPY kafka_2.13-3.3.1.tgz /opt/kafka_2.13-3.3.1.tgz
WORKDIR /opt/
RUN tar -zxvf kafka_2.13-3.3.1.tgz && rm -rf kafka_2.13-3.3.1.tgz && mv kafka_2.13-3.3.1 kafka
EXPOSE 9092


#构建kafka镜像
docker build --no-cache -t kafka:v2.13-3.3.1 .
#查看镜像,已经构成成功
[root@matser kafka-cluster]# docker images | grep kafka
kafka           v2.13-3.3.1   4b5c27bf09e5   8 minutes ago   499MB
#分发镜像到node1、node2上,也可以上传到镜像仓库
[root@matser kafka-cluster]# docker save -o kafkav2.13-3.3.1.tar.gz kafka:v2.13-3.3.1 
[root@matser kafka-cluster]# scp kafkav2.13-3.3.1.tar.gz root@node1:/root
[root@matser kafka-cluster]# scp kafkav2.13-3.3.1.tar.gz root@node2:/root
#node1、node2上进行导入镜像
[root@node1 ~]# docker load -i kafkav2.13-3.3.1.tar.gz
[root@node2 ~]# docker load -i kafkav2.13-3.3.1.tar.gz

部署kafka集群

创建kafka的yaml文件

[root@matser kafka-cluster]# cat kafka-sts.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: kafka-hs
  namespace: default
  labels:
    app: kafka
spec:
  ports:
  - port: 9092
    name: server
  clusterIP: None
  selector:
    app: kafka
--- 
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: kafka-pdb
  namespace: default
spec:
  selector:
    matchLabels:
      app: kafka
  minAvailable: 1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: kafka
  namespace: default
spec:
  serviceName: kafka-hs
  replicas: 3
  selector:
    matchLabels:
      app: kafka
  template:
    metadata:
      labels:
        app: kafka
    spec:
      affinity:
#        podAntiAffinity:		#节点有限,这里就注释掉pod反亲和性
#          requiredDuringSchedulingIgnoredDuringExecution:
#            - labelSelector:
#                matchExpressions:
#                  - key: "app"
#                    operator: In
#                    values:
#                    - kafka
#              topologyKey: "kubernetes.io/hostname"
#        podAffinity:
#          preferredDuringSchedulingIgnoredDuringExecution:
#             - weight: 1
#               podAffinityTerm:
#                 labelSelector:
#                    matchExpressions:
#                      - key: "app"
#                        operator: In
#                        values:
#                        - zk
#                 topologyKey: "kubernetes.io/hostname"
      terminationGracePeriodSeconds: 300
      containers:
      - name: kafka
        imagePullPolicy: IfNotPresent
        image: kafka:v2.13-3.3.1
        resources:
          requests:
            memory: "300M"			#生产环境一个给大一点
            cpu: 500m				#生产环境一个给大一点
        ports:
        - containerPort: 9092
          name: server
        command:
        - sh
        - -c
        - "exec /opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties --override broker.id=${HOSTNAME##*-} \
          --override listeners=PLAINTEXT://:9092 \
          --override zookeeper.connect=zk-0.zk-hs.default.svc.cluster.local:2181,zk-1.zk-hs.default.svc.cluster.local:2181,zk-2.zk-hs.default.svc.cluster.local:2181 \
          --override log.dirs=/var/lib/kafka/data \
          --override auto.create.topics.enable=true \
          --override auto.leader.rebalance.enable=true \
          --override background.threads=10 \
          --override compression.type=producer \
          --override delete.topic.enable=true \
          --override leader.imbalance.check.interval.seconds=300 \
          --override leader.imbalance.per.broker.percentage=10 \
          --override log.flush.interval.messages=9223372036854775807 \
          --override log.flush.offset.checkpoint.interval.ms=60000 \
          --override log.flush.scheduler.interval.ms=9223372036854775807 \
          --override log.retention.bytes=-1 \
          --override log.retention.hours=168 \
          --override log.roll.hours=168 \
          --override log.roll.jitter.hours=0 \
          --override log.segment.bytes=1073741824 \
          --override log.segment.delete.delay.ms=60000 \
          --override message.max.bytes=1000012 \
          --override min.insync.replicas=1 \
          --override num.io.threads=8 \
          --override num.network.threads=3 \
          --override num.recovery.threads.per.data.dir=1 \
          --override num.replica.fetchers=1 \
          --override offset.metadata.max.bytes=4096 \
          --override offsets.commit.required.acks=-1 \
          --override offsets.commit.timeout.ms=5000 \
          --override offsets.load.buffer.size=5242880 \
          --override offsets.retention.check.interval.ms=600000 \
          --override offsets.retention.minutes=1440 \
          --override offsets.topic.compression.codec=0 \
          --override offsets.topic.num.partitions=50 \
          --override offsets.topic.replication.factor=3 \
          --override offsets.topic.segment.bytes=104857600 \
          --override queued.max.requests=500 \
          --override quota.consumer.default=9223372036854775807 \
          --override quota.producer.default=9223372036854775807 \
          --override replica.fetch.min.bytes=1 \
          --override replica.fetch.wait.max.ms=500 \
          --override replica.high.watermark.checkpoint.interval.ms=5000 \
          --override replica.lag.time.max.ms=10000 \
          --override replica.socket.receive.buffer.bytes=65536 \
          --override replica.socket.timeout.ms=30000 \
          --override request.timeout.ms=30000 \
          --override socket.receive.buffer.bytes=102400 \
          --override socket.request.max.bytes=104857600 \
          --override socket.send.buffer.bytes=102400 \
          --override unclean.leader.election.enable=true \
          --override zookeeper.session.timeout.ms=6000 \
          --override zookeeper.set.acl=false \
          --override broker.id.generation.enable=true \
          --override connections.max.idle.ms=600000 \
          --override controlled.shutdown.enable=true \
          --override controlled.shutdown.max.retries=3 \
          --override controlled.shutdown.retry.backoff.ms=5000 \
          --override controller.socket.timeout.ms=30000 \
          --override default.replication.factor=1 \
          --override fetch.purgatory.purge.interval.requests=1000 \
          --override group.max.session.timeout.ms=300000 \
          --override group.min.session.timeout.ms=6000 \
          --override log.cleaner.backoff.ms=15000 \
          --override log.cleaner.dedupe.buffer.size=134217728 \
          --override log.cleaner.delete.retention.ms=86400000 \
          --override log.cleaner.enable=true \
          --override log.cleaner.io.buffer.load.factor=0.9 \
          --override log.cleaner.io.buffer.size=524288 \
          --override log.cleaner.io.max.bytes.per.second=1.7976931348623157E308 \
          --override log.cleaner.min.cleanable.ratio=0.5 \
          --override log.cleaner.min.compaction.lag.ms=0 \
          --override log.cleaner.threads=1 \
          --override log.cleanup.policy=delete \
          --override log.index.interval.bytes=4096 \
          --override log.index.size.max.bytes=10485760 \
          --override log.message.timestamp.difference.max.ms=9223372036854775807 \
          --override log.message.timestamp.type=CreateTime \
          --override log.preallocate=false \
          --override log.retention.check.interval.ms=300000 \
          --override max.connections.per.ip=2147483647 \
          --override num.partitions=1 \
          --override producer.purgatory.purge.interval.requests=1000 \
          --override replica.fetch.backoff.ms=1000 \
          --override replica.fetch.max.bytes=1048576 \
          --override replica.fetch.response.max.bytes=10485760 \
          --override reserved.broker.max.id=1000"
        env:
        - name: KAFKA_HEAP_OPTS
          value : "-Xmx500M -Xms500M"
        - name: KAFKA_OPTS
          value: "-Dlogging.level=INFO"
        volumeMounts:
        - name: datadir
          mountPath: /var/lib/kafka/data
#        readinessProbe:		#存活探针死活都是探测失败,不知道为什么,这里不使用探针了
#          exec:
#           command:
#            - sh
#            - -c
#            - "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server=localhost:9092"
#          tcpSocket:
#             port: 9092   
#          initialDelaySeconds: 10
#          periodSeconds: 3
#          timeoutSeconds: 2
#          failureThreshold: 2
      securityContext:
        runAsUser: 1000
        fsGroup: 1000
  volumeClaimTemplates:
  - metadata:
      name: datadir
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 500M
      storageClassName: "nfs-storageclass"
[root@matser kafka-cluster]# 

参数说明:
zookeeper.connect=zk-0.zk-hs.default.svc.cluster.local:2181,zk-1.zk-hs.default.svc.cluster.local:2181,zk-2.zk-hs.default.svc.cluster.local:2181 指定了zookeeper集群,zk集群也是在k8s中定义好了,而且zk-0.zk-hs.default.svc.cluster.local能解析成zk的pod的IP地址

启动kafka集群

[root@matser zookeeper-cluster]#  kubectl apply -f kafka-sts.yaml -l app=kafka
[root@matser zookeeper-cluster]# kubectl  get pods
NAME                                      READY   STATUS        RESTARTS      AGE
kafka-0                                   1/1     Running   	0 (10m ago)   15m
kafka-1                                   1/1     Running   	0 (10m ago)   15m
kafka-2                                   1/1     Running   	0 (10m ago)   15m

验证kafka集群是否正常

1、查看kafka的pod日志
kubectl logs  -f  kafka-0
kubectl logs  -f  kafka-1
kubectl logs  -f  kafka-2
2、查看zookeeper是否已经注册了kafka
[root@matser ~]# kubectl exec -it zk-0 -- bash				#登录一个zookeeper的pod
 zookeeper@zk-0:/$ zkCli.sh									#登录zk集群
[zk: localhost:2181(CONNECTED) 0] ls /						#查看,可以看到有很多节点
[cluster, controller_epoch, controller, brokers, zookeeper, feature, admin, isr_change_notification, consumers, log_dir_event_notification, latest_producer_id_block, config]
[zk: localhost:2181(CONNECTED) 1] ls /brokers
[ids, topics, seqid]
[zk: localhost:2181(CONNECTED) 2] ls /brokers/ids			#可以看到有个/brokers/ids有3个,这就是kafka的3个节点
[0, 1, 2]
[zk: localhost:2181(CONNECTED) 3] 
3、在kafka集群创建topic
[root@matser ~]# kubectl exec -it kafka-1 -- sh			#登录kafka的pod
$ cd /opt/kafka/bin										#下面就是创建一个topic
$ ./kafka-topics.sh --bootstrap-server localhost:9092 --topic first --create --partitions 1 --replication-factor 3
Created topic first.
$ ./kafka-topics.sh --bootstrap-server localhost:9092 --topic first  --describe		#查看指定topic的详细描述
Topic: first	TopicId: ucPP_X9bS8ezdmf_iqExdQ	PartitionCount: 1	ReplicationFactor: 3	Configs: compression.type=producer,min.insync.replicas=1,cleanup.policy=delete,segment.bytes=1073741824,flush.messages=9223372036854775807,file.delete.delay.ms=60000,max.message.bytes=1000012,min.compaction.lag.ms=0,message.timestamp.type=CreateTime,preallocate=false,min.cleanable.dirty.ratio=0.5,index.interval.bytes=4096,unclean.leader.election.enable=true,retention.bytes=-1,delete.retention.ms=86400000,message.timestamp.difference.max.ms=9223372036854775807,segment.index.bytes=10485760
	Topic: first	Partition: 0	Leader: 2	Replicas: 2,1,0	Isr: 2,1,0
4、查看后端存储是否有数据
[root@nginx data]# ll default-datadir-kafka-0-pvc-75b8d6ab-7e0f-41f8-a0c9-98fc9ca0529e
总用量 16
-rw-r--r-- 1 1000 nfsnobody   0 1110 23:12 cleaner-offset-checkpoint
drwxr-xr-x 2 1000 nfsnobody 167 1111 00:26 first-0
-rw-r--r-- 1 1000 nfsnobody   4 1111 00:36 log-start-offset-checkpoint
-rw-r--r-- 1 1000 nfsnobody  88 1111 00:26 meta.properties
-rw-r--r-- 1 1000 nfsnobody  26 1111 00:36 recovery-point-offset-checkpoint
-rw-r--r-- 1 1000 nfsnobody  26 1111 00:36 replication-offset-checkpoint
[root@nginx data]# 

自此,kakfa集群已经搭建完毕。

排查过程

在部署kafka集群的过程中,出现了很多问题,这里记录一下:
1、创建好的镜像出现问题,创建好的镜像一启动就被杀掉,一直处于重启,挂掉,重启挂掉的过程,这明显就是镜像里面的的进程启动失败了没有任何前台进程夯住容器导致。但是kubectl logskubectl describe根本看不出来是为什么kafka进程启动失败。所以,为什么弄明白为什么kafka进程启动失败,得先想办法进入容器手动启动kafka看看。
所以,得先启动容器吧,然后在容器里面使用yaml文件的command参数来启动kafka,为了能正常启动容器,这里需要对Dockerfile文件做一下修改:

[root@matser zookeeper-cluster]# cat ../kafka-cluster/Dockerfile 
FROM jdk8:latest
COPY kafka_2.13-3.3.1.tgz /opt/kafka_2.13-3.3.1.tgz
WORKDIR /opt/
RUN tar -zxvf kafka_2.13-3.3.1.tgz && rm -rf kafka_2.13-3.3.1.tgz && mv kafka_2.13-3.3.1 kafka
EXPOSE 9092
ENTRYPOINT ["/bin/bash","-c","sleep 99999"]				#加上这条,为了让容器正常启动

创建镜像,启动pod,进入容器手动启动kafka,看看报什么错误:

/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties --override broker.id=0 \
          --override listeners=PLAINTEXT://:9092 \
          --override zookeeper.connect=zk-0.zk-hs.default.svc.cluster.local:2181,zk-1.zk-hs.default.svc.cluster.local:2181,zk-2.zk-hs.default.svc.cluster.local:2181 \
          --override log.dirs=/var/lib/kafka/data \
.....................................................................
报错如下:
[2022-11-10 14:38:26,375] INFO Registered kafka:type=kafka.Log4jController MBean (kafka.utils.Log4jControllerRegistration$)
[2022-11-10 14:38:26,713] INFO Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation (org.apache.zookeeper.common.X509Util)
[2022-11-10 14:38:26,787] ERROR Exiting Kafka due to fatal exception (kafka.Kafka$)
java.lang.IllegalArgumentException: requirement failed: log.message.format.version 3.0-IV1 can only be used when inter.broker.protocol.version is set to version 0.11.0 or higher
	at scala.Predef$.require(Predef.scala:337)
	at kafka.server.KafkaConfig.validateValues(KafkaConfig.scala:2227)
	at kafka.server.KafkaConfig.<init>(KafkaConfig.scala:2063)
	at kafka.server.KafkaConfig.<init>(KafkaConfig.scala:1495)
	at kafka.Kafka$.buildServer(Kafka.scala:67)
	at kafka.Kafka$.main(Kafka.scala:87)
	at kafka.Kafka.main(Kafka.scala)

原来--override inter.broker.protocol.version=0.10.2-IV0参数的版本设置的有问题 。嘛的,干脆删掉它吧。让kafka自己匹配得了。

2、就绪探针一直探测失败,导致pod无法正常running。这个问题未解决,暂时不使用探针。

3、持久化存储没有数据。
明明已经指定了kafka的数据存在 --override log.dir=/var/lib/kafka/data 目录,而且也把

volumeMounts:
        - name: datadir
          mountPath: /var/lib/kafka/data

挂载到了存储上了,怎么nfs服务器上没有数据呢?一看,我靠,好坑,command命令log.dir参数是从网上复制过来的, log.dir在我这个kafka版本里面根本不是这样定义的,进入kafka-0 pod里面看/opt/kafka/config/server.properties ,人家参数名叫log.dirs有个s,也不知道kafka启动为什么不报错,网上的那些怎么是log.dir的。

有关k8s部署kafka集群的更多相关文章

  1. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  2. ruby-on-rails - Ruby on Rails 可以部署在 Azure 网站上吗? - 2

    我可以在Azure网站上部署RubyonRails吗? 最佳答案 还没有。目前仅支持.NET和PHP。 关于ruby-on-rails-RubyonRails可以部署在Azure网站上吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/12964010/

  3. jenkins部署1--jenkins+gitee持续集成 - 2

    前置步骤我们都操作完了,这篇开始介绍jenkins的集成。话不多说,看操作1、登录进入jenkins后会让你选择安装插件,选择第一个默认的就行。安装完成后设置账号密码,重新登录。2、配置JDK和Git都需要执行路径,所以需要先把执行路径找到,先进入服务器的docker容器,2.1JDK的路径root@69eef9ee86cf:/usr/bin#echo$JAVA_HOME/usr/local/openjdk-82.2Git的路径root@69eef9ee86cf:/#whichgit/usr/bin/git3、先配置JDK和Git。点击:ManageJenkins>>GlobalToolCon

  4. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  5. Ruby,使用包含 TK GUI 的 ocra 部署一个 exe - 2

    Ocra无法处理需要“tk”的应用程序require'tk'puts'nope'用奥克拉http://github.com/larsch/ocra不起作用(如链接中的一个问题所述)问题:https://github.com/larsch/ocra/issues/29(Ocra是1.9的"new"rubyscript2exe,本质上它用于将rb脚本部署为可执行文件)唯一的问题似乎是缺少tcl的DLL文件我不认为这是一个问题据我所知,问题是缺少tk的DLL文件如果它们是已知的,则可以在执行ocra时将它们包括在内有没有办法知道tk工作所需的DLL依赖项? 最佳答

  6. ruby-on-rails - NameError(未初始化常量 Unzipper::Zip)但仅在 Heroku 部署(Rails)上 - 2

    我有一个类unzipper.rb,它使用Rubyzip解压文件。在我的本地环境中,我可以成功解压缩文件,而无需使用require'zip'明确包含依赖项但是在Heroku上,我得到一个NameError(uninitializedconstantUnzipper::Zip)我只能通过使用明确的require来解决问题:为什么这在H​​eroku环境中是必需的,但在本地主机上却不是?我的印象是Rails自动需要所有gem。app/services/unzipper.rbrequire'zip'#OnlyrequiredforHeroku.Workslocallywithout!class

  7. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  8. ruby-on-rails - 在服务器上没有互联网访问权限的 Capistrano 部署 - 2

    如何使用Capistrano将Rails应用程序部署到无法访问外部网络或存储库的生产或暂存服务器?我已经设法完成部署的一半,并意识到Capistrano没有在我的本地机器上下载gitrepo,但它首先连接到远程服务器并尝试在那里下载Git存储库。我希望有一个类似Javaee的构建系统,其中创建可交付成果并将该可交付成果发送到服务器。就像您构建.ear文件并将其部署到您想要的任何服务器上一样。显然在RoR中,你被迫(据我所知)在该服务器上构建应用程序,在那里创建一个gem存储库,在那里克隆最新的分支等等。有什么方法可以将准备运行的包发送到远程服务器吗? 最佳答

  9. 【详解】Docker安装Elasticsearch7.16.1集群 - 2

    开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建

  10. Streampark集成Cloudera Flink、ldap、告警,以及部署常见问题 - 2

    集成背景我们当前集群使用的是ClouderaCDP,Flink版本为ClouderaVersion1.14,整体Flink安装目录以及配置文件结构与社区版本有较大出入。直接根据Streampark官方文档进行部署,将无法配置FlinkHome,以及后续整体Flink任务提交到集群中,因此需要进行针对化适配集成,在满足使用需求上,尽量提供完整的Streampark使用体验。集成步骤版本匹配问题解决首先解决无法识别Cloudera中的FlinkHome问题,根据报错主要明确到的事情是无法读取到Flink版本、lib下面的jar包名称无法匹配。修改对象:修改源码:(解决无法匹配clouderajar

随机推荐