K8S部署Kafka
部署nfs请参考:https://www.cnblogs.com/llds/p/17198194.html
部署zookeeper请参考:https://www.cnblogs.com/llds/p/17198487.html
一、集群部署Kafka
Kafka部署在以下节点上
[root@k8s-master nfs-client]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 17d v1.20.0
k8s-node1 Ready <none> 16d v1.20.0
k8s-node2 Ready <none> 16d v1.20.0
二、部署svc
1、部署 Service Headless,用于zookeeper间相互通信
1)、.yaml文件
点击查看代码
apiVersion: v1
kind: Service
metadata:
name: kafka-headless
namespace: middleware
labels:
app: kafka
spec:
type: ClusterIP
clusterIP: None # 创建无头服务,如果需要对外暴露端口可自行创建service
ports:
- name: kafka
port: 9092
targetPort: kafka
selector:
app: kafka
2)、应用.yaml文件
kubectl apply -f kafka-svc-headless.yaml
1、部署 Service,用于外部访问 Zookeeper
1)、.yaml文件
点击查看代码
[root@k8s-master svc]# vim kafka-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kafka-svc
namespace: middleware
labels:
app: kafka
spec:
type: ClusterIP
ports:
- name: kafka
port: 9092
targetPort: kafka
selector:
app: kafka
2)、应用.yaml文件
kubectl apply -f kafka-svc.yaml
三、部署StatefulSet
1、.yaml 文件
点击查看代码
[root@k8s-master conf]# cat kafka.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kafka-test
namespace: middleware
labels:
app: kafka
spec:
selector:
matchLabels:
app: kafka
serviceName: kafka-headless
podManagementPolicy: "Parallel"
replicas: 3
updateStrategy:
type: "RollingUpdate"
template:
metadata:
name: "kafka"
labels:
app: kafka
spec:
securityContext:
fsGroup: 1001
runAsUser: 1001
affinity:
podAntiAffinity: # Pod反亲和性
preferredDuringSchedulingIgnoredDuringExecution: # 软策略,使Pod分布在不同的节点上
- weight: 1 # 权重,有多个策略通过权重控制调度
podAffinityTerm:
topologyKey: app.kubernetes.io/name # 通过app.kubernetes.io/name作为域调度
labelSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values:
- zookeeper
containers:
- name: kafka
image: "docker.io/bitnami/kafka:2.3.0-debian-9-r4"
imagePullPolicy: "IfNotPresent"
env:
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KAFKA_CFG_ZOOKEEPER_CONNECT
value: "zk-headless" # Zookeeper Service 名称
- name: KAFKA_PORT_NUMBER
value: "9092"
- name: KAFKA_CFG_LISTENERS
value: "PLAINTEXT://:$(KAFKA_PORT_NUMBER)"
- name: KAFKA_CFG_ADVERTISED_LISTENERS
value: 'PLAINTEXT://$(MY_POD_NAME).kafka-headless:$(KAFKA_PORT_NUMBER)'
- name: ALLOW_PLAINTEXT_LISTENER
value: "yes"
- name: KAFKA_HEAP_OPTS
value: "-Xmx512m -Xms512m"
- name: KAFKA_CFG_LOGS_DIRS
value: /opt/bitnami/kafka/data
- name: JMX_PORT
value: "9988"
ports:
- name: kafka
containerPort: 9092
livenessProbe:
tcpSocket:
port: kafka
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 2
readinessProbe:
tcpSocket:
port: kafka
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 6
volumeMounts:
- name: data
mountPath: /bitnami/kafka
volumeClaimTemplates:
- metadata:
name: data
spec:
storageClassName: kafka-nfs-storage # 指定为上面创建的 storageclass
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
2)、应用.yaml文件
kubectl apply -f kafka.yaml
四、部署kafka-manager
1、.yaml 文件
点击查看代码
[root@k8s-master conf]# cat kafka-manager.yaml
apiVersion: v1
kind: Service
metadata:
name: kafka-manager
namespace: middleware
labels:
app: kafka-manager
spec:
type: NodePort
ports:
- name: kafka
port: 9000
targetPort: 9000
nodePort: 30900
selector:
app: kafka-manager
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kafka-manager
namespace: middleware
labels:
app: kafka-manager
spec:
replicas: 1
selector:
matchLabels:
app: kafka-manager
template:
metadata:
labels:
app: kafka-manager
spec:
containers:
- name: kafka-manager
image: zenko/kafka-manager:1.3.3.22
imagePullPolicy: IfNotPresent
ports:
- name: kafka-manager
containerPort: 9000
protocol: TCP
env:
- name: ZK_HOSTS
value: "zk-service:2181"
livenessProbe:
httpGet:
path: /api/health
port: kafka-manager
readinessProbe:
httpGet:
path: /api/health
port: kafka-manager
2)、应用.yaml文件
kubectl apply -f kafka-manager.yaml
五、Kafka配置外部通信
1、配置svc 开放外部访问端口 这里使用nodePort的方式
点击查看代码
[root@k8s-master conf]# cat svc/external/kafka-external-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: kafka
name: kafka-external-svc-0
namespace: middleware
spec:
ports:
- name: server
nodePort: 31090
port: 9092
protocol: TCP
targetPort: 9092
selector:
statefulset.kubernetes.io/pod-name: kafka-test-0
sessionAffinity: None
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
labels:
app: kafka
name: kafka-external-svc-1
namespace: middleware
spec:
ports:
- name: server
nodePort: 31091
port: 9092
protocol: TCP
targetPort: 9092
selector:
statefulset.kubernetes.io/pod-name: kafka-test-1
sessionAffinity: None
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
labels:
app: kafka
name: kafka-external-svc-2
namespace: middleware
spec:
ports:
- name: server
nodePort: 31092
port: 9092
protocol: TCP
targetPort: 9092
selector:
statefulset.kubernetes.io/pod-name: kafka-test-2
sessionAffinity: None
type: NodePort
2、配置Kafka advertised.listener属性
修改Kafka StatefulSet yaml 文件
- 删除KAFKA_CFG_ADVERTISED_LISTENERS 属性
- 新增command 命令 以动态配置 KAFKA_CFG_ADVERTISED_LISTENERS 属性
修改后yaml 文件 如下:
点击查看代码
[root@k8s-master conf]# cat kafka-external.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kafka-test
namespace: middleware
labels:
app: kafka
spec:
selector:
matchLabels:
app: kafka
serviceName: kafka-headless
podManagementPolicy: "Parallel"
replicas: 3
updateStrategy:
type: "RollingUpdate"
template:
metadata:
name: "kafka"
labels:
app: kafka
spec:
securityContext:
fsGroup: 1001
runAsUser: 1001
affinity:
podAntiAffinity: # Pod反亲和性
preferredDuringSchedulingIgnoredDuringExecution: # 软策略,使Pod分布在不同的节点上
- weight: 1 # 权重,有多个策略通过权重控制调度
podAffinityTerm:
topologyKey: app.kubernetes.io/name # 通过app.kubernetes.io/name作为域调度
labelSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values:
- zookeeper
containers:
- name: kafka
command:
- bash
- -ec
- |
HOSTNAME=`hostname -s`
if [[ $HOSTNAME =~ (.*)-([0-9]+)$ ]]; then
ORD=${BASH_REMATCH[2]}
PORT=$((ORD + 31090))
export KAFKA_CFG_ADVERTISED_LISTENERS="PLAINTEXT://172.171.2.148:$PORT"
else
echo "Failed to get index from hostname $HOST"
exit 1
fi
exec /entrypoint.sh /run.sh
image: "docker.io/bitnami/kafka:2.3.0-debian-9-r4"
imagePullPolicy: "IfNotPresent"
env:
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KAFKA_CFG_ZOOKEEPER_CONNECT
value: "zk-headless" # Zookeeper Service 名称
- name: KAFKA_PORT_NUMBER
value: "9092"
- name: KAFKA_CFG_LISTENERS
value: "PLAINTEXT://:$(KAFKA_PORT_NUMBER)"
- name: ALLOW_PLAINTEXT_LISTENER
value: "yes"
- name: KAFKA_HEAP_OPTS
value: "-Xmx512m -Xms512m"
- name: KAFKA_CFG_LOGS_DIRS
value: /opt/bitnami/kafka/data
- name: JMX_PORT
value: "9988"
ports:
- name: kafka
containerPort: 9092
livenessProbe:
tcpSocket:
port: kafka
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 2
readinessProbe:
tcpSocket:
port: kafka
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 6
volumeMounts:
- name: data
mountPath: /bitnami/kafka
volumeClaimTemplates:
- metadata:
name: data
spec:
storageClassName: kafka-nfs-storage # 指定为上面创建的 storageclass
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 1Gi
参考文献:
https://www.cnblogs.com/hsyw/p/16753968.html
https://www.cnblogs.com/shareHistory/p/15843422.html
https://www.jianshu.com/p/50a9d38ada27
https://blog.csdn.net/qq_34777982/article/details/126520962
https://zhuanlan.zhihu.com/p/497943409