我想在Kubernetes配置Kafka经纪人。我使用的泊坞窗图片是confluentinc/cp-kafka:latest
。它需要KAFKA_ADVERTISED_LISTENERS
环境变量,允许Kafka客户端与代理进行通信。
问题是难以将服务端点IP分配给KAFKA_ADVERTISED_LISTENERS
。如果我使用localhost
作为此值,则它仅在本地Kafka代理窗格中工作,但它不适用于kubernetes群集中的某些Kafka客户端窗格以与其通信。如果我使用来自kubectl get endpoints -l app=kafka
的服务端点IP,这是有效的,但每次使用一些审计脚本设置此动态值的开销很小。
我想知道是否有更好的方法可以在Kubernetes yaml文件中动态设置此值,因此我不需要每次都以编程方式设置此IP。
这是yaml文件:
---
apiVersion: v1
kind: Service
metadata:
name: kafka-broker
labels:
app: kafka
spec:
type: NodePort
ports:
- port: 9092
targetPort: 9092
selector:
app: kafka
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kafka-broker
spec:
replicas: 1
selector:
matchLabels:
app: kafka
template:
metadata:
labels:
app: kafka
spec:
hostname: broker
containers:
- name: kafka
image: confluentinc/cp-kafka:latest
ports:
- containerPort: 9092
env:
- name: KAFKA_ADVERTISED_LISTENERS
value: "PLAINTEXT://DYNAMIC_ENDPOINT_IP:9092"
- name: KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR
value: "1"
- name: KAFKA_ZOOKEEPER_CONNECT
value: zoo1:2181
提前致谢。
编辑:我尝试使用服务器名称,服务主机环境变量,服务源IP和Pod IP。不幸的是,我仍然在kafka日志中得到错误:
java.lang.IllegalArgumentException: Error creating broker listeners from 'PLAINTEXT://$KAFKA_BROKER_SERVICE_HOST:9092': Unable to parse PLAINTEXT://$KAFKA_BROKER_SERVICE_HOST:9092 to a broker endpoint
如果我使用的是kubectl exec -it kafa-broker-ssfjks env
,那么这个环境变量实际上已在此pod中正确设置。我想这可能与Kafka代理配置问题有关?
答案 0 :(得分:1)
您应该让您的客户端通过该服务连接,因此暴露服务的ip或dns应该有效。默认情况下,服务在pod中作为变量名称公开。如果配置了dns插件,则可以使用dns。更多信息:https://kubernetes.io/docs/concepts/services-networking/service/#environment-variables
答案 1 :(得分:0)
使用服务名称(kafka-broker)代替其IP。 Kube-dns将为您解决。如果kafka客户端放在同一个命名空间,你应该只使用" kafka-broker"如果没有,你必须使用限定名称" kafka-broker.YOURNAMESPACE.svc"
答案 2 :(得分:0)
@Jakub让我步入正轨,因此对于cp-kafka-connect这样的东西,我的Dockerfile看起来像:
FROM confluentinc/cp-kafka-connect:5.4.0
ENV CONNECT_GROUP_ID='kafkatosql'
ENV CONNECT_CONFIG_STORAGE_TOPIC="kafkatosql-config"
ENV CONNECT_OFFSET_STORAGE_TOPIC="kafkatosql-offsets"
ENV CONNECT_STATUS_STORAGE_TOPIC="kafkatosql-status"
ENV CONNECT_KEY_CONVERTER="io.confluent.connect.avro.AvroConverter"
ENV CONNECT_VALUE_CONVERTER="io.confluent.connect.avro.AvroConverter"
ENV CONNECT_LOG4J_ROOT_LOGLEVEL="ERROR"
ENV CONNECT_PLUGIN_PATH="/usr/share/java,/usr/share/confluent-hub-components"
RUN confluent-hub install --no-prompt confluentinc/kafka-connect-jdbc:5.4.0
WORKDIR /app
COPY start.sh .
CMD exec ./start.sh
然后start.sh看起来像:
kafka_connect_host=localhost:8083
export CONNECT_REST_ADVERTISED_HOST_NAME=$(hostname -I)
/etc/confluent/docker/run &
wait_counter=0
echo "Waiting for Kafka Connect to start listening on kafka-connect ⏳"
while true; do
status=$(curl -s -o /dev/null -w %{http_code} http://$kafka_connect_host/connectors)
if [ $status -eq 000 ]; then
wait_counter=$((wait_counter+1))
echo "Kafka Connect listener HTTP status: $status (waiting for 200)"
if [ $wait_counter = 15 ]; then
echo 'Waited too long!';
exit 1;
else
echo "Retries: $wait_counter"
sleep 3
fi
else
break
fi
done
echo -e "\n--\n+> Creating Kafka Connect Postgresql Sink"
curl -X PUT http://$kafka_connect_host/connectors/jdbc_sink_postgresql_00/config -H "Content-Type: application/json" -d '{
"connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
"tasks.max": 1,
"topics": "users",
"connection.url": "jdbc:'"$DB_URL"'",
"auto.create": false
}'
# ... other stuff
trap : TERM INT; sleep infinity & wait