如何将kubernetes服务端点IP传递给KAFKA广告的监听器

时间:2018-04-29 13:53:36

标签: apache-kafka kubernetes

我想在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代理配置问题有关?

3 个答案:

答案 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