Невозможно запустить протокол gRPC в альпийском Dotnet SDK - PullRequest
1 голос
/ 12 марта 2019

См. Эту проблему github: https://github.com/grpc/grpc/issues/18338

См. Этот репозиторий: https://github.com/slolife/alpine-protoc

Если я включу пакет Nuget Grpc.Tools 1.19.0 впроект, который добавляет шаг сборки <Protobuf Include="Test.proto" />

Это прекрасно работает, если я создаю образ докера для сборки и использую microsoft/dotnet:2.2-sdk в качестве образа сборки.Однако, если я попытаюсь использовать образ сборки microsoft/dotnet:2.2-sdk-alpine на основе альпийского языка, сборка завершится неудачно со следующим сообщением об ошибке:

/root/.nuget/packages/grpc.tools/1.19.0/build/_protobuf/Google.Protobuf.Tools.targets(263,5): error MSB6003: The specified task executable "/root/.nuget/packages/grpc.tools/1.19.0/tools/linux_x64/protoc" could not be run. No such file or directory [/src/alpine-protoc.csproj]

Я подтвердил, что файл protoc находится врасположение, на которое жалуется сообщение об ошибке.

Я попытался запустить apk add libc6-compat и перезапустить сборку.На этот раз я получил следующую ошибку:

/root/.nuget/packages/grpc.tools/1.19.0/build/_protobuf/Google.Protobuf.Tools.targets(263,5): error MSB6006 : "/root/.nuget/packages/grpc.tools/1.19.0/tools/linux_x64/protoc" exited with code 139. [/src/alpine-proto c.csproj]


Обновление: вывод из ldd protoc

~/.nuget/packages/grpc.tools/1.19.0/tools/linux_x64 # ldd protoc
/lib64/ld-linux-x86-64.so.2 (0x7f60935a7000)
libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f60935a7000)
libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f60935a7000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f60935a7000)

1 Ответ

1 голос
/ 13 марта 2019

Это похоже на проблему совместимости с libc - я думаю, что dotnet тянет за собой материк, glibc-совместимый protoc вместе с grpc.

Ошибка No such file or directory на Alpine.при запуске исполняемого файла, который присутствует и доступен, типично для ld не удается разрешить зависимые библиотеки, такие как libc.so.6.

Из вывода ldd protoc мы можем видеть, что protoc требует libc.so.6, поэтомувероятно был построен на Linux с glibc, такой как Ubuntu или Debian.Пакет libc6-compat обеспечивает уровень совместимости поверх musl libc, чтобы обеспечить базовую функциональность glibc, например, добавление необходимых файлов библиотеки и отсутствующих функций.Однако он не обеспечивает полной совместимости с glibc.Сложные приложения, зависящие от glibc, вряд ли будут работать "из коробки", когда связаны с musl libc, по крайней мере, без каких-либо усилий по переносу.

Когда вы добавили libc6-compat, protoc смог соединиться сбиблиотеки совместимости musl-glibc, libc.so.6 и др., но при запуске завершается с кодом 139, что означает, что он вышел из строя (получил SIGSEGV).Это хороший признак того, что вы должны использовать его с настоящим glibc.Одной из возможных причин этого является размер стека по умолчанию: musl libc создает потоки с очень маленьким размером стека по умолчанию, около 68 КБ, тогда как потоки glibc создаются со стеками 2-8 МБ.Для других тонких различий, обратитесь к: https://wiki.musl -libc.org / functions-отличию от-glibc.html .

Вы можете попробовать обойти несовместимость пакетов nuget, используя простойвзломать: установить Alpine-совместимый компилятор protobuf , с apk add protobuf;затем замените ваш protoc символической ссылкой на /usr/bin/protoc.

В качестве альтернативы, вы можете попробовать установить правильный glibc на Alpine, добавив следующее в ваш Dockerfile (благодаря sgerrand и Анапсикс ):

ENV GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc
ENV GLIBC_VERSION=2.28-r0

RUN set -ex && \
    apk --update add libstdc++ curl ca-certificates && \
    for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
        do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
    apk add --allow-untrusted /tmp/*.apk && \
    rm -v /tmp/*.apk && \
    /usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib
...