当前位置: 首页 > 知识库问答 >
问题:

在kubernetes集群之外访问bitnami/kafka

苗森
2023-03-14

我目前正在使用bitnami/kafka image(https://hub.docker.com/r/bitnami/kafka)并将其部署在kubernetes上。

  • kubernetes大师:1
  • 库伯内特斯工人:3人

在群集中,其他应用程序能够找到 kafka。尝试从群集外部访问 kafka 容器时出现问题。在阅读时,我读到我们需要为外部 kafka 客户端设置属性“广告.监听器=纯文本://主机名:port_number”。

我目前正在引用“https://github.com/bitnami/charts/tree/master/bitnami/kafka”。在我的values.yaml文件中,我添加

价值观. yaml

    < li >广告收听者1: 10.21.0.191

还有statefulset.yaml

    - name: KAFKA_CFG_ADVERTISED_LISTENERS
      value: 'PLAINTEXT://{{ .Values.advertisedListeners }}:9092' 

对于单个kafka实例,它运行良好。

但是对于3节点kafka集群,我更改了一些配置,如下所示

  • 广告听众1: 10.21.0.191
  • 广告主持人2: 10.21.0.192
  • 广告听众3: 10.21.0.193

还有Statefulset.yaml

    - name: KAFKA_CFG_ADVERTISED_LISTENERS
      {{- if $MY_POD_NAME := "kafka-0" }}
      value: 'PLAINTEXT://{{ .Values.advertisedListeners1 }}:9092'
      {{- else if $MY_POD_NAME := "kafka-1" }}
      value: 'PLAINTEXT://{{ .Values.advertisedListeners2 }}:9092'
      {{- else if $MY_POD_NAME := "kafka-2" }}
      value: 'PLAINTEXT://{{ .Values.advertisedListeners3 }}:9092'
      {{- end }}

预期结果是,所有 3 个 kafka 实例都应将播发 .listener 属性设置为工作线程节点 IP 地址。

例:

> Kafka-0 -

Kafka-1 -

Kafka-3--

目前只有一个kafka pod处于启动和运行状态,另外两个将进入crashloopbackoff状态。

而其他两个 pod 的错误显示为:

[2019-10-20 13:09:37,753]信息 [LogDirFailureHandler]: 正在启动 (kafka.server.ReplicaManager$LogDirFailureHandler) [2019-10-20 13:09:37,786] 错误 [Kafka服务器 id=1002] Kafka服务器启动期间出现致命错误。准备关闭 (kafka.server.KafkaServer) java.lang.非法描述异常:要求失败:在播发的侦听器中配置的endpoint 10.21.0.191:9092 已由代理 1001 在 scala 注册。Predef$.require(Predef.scala:224) at kafka.server.kafkaServer$$anonfun$createBrokerInfo(可调整大小的阵列:399) at kafka.server.kafkaServer$$anonfun$createBrokerInfo$2.apply(KafkaServer.scala:397) at scala.collection.mutable.ResizableArray$class.foreach(可调整大小的数组:59) 在 scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.exeach(ArrayBuffer.scala:48) at kafka.server.kafkaServer.createBrokerInfo(KafkaServer.scala:397) at kafka.server.kafkaServer.startup(KafkaServer.scala:261) at kafka.server.kafkaServerStartable.startup(KafkaServerStartable.scala:38) at kafka.Kafka在Kafka。Kafka主(Kafka斯卡拉)

这意味着在statefulset中应用的逻辑。yaml不工作了。有人能帮我解决这个问题吗。。?

任何帮助将不胜感激。

kubectl get statefulset kafka -o yaml 的输出

apiVersion: apps/v1
kind: StatefulSet
metadata:
  creationTimestamp: "2019-10-29T07:04:12Z"
  generation: 1
  labels:
    app.kubernetes.io/component: kafka
    app.kubernetes.io/instance: kafka
    app.kubernetes.io/managed-by: Tiller
    app.kubernetes.io/name: kafka
    helm.sh/chart: kafka-6.0.1
  name: kafka
  namespace: default
  resourceVersion: "12189730"
  selfLink: /apis/apps/v1/namespaces/default/statefulsets/kafka
  uid: d40cfd5f-46a6-49d0-a9d3-e3a851356063
spec:
  podManagementPolicy: Parallel
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/component: kafka
      app.kubernetes.io/instance: kafka
      app.kubernetes.io/name: kafka
  serviceName: kafka-headless
  template:
    metadata:
      creationTimestamp: null
      labels:
        app.kubernetes.io/component: kafka
        app.kubernetes.io/instance: kafka
        app.kubernetes.io/managed-by: Tiller
        app.kubernetes.io/name: kafka
        helm.sh/chart: kafka-6.0.1
      name: kafka
    spec:
      containers:
      - env:
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: KAFKA_CFG_ZOOKEEPER_CONNECT
          value: kafka-zookeeper
        - name: KAFKA_PORT_NUMBER
          value: "9092"
        - name: KAFKA_CFG_LISTENERS
          value: PLAINTEXT://:$(KAFKA_PORT_NUMBER)
        - name: KAFKA_CFG_ADVERTISED_LISTENERS
          value: PLAINTEXT://10.21.0.191:9092
        - name: ALLOW_PLAINTEXT_LISTENER
          value: "yes"
        - name: KAFKA_CFG_BROKER_ID
          value: "-1"
        - name: KAFKA_CFG_DELETE_TOPIC_ENABLE
          value: "false"
        - name: KAFKA_HEAP_OPTS
          value: -Xmx1024m -Xms1024m
        - name: KAFKA_CFG_LOG_FLUSH_INTERVAL_MESSAGES
          value: "10000"
        - name: KAFKA_CFG_LOG_FLUSH_INTERVAL_MS
          value: "1000"
        - name: KAFKA_CFG_LOG_RETENTION_BYTES
          value: "1073741824"
        - name: KAFKA_CFG_LOG_RETENTION_CHECK_INTERVALS_MS
          value: "300000"
        - name: KAFKA_CFG_LOG_RETENTION_HOURS
          value: "168"
        - name: KAFKA_CFG_LOG_MESSAGE_FORMAT_VERSION
        - name: KAFKA_CFG_MESSAGE_MAX_BYTES
          value: "1000012"
        - name: KAFKA_CFG_LOG_SEGMENT_BYTES
          value: "1073741824"
        - name: KAFKA_CFG_LOG_DIRS
          value: /bitnami/kafka/data
        - name: KAFKA_CFG_DEFAULT_REPLICATION_FACTOR
          value: "1"
        - name: KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR
          value: "1"
        - name: KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR
          value: "1"
        - name: KAFKA_CFG_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM
          value: https
        - name: KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR
          value: "1"
        - name: KAFKA_CFG_NUM_IO_THREADS
          value: "8"
        - name: KAFKA_CFG_NUM_NETWORK_THREADS
          value: "3"
        - name: KAFKA_CFG_NUM_PARTITIONS
          value: "1"
        - name: KAFKA_CFG_NUM_RECOVERY_THREADS_PER_DATA_DIR
          value: "1"
        - name: KAFKA_CFG_SOCKET_RECEIVE_BUFFER_BYTES
          value: "102400"
        - name: KAFKA_CFG_SOCKET_REQUEST_MAX_BYTES
          value: "104857600"
        - name: KAFKA_CFG_SOCKET_SEND_BUFFER_BYTES
          value: "102400"
        - name: KAFKA_CFG_ZOOKEEPER_CONNECTION_TIMEOUT_MS
          value: "6000"
        image: docker.io/bitnami/kafka:2.3.0-debian-9-r88
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 2
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: kafka
          timeoutSeconds: 5
        name: kafka
        ports:
        - containerPort: 9092
          name: kafka
          protocol: TCP
        readinessProbe:
          failureThreshold: 6
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: kafka
          timeoutSeconds: 5
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /bitnami/kafka
          name: data
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        fsGroup: 1001
        runAsUser: 1001
      terminationGracePeriodSeconds: 30
  updateStrategy:
    type: RollingUpdate
  volumeClaimTemplates:
  - metadata:
      creationTimestamp: null
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 8Gi
      volumeMode: Filesystem
    status:
      phase: Pending
status:
  collisionCount: 0
  currentReplicas: 3
  currentRevision: kafka-56ff499d74
  observedGeneration: 1
  readyReplicas: 1
  replicas: 3
  updateRevision: kafka-56ff499d74
  updatedReplicas: 3

共有2个答案

卫鸿朗
2023-03-14

我认为舵手图表不会将您的外部(到 kubernetes)网络列入白名单,以供广告听众使用。我通过像这样重新配置头盔值.yaml解决了类似的问题。在我的情况下,127.0.0.1网络是mac,你的网络可能会有所不同:

externalAccess:
  enabled: true
  autoDiscovery:
    enabled: false
    image:
      registry: docker.io
      repository: bitnami/kubectl
      tag: 1.23.4-debian-10-r17
      pullPolicy: IfNotPresent
      pullSecrets: []
    resources:
      limits: {}
      requests: {}
  service:
    type: NodePort
    port: 9094
    loadBalancerIPs: []
    loadBalancerSourceRanges: []
    nodePorts:
      - 30000
      - 30001
      - 30002
    useHostIPs: false
    annotations: {}
    domain: 127.0.0.1
宰父衡
2023-03-14

我发现您在为一个状态集中的不同pod传递不同的环境变量时遇到了一些麻烦。

您正在尝试使用头盔模板来实现这一点:

- name: KAFKA_CFG_ADVERTISED_LISTENERS
  {{- if $MY_POD_NAME := "kafka-0" }}
  value: 'PLAINTEXT://{{ .Values.advertisedListeners1 }}:9092'
  {{- else if $MY_POD_NAME := "kafka-1" }}
  value: 'PLAINTEXT://{{ .Values.advertisedListeners2 }}:9092'
  {{- else if $MY_POD_NAME := "kafka-2" }}
  value: 'PLAINTEXT://{{ .Values.advertisedListeners3 }}:9092'
  {{- end }}

在头盔模板指南文档中,您可以找到以下说明:

在Helm模板中,变量是对另一个对象的命名引用。它遵循$name形式。变量使用特殊的赋值操作符::=分配。

现在让我们看看你的代码:

{{- if $MY_POD_NAME := "kafka-0" }}

这是变量赋值,而不是比较,在此赋值之后,if语句将此表达式计算为true,这就是为什么在您的staefulsetyaml清单中您将其视为输出:

- name: KAFKA_CFG_ADVERTISED_LISTENERS
    value: PLAINTEXT://10.21.0.191:9092

要使其按预期工作,不应使用舵机模板。这是行不通的。

一种方法是为每个kafka节点创建单独的环境变量,并将所有这些变量传递给所有pod,如下所示:

- env:
  - name: MY_POD_NAME
    valueFrom:
      fieldRef:
        apiVersion: v1
        fieldPath: metadata.name
  - name: KAFKA_0
      value: 10.21.0.191
  - name: KAFKA_1
      value: 10.21.0.192
  - name: KAFKA_2
      value: 10.21.0.193
#  - name: KAFKA_CFG_ADVERTISED_LISTENERS
#      value: PLAINTEXT://$MY_POD_NAME:9092

并使用修改后的启动脚本创建您自己的 docker 映像,该脚本将导出KAFKA_CFG_ADVERTISED_LISTENERS变量,并根据MY_POD_NAME具有适当的值。

如果你不想创建自己的映像,你可以创建一个ConfigMap与修改entrypoint.sh和挂载它在旧的entrypoint.sh的地方(你也可以使用任何其他文件,只是看看这里如何kafka映像构建的更多信息)。

安装ConfigMap如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
    - name: test-container
      image: docker.io/bitnami/kafka:2.3.0-debian-9-r88
      volumeMounts:
      - name: config-volume
        mountPath: /entrypoint.sh
        subPath: entrypoint.sh
  volumes:
    - name: config-volume
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: kafka-entrypoint-config
        defaultMode: 0744 # remember to add proper (executable) permissions

apiVersion: v1
kind: ConfigMap
metadata:
  name: kafka-entrypoint-config
  namespace: default
data:
  entrypoint.sh: |
    #!/bin/bash
    # Here add modified entrypoint script

请让我知道它是否有帮助。

 类似资料:
  • 根据用户部署和暴露服务的方式不同,有很多种方式可以用来访问 kubernetes 集群。 最简单也是最直接的方式是使用 kubectl 命令。 其次可以使用 kubeconfig 文件来认证授权访问 API server。 通过各种 proxy 经过端口转发访问 kubernetes 集群中的服务 使用 Ingress,在集群外访问 kubernetes 集群内的 service

  • 在 Kubernetes 集群内访问 TiDB 时,使用 TiDB service 域名 ${cluster_name}-tidb.${namespace} 即可。 若需要在集群外访问,则需将 TiDB 服务端口暴露出去。在 TidbCluster CR 中,通过 spec.tidb.service 字段进行配置: spec: ... tidb: service: ty

  • 我有几个问题。1)我们能不能在k8集群之外以上述方式访问k8集群之外的Kafka?如果是这样,我在某种程度上做错了吗?2)如果端口是打开的,那不是意味着代理是可用的吗? 如有任何帮助,不胜感激。谢谢

  • 第一次使用 kubectl 访问 如果您是第一次访问 Kubernetes API 的话,我们建议您使用 Kubernetes 命令行工具:kubectl。 为了访问集群,您需要知道集群的地址,并且需要有访问它的凭证。通常,如果您完成了入门指南那么这些将会自动设置,或者其他人为您部署的集群提供并给您凭证和集群地址。 使用下面的命令检查 kubectl 已知的集群的地址和凭证: $ kubectl

  • 我试图在CentOS上使用kubernetes创建redis集群。我的kubernetes主服务器运行在一台主机上,而kubernetes从服务器运行在两台不同的主机上。 kubectl create-f RC.Yaml 使用的Redis-config文件 我使用以下命令创建kubernetes服务。 ./redis-trib.rb创建-副本1 172.30.79.2:6379 172.30.79

  • 当我执行时 kubectl代理 它为我提供了o/p:开始在虚拟机上的127.0.0.1:8001上提供服务 我想在主机上看到仪表板,这给我带来了问题。 192 168 113 8001 api命名空间库贝系统服务https kubernetes仪表板代理 有什么问题,我没明白。我是库伯内特斯的新手。谢谢