Нет такого хоста, где я подключаюсь к брокеру kafka на сервере через переадресацию портов - PullRequest
0 голосов
/ 05 марта 2020

У меня следующая проблема: у меня запущен экземпляр брокера kafka на сервере в k8s. У этого брокера у меня есть порт, перенаправленный на localhost kubectl port-forward kafka-broker-0 9104.

Я уверен, что это работает, потому что я пробую это из моего приложения python, но если я попробую пример в go от целых rnet

package main

import (
    "fmt"
    "os"
    "os/signal"

    kingpin "gopkg.in/alecthomas/kingpin.v2"

    "github.com/Shopify/sarama"
)

var (
    brokerList        = kingpin.Flag("brokerList", "List of brokers to connect").Default("localhost:9104").Strings()
    topic             = kingpin.Flag("topic", "Topic name").Default("important").String()
    partition         = kingpin.Flag("partition", "Partition number").Default("0").String()
    offsetType        = kingpin.Flag("offsetType", "Offset Type (OffsetNewest | OffsetOldest)").Default("-1").Int()
    messageCountStart = kingpin.Flag("messageCountStart", "Message counter start from:").Int()
)

func main() {
    kingpin.Parse()
    config := sarama.NewConfig()
    config.Consumer.Return.Errors = true
    brokers := *brokerList
    master, err := sarama.NewConsumer(brokers, config)
    if err != nil {
        panic(err)
    }
    defer func() {
        if err := master.Close(); err != nil {
            panic(err)
        }
    }()
    consumer, err := master.ConsumePartition(*topic, 0, sarama.OffsetOldest)
    if err != nil {
        panic(err)
    }
    signals := make(chan os.Signal, 1)
    signal.Notify(signals, os.Interrupt)
    doneCh := make(chan struct{})
    go func() {
        for {
            select {
            case err := <-consumer.Errors():
                fmt.Println(err)
            case msg := <-consumer.Messages():
                *messageCountStart++
                fmt.Println("Received messages", string(msg.Key), string(msg.Value))
            case <-signals:
                fmt.Println("Interrupt is detected")
                doneCh <- struct{}{}
            }
        }
    }()
    <-doneCh
    fmt.Println("Processed", *messageCountStart, "messages")
}

у меня ошибка

panic: dial tcp: lookup host.docker.internal: no such host

goroutine 1 [running]:
main.main()
    /Users/anonymous/go/src/pr1/kafka-consumer.go:37 +0x33b
exit status 2

пожалуйста, где может быть проблема?

1 Ответ

1 голос
/ 05 марта 2020

Довольно просто, ваш процесс не может разрешить имя хоста host.docker.internal.

Go Программа, запущенная в модуле на k8s

Предполагается, что ваша программа Go работает в контейнера в кластере Kubernetes, вам нужно принять несколько мер, как описано ниже.

Если вы используете Kubernetes, должна быть служба, которая экспортирует Kubernetes в остальную часть вашего кластера, обычно под ip кластера и hostname <servicename>.<namespace>.<clusterdomain>.

Ниже вы можете увидеть, как подойти к этому:

$ kubectl --namespace=mynamespace get svc
NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)              AGE
centraldb-cockroachdb          ClusterIP   None             <none>        26257/TCP,8080/TCP   21d
centraldb-cockroachdb-public   ClusterIP   10.110.105.151   <none>        26257/TCP,8080/TCP   21d

$ kubectl get --namespace=mynamespace service centraldb-cockroachdb-public -o json | jq ".spec"
{
  "clusterIP": "10.110.105.151",
  "ports": [
    {
      "name": "grpc",
      "port": 26257,
      "protocol": "TCP",
      "targetPort": "grpc"
    },
    {
      "name": "http",
      "port": 8080,
      "protocol": "TCP",
      "targetPort": "http"
    }
  ],
  "selector": {
    "app.kubernetes.io/component": "cockroachdb",
    "app.kubernetes.io/instance": "centraldb",
    "app.kubernetes.io/name": "cockroachdb"
  },
  "sessionAffinity": "None",
  "type": "ClusterIP"
}

Как вы видите, я запускаю cockroachdb и его публичный c grp c порт доступен через 10.110.105.151:26257, а его http-порт доступен через 10.110.105.151:8080.

Теперь, как нам узнать наше DNS-имя?

Мы развернем маленького помощника в том же пространстве имен.

Сначала мы создаем файл yaml bb.yaml

apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - image: busybox:latest
    command:
      - sleep
      - &quot;7200&quot;
    name: busybox
  restartPolicy: Always

Затем мы применяем его к тому же пространству имен , что и сервис, который мы хотим чтобы получить DNS-имя для:

$ kubectl --namespace=mynamespace apply -f bb.yaml 
pod/busybox created

Теперь мы можем найти полное DNS-имя вашей службы через:

$ kubectl exec --namespace=mynamespace busybox -- nslookup centraldb-cockroachdb-public
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      centraldb-cockroachdb-public
Address 1: 10.110.105.151 centraldb-cockroachdb-public.mynamespace.svc.cluster.local

(обратите внимание, что IP-платья и DNS-имена, очевидно, могут различаться в вашей установке).

Итак, мы должны быть в состоянии достичь Сеть CockroachDB через "centraldb-cockroachdb-publi c .mynamespace.sv c .cluster.local: 8080" из кластера .

Go программа, работающая вне k8s

Что делать здесь сильно зависит от вашей установки. Если вы используете Docker для рабочего стола, как я полагаю, самый простой способ - раскрыть рассматриваемое развертывание:

$ kubectl port-forward svc/$yourServiceName $localport:$serviceport

Это сделает http-порт службы "centraldb-cockroachdb-publi c "доступно через localhost: 9000:

$ kubectl port-forward --namespace=mynamespace svc/centraldb-cockroachdb-public 9000:8080
Forwarding from 127.0.0.1:9000 -> 8080
Forwarding from [::1]:9000 -> 8080

Теперь мы открываем другую оболочку и вызываем http://localhost: 9000 :

$ curl -sI  http://localhost:9000
HTTP/1.1 307 Temporary Redirect
Content-Type: text/html; charset=utf-8
Location: https://localhost:9000/
Date: Thu, 05 Mar 2020 12:17:09 GMT

Чтобы сделать это постоянный, вам нужно либо изменить тип службы на NodePort , либо использовать то, что Kubernetes называет «LoadBalancer» .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...