I'm trying to create a static binary on Alpine, but can't figure out how to solve the problem of a missing sasl2 library.
Here's a list of packages that I install on Alpine:
libressl2.6-libcrypto
libressl2.6-libssl
python
git
bash
openssh
openssl
lz4-dev
libsasl
yajl-dev
zlib-dev
cyrus-sasl-dev
openssl-dev
libevent
build-base
coreutils
I also built librdkafka from source using HEAD (the build output showed support for sasl was found, and enabled).
go build -tags static main.go works as expected:
ldd main
/lib/ld-musl-x86_64.so.1 (0x7f1fd3370000)
libsasl2.so.3 => /usr/lib/libsasl2.so.3 (0x7f1fd3157000)
libssl.so.1.0.0 => /lib/libssl.so.1.0.0 (0x7f1fd2eee000)
liblz4.so.1 => /usr/lib/liblz4.so.1 (0x7f1fd2cdb000)
libcrypto.so.1.0.0 => /lib/libcrypto.so.1.0.0 (0x7f1fd28bb000)
libz.so.1 => /lib/libz.so.1 (0x7f1fd26a4000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f1fd3370000)
You can see the pointer to /usr/lib/libsasl2.so.3.
But go build -tags static_all main.go won't work:
go build -tags static_all main.go
# github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka
/usr/lib/gcc/x86_64-alpine-linux-musl/6.4.0/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lsasl2
collect2: error: ld returned 1 exit status
Here's the full
go build -x -tags static_all main.go output
WORK=/tmp/go-build967075363
mkdir -p $WORK/b115/
cd /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka
pkg-config --cflags --static -- rdkafka
pkg-config --libs --static -- rdkafka
CGO_LDFLAGS='"-g" "-O2" "-static" "-L/usr/local/lib" "-lrdkafka" "-L/lib" "-lsasl2" "-lssl" "-llz4" "-lcrypto" "-L/lib" "-lz" "-ldl" "-lpthread" "-lrt"' /usr/local/go/pkg/tool/linux_amd64/cgo -objdir $WORK/b115/ -importpath github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -- -I/usr/local/include -I $WORK/b115/ -g -O2 ./00version.go ./build_static_all.go ./config.go ./consumer.go ./error.go ./event.go ./generated_errors.go ./handle.go ./header.go ./kafka.go ./message.go ./metadata.go ./misc.go ./offset.go ./producer.go ./testhelpers.go
cd $WORK
gcc -fno-caret-diagnostics -c -x c - || true
gcc -Qunused-arguments -c -x c - || true
gcc -fdebug-prefix-map=a=b -c -x c - || true
gcc -gno-record-gcc-switches -c -x c - || true
cd $WORK/b115
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x001.o -c _cgo_export.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x002.o -c 00version.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x003.o -c build_static_all.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x004.o -c config.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x005.o -c consumer.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x006.o -c error.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x007.o -c event.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x008.o -c generated_errors.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x009.o -c handle.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x010.o -c header.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x011.o -c kafka.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x012.o -c message.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x013.o -c metadata.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x014.o -c misc.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x015.o -c offset.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x016.o -c producer.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_x017.o -c testhelpers.cgo2.c
gcc -I /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -I/usr/local/include -I ./ -g -O2 -o ./_cgo_main.o -c _cgo_main.c
cd /go/src/github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka
gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b115=/tmp/go-build -gno-record-gcc-switches -o $WORK/b115/_cgo_.o $WORK/b115/_cgo_main.o $WORK/b115/_x001.o $WORK/b115/_x002.o $WORK/b115/_x003.o $WORK/b115/_x004.o $WORK/b115/_x005.o $WORK/b115/_x006.o $WORK/b115/_x007.o $WORK/b115/_x008.o $WORK/b115/_x009.o $WORK/b115/_x010.o $WORK/b115/_x011.o $WORK/b115/_x012.o $WORK/b115/_x013.o $WORK/b115/_x014.o $WORK/b115/_x015.o $WORK/b115/_x016.o $WORK/b115/_x017.o -g -O2 -static -L/usr/local/lib -lrdkafka -L/lib -lsasl2 -lssl -llz4 -lcrypto -L/lib -lz -ldl -lpthread -lrt
# github.com/blendle/stream-processor-file-importer/vendor/github.com/confluentinc/confluent-kafka-go/kafka
/usr/lib/gcc/x86_64-alpine-linux-musl/6.4.0/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lsasl2
collect2: error: ld returned 1 exit status
And here's the output of
find / -name *sasl*
/run/saslauthd
/usr/lib/libgsasl.so
/usr/lib/libgsasl.a
/usr/lib/libgsasl.so.7
/usr/lib/sasl2
/usr/lib/sasl2/libsasldb.so.3
/usr/lib/sasl2/libsasldb.so
/usr/lib/sasl2/libsasldb.so.3.0.0
/usr/lib/pkgconfig/libsasl2.pc
/usr/lib/pkgconfig/libgsasl.pc
/usr/lib/libgsasl.so.7.9.6
/usr/lib/libsasl2.so.3.0.0
/usr/lib/libsasl2.so
/usr/lib/libsasl2.so.3
/usr/sbin/sasldblistusers2
/usr/sbin/testsaslauthd
/usr/sbin/saslauthd
/usr/sbin/saslpasswd2
/usr/include/c++/6.4.0/javax/security/sasl
/usr/include/c++/6.4.0/gnu/javax/crypto/sasl
/usr/include/sasl
/usr/include/sasl/saslplug.h
/usr/include/sasl/saslutil.h
/usr/include/sasl/sasl.h
/usr/include/gsasl-mech.h
/usr/include/gsasl-compat.h
/usr/include/gsasl.h
/etc/init.d/saslauthd
Two questions:
Maybe alpine does not provided static builds of libsdasl2?
If you can find a package that does you might also need to link the Go application with some additional linker flags, see here:
https://stackoverflow.com/a/26095605/1821055
As for disabling libsasl support when building librdkafka, there is a bug that prevents --disable-sasl to disable it, which will be fixed after the next release.
In the meantime you can edit librdkafka/configure.librdkafka to fail the libsasl2 lib_check.
Well, sorry for jumping the gun on this issue. I've actually managed to solve the second question by sifting through the librdkafka repository, and using ./configure --disable-sasl to disable SASL support.
After that the build went fine, and it looks like the binary is now statically linked:
ldd ./main
ldd: ./main: Not a valid dynamic program
The problem obviously still remains, but it's less of an issue for me right now. I'll see if I can get it to work with SASL support on Alpine and report back when I do, until then, I'll close this issue.
edit: was posting while you responded @edenhill, thank you for the pointers, appreciated 👍.
This is useful for many people, would you mind blogging a small tutorial or outlining it here?
I can at least put the Dockerfile here that made this work for me, with the commands on how to use it:
# First build phase (of two), this part uses Alpine to install all required
# dependencies required to build a project that requires librdkafka. It will
# then build a static binary that can be used in a smaller "scratch" image.
FROM golang:1.10-alpine
# The default librdkafka version is the latest stable release on GitHub. You can
# use the `--build-arg` argument for `docker build` to specify a different
# version to be installed.
#
# e.g.: docker build --build-arg LIBRDKAFKA_VERSION=4e7a46701ecce7297b2298885da980be7856e5f9
#
ARG LIBRDKAFKA_VERSION=v0.11.3
# Set the workdir to the full GOPATH of your project.
WORKDIR $GOPATH/src/PATH/TO/PROJECT
# Install all dependencies required to build the project as a static binary.
RUN apk add -U \
bash \
build-base \
coreutils \
curl \
cyrus-sasl-dev \
git \
libevent \
libressl2.6-libcrypto \
libressl2.6-libssl \
libsasl \
lz4-dev \
openssh \
openssl \
openssl-dev \
python \
yajl-dev \
zlib-dev
# Install `dep`, the official Golang package manager to install dependencies.
RUN apk add -U -X http://nl.alpinelinux.org/alpine/edge/testing dep
# SASL support is disabled for now, due to issues when compiling a static
# binary. See: https://git.io/vAFFm
RUN cd $(mktemp -d) \
&& curl -sL "https://github.com/edenhill/librdkafka/archive/$LIBRDKAFKA_VERSION.tar.gz" | \
tar -xz --strip-components=1 -f - \
&& ./configure --disable-sasl \
&& make -j \
&& make install
# Copy the entire project tree into the container, so we can build the binary.
COPY . .
# Install any defined project dependencies using `dep`.
RUN dep ensure -vendor-only
# Build a completely static binary, able to be used in a `scratch` container.
RUN go build -o /tmp/run -tags static_all
# Second build phase, copy the generated binary from the first build phase into
# a "scratch" image, and set the entrypoint to run the binary.
FROM scratch
ENTRYPOINT ["/run"]
COPY --from=0 /tmp/run .
I then build the image as follows:
$ docker build \
--build-arg LIBRDKAFKA_VERSION=4e7a46701ecce7297b2298885da980be7856e5f9 \
--tag static-test .
It succeeds, and I can see the relatively small container size as a result:
$ docker images | grep static-test
static-test, latest, 8cd387b3607e, About a minute ago, 33.4MB
And finally, I can run it as expected:
$ docker run static-test
hello world!
https://pkgs.alpinelinux.org/package/v3.7/main/x86_64/cyrus-sasl-dev
It would appear it doesn't bundle the static version as noted previously. My problem is I do need SASL in librdkafka.
I tried building cyrus-sasl-dev to get my own static library built but then I run into all manner of conflicts between libressl and openssl. I still haven't resolved the issue :(
[edit] Docker multi-step builds appeared to sort me. I defined a build step just for the Cyrus SASL library (as a static build) and on the next step used COPY --from=previous-step the libsasl2.a (and all the plugin .a files) into the correct place. Seems to work but was a faff to say the least.
libsasl2 is tricky with all its dynamic library plugins, I have not yet been able to create proper static builds with libsasl2.
With docker you don't really need static builds since you can include whatever dynamic libraries dependencies you have.
FYI, Alpine now provides a static library for libsasl2.
cyrus-sasl-dev indeed includes the statically linked libraries.
```/ # find / | grep sasl.*a$
/usr/lib/sasl2/libplain.a
/usr/lib/sasl2/libanonymous.a
/usr/lib/sasl2/libscram.a
/usr/lib/sasl2/libdigestmd5.a
/usr/lib/sasl2/libsasldb.a
/usr/lib/sasl2/libgssapiv2.a
/usr/lib/sasl2/libntlm.a
/usr/lib/sasl2/libgs2.a
/usr/lib/sasl2/libcrammd5.a
/usr/lib/sasl2/liblogin.a
/usr/lib/libsasl2.a
and while `-tags static` build completes, static_all build still fails. @edenhill
```/go/src/package # go build -ldflags "-L/usr/lib/sasl2/" -tags static_all .
# package/vendor/github.com/confluentinc/confluent-kafka-go/kafka
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): warning: relocation against `GSS_C_NT_USER_NAME' in read-only section '.text'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(db_berkeley.o): in function 'berkeleydb_open':
db_berkeley.c:(.text+0x9d): undefined reference to `db_create'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: db_berkeley.c:(.text+0x10f): undefined reference to 'db_strerror'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(db_berkeley.o): in function 'berkeleydb_close.isra.0':
db_berkeley.c:(.text+0x193): undefined reference to 'db_strerror'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(db_berkeley.o): in function '_sasldb_getdata':
db_berkeley.c:(.text+0x35a): undefined reference to 'db_strerror'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(db_berkeley.o): in function `_sasldb_putdata':
db_berkeley.c:(.text+0x5ee): undefined reference to `db_strerror'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: db_berkeley.c:(.text+0x646): undefined reference to `db_strerror'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `sasl_gss_free_context_contents':
gssapi.c:(.text+0x61): undefined reference to `gss_delete_sec_context'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x93): undefined reference to `gss_release_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0xb0): undefined reference to `gss_release_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0xcd): undefined reference to `gss_release_cred'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0xea): undefined reference to `gss_release_cred'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `sasl_gss_seterror_':
gssapi.c:(.text+0x32f): undefined reference to `gss_display_status'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x3c0): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x448): undefined reference to `gss_display_status'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x4f1): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `sasl_gss_encode':
gssapi.c:(.text+0x682): undefined reference to `gss_wrap'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x6dd): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x747): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x821): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `gssapi_decode_packet':
gssapi.c:(.text+0x964): undefined reference to `gss_unwrap'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x9c8): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0xa40): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0xaab): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `gssapi_get_ssf':
gssapi.c:(.text+0xb38): undefined reference to `gss_inquire_sec_context_by_oid'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0xb71): undefined reference to `gss_release_buffer_set'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0xbaf): undefined reference to `gss_release_buffer_set'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `gssapi_wrap_sizes.isra.3':
gssapi.c:(.text+0xda9): undefined reference to `gss_wrap_size_limit'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `gssapi_client_mech_step':
gssapi.c:(.text+0x10b1): undefined reference to `GSS_C_NT_HOSTBASED_SERVICE'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x10c4): undefined reference to `gss_import_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x11cd): undefined reference to `gss_init_sec_context'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x135f): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x13af): undefined reference to `gss_inquire_context'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x141c): undefined reference to `gss_display_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1485): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1521): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1602): undefined reference to `gss_unwrap'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1687): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1831): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x19a0): undefined reference to `gss_wrap'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1a9f): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1b22): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1b92): undefined reference to `gss_delete_sec_context'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `gssapi_server_mech_step':
gssapi.c:(.text+0x1de1): undefined reference to `GSS_C_NT_HOSTBASED_SERVICE'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1df2): undefined reference to `gss_import_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1e70): undefined reference to `gss_release_cred'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1ec3): undefined reference to `gss_acquire_cred'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1f75): undefined reference to `gss_accept_sec_context'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x1ffe): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x206e): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x20ec): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x21c6): undefined reference to `gss_canonicalize_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2259): undefined reference to `gss_display_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2357): undefined reference to `GSS_C_NT_USER_NAME'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x236c): undefined reference to `gss_import_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x23e7): undefined reference to `gss_compare_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x24cf): undefined reference to `gss_release_cred'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2500): undefined reference to `gss_release_cred'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2553): undefined reference to `gss_release_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x258d): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x25e2): undefined reference to `gss_release_name'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x27bb): undefined reference to `gss_wrap'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2881): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2906): undefined reference to `gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2999): undefined reference to 'gss_unwrap'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2a65): undefined reference to 'gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2b25): undefined reference to 'gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: gssapi.c:(.text+0x2bc1): undefined reference to 'gss_release_buffer'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../lib/libsasl2.a(gssapi.o): in function `gssapiv2_server_plug_init':
gssapi.c:(.text+0x2dd2): undefined reference to 'krb5_gss_register_acceptor_identity'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: read-only segment has dynamic relocations
collect2: error: ld returned 1 exit status
/go/src/package #
i got the same result with a stretch image, as well as alpine.
any help is appreciated.
I don't think there is a current solution to linking libsasl2 statically, it depends on runtime loaded plugins which require dynamic linking. (Yes, it is a mess from our perspective)
yeah i figured it was something like that. thanks for the confirmation!
The plugins are being compiled into the static libsasl2. The problem is that some plugins depend on libraries (e.g. Berkeley db, Kerberos 5) that are not available as static libraries in Alpine. If you don't need those plugins, then you can compile the SASL library statically without them, then compile librdkafka, then compile your Go program.
I only have need for SCRAM support in SASL, so this worked for me to create an imagine that can then be used to compile the Go program:
FROM golang:1.12.0-alpine3.9
RUN apk add --no-cache \
bash \
build-base \
coreutils \
gcc \
git \
make \
musl-dev \
openssl-dev \
rpm \
lz4-dev \
zlib-dev \
wget && \
#
# Build Cyrus SASL from source.
cd $(mktemp -d) && \
wget -nv -O cyrus-sasl-2.1.27.tar.gz https://github.com/cyrusimap/cyrus-sasl/releases/download/cyrus-sasl-2.1.27/cyrus-sasl-2.1.27.tar.gz && \
tar -xz --strip-components=1 -f cyrus-sasl-2.1.27.tar.gz && \
rm -f cyrus-sasl-2.1.27.tar.gz && \
./configure --prefix=/usr --disable-sample --disable-obsolete_cram_attr --disable-obsolete_digest_attr --enable-static --disable-shared \
--disable-checkapop --disable-cram --disable-digest --enable-scram --disable-otp --disable-gssapi --with-dblib=none --with-pic && \
make && \
make install && \
#
# Build librdkafka from source.
cd $(mktemp -d) && \
wget -nv -O v0.11.6.tar.gz https://github.com/edenhill/librdkafka/archive/v0.11.6.tar.gz && \
tar -xz --strip-components=1 -f v0.11.6.tar.gz && \
rm -f v0.11.6.tar.gz && \
./configure --prefix=/usr --enable-sasl && \
make -j && \
make install
After that you can use go build -tags static_all . to build your program.
Thanks for the instructions @eliaslevy !
As for SCRAM support; you don't need libsasl2 at all for that, librdkafka has its own SCRAM implementation that only relies on OpenSSL.
Doh! 🤦♂️ I was not aware of that. Oh well, duly noted.
Do we have any updates on getting librdkafka to work with gssapi (kerberos authentication) inside alpine?
@PanagiotisFytas It should work as long as librdkafka (and libsasl2) are linked dynamically and not statically.
I have an issue with the kerberos authentication of the librdkafka from an alpine docker. Thought that it was an issue with the libraries, maybe I am wrong though. I should start another thread on librdkafka
Most helpful comment
I can at least put the
Dockerfilehere that made this work for me, with the commands on how to use it:I then build the image as follows:
It succeeds, and I can see the relatively small container size as a result:
And finally, I can run it as expected: