Сборка докера завершается неудачно из-за неопределенной ошибки кафки

# #docker #go #apache-kafka #dockerfile #confluent-platform

Вопрос:

Когда я пытаюсь создать наше приложение go, мы получаем следующую ошибку.

 => ERROR [builder 7/7] RUN CGO_ENABLED=0 GOOS=linux go build -o myapp
 > [builder 7/7] RUN CGO_ENABLED=0 GOOS=linux go build -o myapp:
#14 6.962 # main
#14 6.962 ./kafkaproducer.go:12:12: undefined: kafka.NewProducer
#14 6.962 ./kafkaproducer.go:12:31: undefined: kafka.ConfigMap
#14 6.962 ./kafkaproducer.go:23:10: undefined: kafka.Message
#14 6.962 ./kafkaproducer.go:39:13: undefined: kafka.Message
 

Мой файл Docker находится

 FROM golang:1.16-alpine AS builder
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN go mod tidy
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp
FROM busybox AS prod
COPY --from=builder /app .
CMD ["./myapp"]
 

В моем файле KafkaProducer go я импортирую это

 import (
    "fmt"
    "log"

    "github.com/confluentinc/confluent-kafka-go/kafka"
)
 

Мое приложение успешно построено, когда я создаю его локально, но при сборке docker происходит сбой, так как не удается загрузить зависимость от кафки, и возникает неопределенная ошибка.
Пожалуйста, помогите мне решить эту проблему

Ответ №1:

Так что каким-то образом это, похоже, зависит от cgo при построении. Мне удалось обойти это, скомпилировав cgo, но связав зависимости. Статически.

 FROM golang AS builder

WORKDIR /app
COPY . .
RUN go mod download amp;amp; 
    go build -o myapp -ldflags '-linkmode external -w -extldflags "-static"'


# works also with alpine
FROM busybox 

COPY --from=builder /app/myapp myapp
CMD ["./myapp"]
 

Я использовал приведенный ниже код из их репозитория для тестирования. Что изначально дало мне ту ошибку, которую вы показали.

 package main

import (
    "fmt"

    "github.com/confluentinc/confluent-kafka-go/kafka"
)

func main() {

    p, err := kafka.NewProducer(amp;kafka.ConfigMap{"bootstrap.servers": "localhost"})
    if err != nil {
        panic(err)
    }

    defer p.Close()

    // Delivery report handler for produced messages
    go func() {
        for e := range p.Events() {
            switch ev := e.(type) {
            case *kafka.Message:
                if ev.TopicPartition.Error != nil {
                    fmt.Printf("Delivery failed: %vn", ev.TopicPartition)
                } else {
                    fmt.Printf("Delivered message to %vn", ev.TopicPartition)
                }
            }
        }
    }()

    // Produce messages to topic (asynchronously)
    topic := "myTopic"
    for _, word := range []string{"Welcome", "to", "the", "Confluent", "Kafka", "Golang", "client"} {
        p.Produce(amp;kafka.Message{
            TopicPartition: kafka.TopicPartition{Topic: amp;topic, Partition: kafka.PartitionAny},
            Value:          []byte(word),
        }, nil)
    }

    // Wait for message deliveries before shutting down
    p.Flush(15 * 1000)
}
 

Комментарии:

1. Привет , я использовал это в своем файле docker , ЗАПУСТИТЕ CGO_ENABLED=0 GOOS=linux, перейдите к сборке тегов musl-ldflags ‘- linkmode external-w-extldflags «- статический»- o myapp.go …. если я не использую CGO_ENABLED=0 или сохраняю его как CGO_ENABLED=1, неопределенная ошибка кафки исчезла, но затем появляется другая ошибка как standard_init_linux.go:228: пользовательский процесс exec вызван: нет такого файла или каталога, не мог пожалуйста, помогите мне это исправить

2. Поделитесь своим текущим файлом Dockerfile, потому что я не получаю никаких ошибок, поэтому я не могу воспроизвести вашу проблему и, следовательно, не могу вам помочь. Я бы посоветовал вам скопировать мой файл dockerfile 1to1 и использовать его. И опираться на go-alpine, похоже, не имеет особого смысла, поскольку у вас несколько этапов. Таким образом, изображение конструктора может быть громоздким, это не имеет значения.

3. Также поделитесь своим кодом, если есть что-то еще, что может вызвать проблему. Поскольку проблема кафки, похоже, решается этим.