背景
随着业务规模的发展,需要的kafka集群越来越来,这给部署与管理带来了很大的挑战。我们期望能够利用K8S优秀的扩容能力与快速部署能力,为日常的工作减负。所以就kafka上K8S的可行性方案进行了调研。
像kafka集群这种,涉及到的组件比较多,且都是有状态的集群,业界采用自定义operator的解决方案。目前GitHub上有多个相关的仓库,根据社区活跃度及使用数等综合考虑,此次采用Strimzi Github地址。
kafka组件交互图
方案
- 使用阿里云K8S集群部署Strimzi
- 由于组内使用的kafka是由开源版本二次开发而来,所以需要维护一个自定义的Strimzi-kafka镜像
- Strimzi管理kafka集群,其中包含kafka、zk、kafka-exporter、
- 使用zoo-entrance 代理集群中的zk GitHub地址
- 部署prometheus,采集kafka和zk的metrics
- 开启服务端口,暴露kafka及zk给K8S集群外部使用
实战过程
构建自定义kafka镜像
构建自定义kafka镜像
部署operator
每个K8S集群仅需部署一个operator
部署kafka集群
确保你的operator已经部署成功,且kafka部署的namespace需在上边operator的监控中
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-cluster
spec:
kafka:
version: 2.8.1
replicas: 3
resources:
requests:
memory: 16Gi
cpu: 4000m
limits:
memory: 16Gi
cpu: 4000m
image: repository.poizon.com/kafka-operator/poizon/kafka:2.8.4
jvmOptions:
-Xms: 3072m
-Xmx: 3072m
listeners:
- name: external
port: 9092
type: nodeport
tls: false
- name: plain
port: 9093
type: internal
tls: false
config:
offsets.topic.replication.factor: 2
transaction.state.log.replication.factor: 2
transaction.state.log.min.isr: 1
default.replication.factor: 2
***
template:
pod:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchexpressions:
- key: strimzi.io/name
operator: In
values:
- my-cluster-kafka
topologyKey: "kubernetes.io/hostname"
storage:
type: persistent-claim
size: 100Gi
class: rocketmq-storage
deleteClaim: false
metricsConfig:
type: jmxPrometheusExporter
valueFrom:
configMapKeyRef:
name: kafka-metrics
key: kafka-metrics-config.yml
zookeeper:
replicas: 3
resources:
requests:
memory: 3Gi
cpu: 1000m
limits:
memory: 3Gi
cpu: 1000m
jvmOptions:
-Xms: 2048m
-Xmx: 2048m
jmxOptions: {}
template:
pod:
affinity:
podAntiAffinity:
***
storage:
type: persistent-claim
size: 50Gi
class: rocketmq-storage
deleteClaim: false
metricsConfig:
type: jmxPrometheusExporter
valueFrom:
configMapKeyRef:
name: kafka-metrics
key: zookeeper-metrics-config.yml
***
***
apiVersion: v1
kind: Service
metadata:
labels:
strimzi.io/cluster: my-cluster
strimzi.io/name: my-cluster-kafka-jmx
name: my-cluster-kafka-jmx-0
spec:
ports:
- name: kafka-jmx-nodeport
port: 9999
protocol: TCP
targetPort: 9999
selector:
statefulset.kubernetes.io/pod-name: my-cluster-kafka-0
strimzi.io/cluster: my-cluster
strimzi.io/kind: Kafka
strimzi.io/name: my-cluster-kafka
type: NodePort
apiVersion: v1
kind: Service
metadata:
labels:
app: kafka-export-service
name: my-cluster-kafka-exporter-service
spec:
ports:
- port: 9404
protocol: TCP
targetPort: 9404
selector:
strimzi.io/cluster: my-cluster
strimzi.io/kind: Kafka
strimzi.io/name: my-cluster-kafka-exporter
type: ClusterIP
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kafka-prometheus
labels:
app: kafka-prometheus
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: kafka-prometheus
serviceName: kafka-prometheus
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app: kafka-prometheus
spec:
containers:
- args:
- '--query.max-concurrency=800'
- '--query.max-samples=800000000'
***
command:
- /bin/prometheus
image: 'repository.poizon.com/prometheus/prometheus:v2.28.1'
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 10
httpGet:
path: /status
port: web
scheme: HTTP
initialDelaySeconds: 300
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 3
name: kafka-prometheus
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 200m
memory: 128Mi
volumeMounts:
- mountPath: /etc/localtime
name: volume-localtime
- mountPath: /data/prometheus/
name: kafka-prometheus-config
- mountPath: /data/database/prometheus
name: kafka-prometheus-db
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
terminationGracePeriodSeconds: 30
restartPolicy: Always
schedulerName: default-scheduler
securityContext:
fsGroup: 0
volumes:
- hostPath:
path: /etc/localtime
type: ''
name: volume-localtime
- configMap:
defaultMode: 420
name: kafka-prometheus-config
name: kafka-prometheus-config
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: kafka-prometheus-db
spec:
accessModes:
- ReadWriteonce
resources:
requests:
storage: 20Gi
storageClassName: rocketmq-storage
volumeMode: Filesystem
status:
phase: Pending
总结
文/ZUOQI
关注得物技术,做最潮技术人



