背景随着业务规模的发展,需要越来越多的Kafka集群,这给部署和管理带来了极大的挑战。我们期望能够利用K8S出色的扩容和快速部署能力来减轻日常工作的负担。因此,我们对K8S在Kafka上的可行性进行了研究。和Kafka集群一样,涉及的组件很多,都是有状态的集群。该行业使用自定义运营商解决方案。目前GitHub上有多个相关仓库。根据社区活跃度和用户数量综合考虑,本次使用StrimziGithub地址。kafka组件交互图方案使用阿里云K8S集群部署Strimzi。由于组内使用的kafka是开源版本开发而来,因此需要维护一个自定义的Strimzi-kafka镜像。strimzi管理kafka集群,包括kafka、zk、kafka-exporter,使用动物园入口代理集群中的zkGitHub地址部署prometheus,收集kafka和zk的metrics,开放服务端口,将kafka和zk暴露给在K8S集群外,使用实际流程构建自定义kafka镜像,从公司的Git中拉取最新代码strimzi-kafka-operator(与开源版本略有改动,可以直接使用开源版本进行experiments)在docker-images文件夹下,有一个Makefile,执行里面的docker_build,就会执行里面的build。脚本;这一步会从官网拉取kafka安装包,我们需要将这一步中的包修改为我们内部的安装包。构建镜像后,镜像是本地的。我们需要将镜像上传到公司内部的harbor服务器部署operator。每个K8S集群只需要部署一个Operator。充分必要条件:为健康的k8s集群创建命名空间,已经存在则跳过。默认使用kafka,kubectlcreatenamespacekafka从公司的Git中拉取最新的代码(地址在前面)。目前该文件默认监听名为kafka的命名空间。如果需要修改,执行sed-i's/namespace:./namespace:kafka/'install/cluster-operator/RoleBinding*.yaml(将命令中的kafka/替换掉)然后apply所有文件kubectlapply-finstall/cluster-operator/-nkafka稍等片刻,可以查看创建的自定义资源和operatorkubectlgetpods-nkafka,从阿里云的k8s控制台查看这些资源的创建和operator的运行情况。部署kafka集群,确保你的operator已经部署成功,而kafka部署的namespace需要在operator上面或者在最新的代码目录中进行监控。此部署所需的文件位于examples/kafka目录下。部署kafka和zk查看kafka-persistent.yaml,这是核心文件是的,这个文件部署了kafka,zk和kafka-exporter,其中一些如下:apiVersion:kafka.strimzi.io/v1beta2kind:Kafkametadata:name:my-clusterspec:kafka:版本:2.8.1副本:3资源:请求:内存:16Gicpu:4000m限制:内存:16Gicpu:4000m图像:repository.poizon.com/kafka-operator/poizon/kafka:2.8.4jvmOptions:-Xms:3072m-Xmx:3072m侦听器:-名称:外部端口:9092类型:nodeporttls:false-名称:普通端口:9093类型:内部tls:false配置:offsets.topic.replication。因子:2transaction.state.log.replication.factor:2transaction.state.log.min.isr:1default.replication.factor:2***模板:pod:affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:-labelSelector:matchExpressions:-key:strimzi.io/nameoperator:Invalues:-my-cluster-kafkatopologyKey:"kubernetes.io/hostname"storage:type:persistent-claimsize:100Giclass:rocketmq-storagedeleteClaim:falsemetricsConfig:类型:jmx普罗米修斯usExportervalueFrom:configMapKeyRef:名称:kafka-metricskey:kafka-metrics-config.ymlzookeeper:replicas:3resources:requests:memory:3Gicpu:1000mlimits:memory:3Gicpu:1000mjvmOptions:-Xms:2048m-Xm:2048mjmxOptions:{}模板:pod:亲和力:podAntiAffinity:***存储:类型:持久声明大小:50Gi类:rocketmq-storagedeleteClaim:falsemetricsConfig:类型:jmxPrometheusExportervalueFrom:config:MapKeyRefkey:名称:zookeeper-metrics-config.yml******可以修改kafka集群的名称。第四行的name属性目前默认为my-cluster。可以修改kafka中的pod个数,也就是节点个数。默认为3Pod配置内存CPU可修改kafkaJVM启动的堆内存大小可修改Kafka配置可修改,磁盘类型和大小可在第36行config配置中修改,类型为第50行,可以修改为其他存储类,目前可选高效云盘、SSD、ESSDzk,修改同kafka。可修改的东西都差不多,同一个文件下是kafka和zk需要暴露的metrics。可以根据需要增删改改配置,然后直接执行kubectapply-fkafka-persistent.yaml-nkafka可以创建和部署zk代理。由于官方不支持外部组件直接访问zk,所以采用代理方式访问zk。出于安全考虑,官方故意不支持外部程序访问zk:https://github.com/strimzi/strimzi-kafka-operator/issues/1337解决方法:https://github.com/scholzj/zo。..部署完zk代理后,我们需要在k8s控制台创建一个loadbalance服务,将这个代理暴露给集群外的应用进行连接具体操作:k8sconsole-->network-->service-->create(选择loadbalance创建,然后找到zoo-entrance应用)deployzk-exporter官方operator中没有zk-exporter,我们使用https://github.com/dabealu/zo...文件夹中的zk-exporter.yaml文件,我们只需要修改监控zk的地址(spec.container.args),执行kubectlapply-fzk-出口商。yaml可以部署。部署kafka-jmx。由于ingress不支持tcp连接,loadbalance的成本太高,kafka的jmx使用nodeport对外暴露。可以在阿里云控制台创建对应的nodeport,或者使用kafka-jmx创建apiVersion:v1kind:Servicemetadata:labels:strimzi.io/cluster:my-clusterstrimzi.io/name:my-cluster-kafka-jmxname:my-cluster-kafka-jmx-0spec:端口:-名称:kafka-jmx-nodeport端口:9999协议:TCPtargetPort:9999选择器:statefulset.kubernetes.io/pod-name:my-cluster-kafka-0strimzi。io/cluster:my-clusterstrimzi.io/kind:Kafkastrimzi.io/name:my-cluster-kafkatype:NodePortDeploykafka-exporter-service在之前部署kafka之后,我们的配置中启用了exporter。但是exporter正式开启后,并没有自动生成相关的服务。为了让Prometheus连接更方便,我们在文件夹kafka-exporter-service.yaml文件里部署了一个serviceapiVersion:v1kind:Servicemetadata:labels:app:kafka-export-servicename:my-cluster-kafka-exporter-服务规范:端口:-端口:9404协议:TCPtargetPort:9404选择器:strimzi.io/cluster:my-clusterstrimzi.io/kind:Kafkastrimzi。io/name:my-cluster-kafka-exportertype:ClusterIP执行kubectlapply-fkafka-exporter-service.yaml进行部署。部署kafka-prometheus如果Prometheus部署在k8s集群外,采集数据会比较麻烦,所以我们直接将Prometheus部署到集群内部文件夹的kafka-prometheus.yaml文件中,并选择性地修改prometheus的配置,如作为需要内存CPU的大小,比如监控数据的存储时间,外接云盘的大小,以及需要监控的kafka和zk地址apiVersion:apps/v1kind:StatefulSetmetadata:name:kafka-prometheus标签:应用程序:kafka-prometheusspec:副本:1revisionHistoryLimit:10选择器:matchLabels:app:kafka-prometheus服务名称:kafka-prometheusupdateStrate类型:RollingUpdate模板:元数据:标签:应用程序:kafka-prometheus规范:容器:-args:-'--query.max-concurrency=800'-'--query.max-samples=800000000'***命令:-/bin/prometheus图像:'repository.poizon.com/prometheus/prometheus:v2.28.1'imagePullPolicy:IfNotPresentlivenessProbe:failureThreshold:10httpGet:path:/statusport:webscheme:HTTPinitialDelaySeconds:300periodSeconds:5successThreshold:1timeoutSeconds:3name:kafka-prometheus资源:限制:cpu:500m内存:512Mi请求:cpu:200m内存:128MivolumeMounts:-mountPath:/etc/localtime名称:volume-localtime-mountPath:/data/prometheus/na我:kafka-prometheus-config-mountPath:/data/database/prometheus名称:kafka-prometheus-dbterminationMessagePath:/dev/termination-logterminationMessagePolicy:FileterminationGracePeriodSeconds:30restartPolicy:AlwaysschedulerName:default-schedulersecurityContext:fsGroup:0volumes:-hostPath:path:/etc/localtimetype:''name:volume-localtime-configMap:defaultMode:420name:kafka-prometheus-configname:kafka-prometheus-configvolumeClaimTemplates:-apiVersion:v1kind:PersistentVolumeClaim元数据:name:kafka-prometheus-dbspec:accessModes:-ReadWriteOnceresources:requests:storage:20GistorageClassName:rocketmq-storagevolumeMode:Filesystemstatus:phase:Pending执行kubectlapply-fkafka-prometheus.yaml可以部署。部署完成后,prometheus会暴露在监控组的grafana中。可以直接连接podIP验证,然后创建k8s控制台网络-->路由-->创建Ingress,选择刚刚部署的Prometheus服务,然后找到运维申请域名,和可以总结出集群快速部署(分钟)、集群快速扩容(秒)、容灾快速(秒)的优势。支持滚动更新。备份和恢复的缺点是引入了更多的组件,复杂度增加。K8S集群外访问不是很友好。文/ZUOQI关注事物的科技,做最时尚的科技人!
