2 回答
TA贡献1795条经验 获得超7个赞
您构建了dlv基于alpine- 的发行版。dlv可执行文件链接到libc.musl:
# ldd dlv
linux-vdso.so.1 (0x00007ffcd251d000)
libc.musl-x86_64.so.1 => not found
但是后来你切换到glibc基于图像debian:buster-slim。该图像没有所需的库。
# find / -name libc.musl*
<nothing found>
这就是您无法执行的原因dlv- 动态链接器无法找到正确的库。
您需要构建glibc基于 - 的 docker。例如,替换第一行
FROM golang:bullseye AS builder
顺便提一句。构建后,您需要以特权模式运行容器
$ docker build . -t try-dlv
...
$ docker run --privileged --rm try-dlv
API server listening at: [::]:40000
2022-10-30T10:51:02Z warning layer=rpc Listening for remote connections (connections are not authenticated nor encrypted)
在非特权容器中dlv不允许产生子进程。
$ docker run --rm try-dlv
API server listening at: [::]:40000
2022-10-30T10:55:46Z warning layer=rpc Listening for remote connections (connections are not authenticated nor encrypted)
could not launch process: fork/exec /app/fooapp: operation not permitted
真正最小的图像
你用来debian:buster-slim最小化图像,它的大小是 80 MB。但是如果你需要一个非常小的图像,使用busybox,它只有 4.86 MB 的开销。
FROM golang:bullseye AS builder
# Build Delve for debugging
RUN go install github.com/go-delve/delve/cmd/dlv@latest
# Create and change to the app directory.
WORKDIR /app
ENV CGO_ENABLED=0
# Retrieve application dependencies.
COPY go.* ./
RUN go mod download
# Copy local code to the container image.
COPY . ./
# Build the binary.
RUN go build -o fooapp .
# Download certificates
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
ca-certificates
# Use the official Debian slim image for a lean production container.
FROM busybox:glibc
EXPOSE 8000 40000
# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/fooapp /app/fooapp
# COPY --from=builder /app/ /app
COPY --from=builder /go/bin/dlv /dlv
COPY --from=builder /etc/ssl /etc/ssl
# Run dlv as pass fooapp as parameter
CMD ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/app/fooapp"]
# ENTRYPOINT ["/bin/sh"]
图像大小为 25 MB,其中 18 MB 来自应用程序dlv,2 MB 来自Hello World应用程序。
在选择图像时,应注意具有相同风格的libc. golang:bullseye针对glibc. 因此,最小图像必须glibc基于。
但是,如果您想要更舒适一些,请使用已安装的alpine软件包gcompat。与busybox.
FROM golang:bullseye AS builder
# Build Delve for debugging
RUN go install github.com/go-delve/delve/cmd/dlv@latest
# Create and change to the app directory.
WORKDIR /app
ENV CGO_ENABLED=0
# Copy local code to the container image.
COPY . ./
# Retrieve application dependencies.
RUN go mod tidy
# Build the binary.
RUN go build -o fooapp .
# Use alpine lean production container.
# FROM busybox:glibc
FROM alpine:latest
# gcompat is the package to glibc-based apps
# ca-certificates contains trusted TLS CA certs
# bash is just for the comfort, I hate /bin/sh
RUN apk add gcompat ca-certificates bash
EXPOSE 8000 40000
# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/fooapp /app/fooapp
# COPY --from=builder /app/ /app
COPY --from=builder /go/bin/dlv /dlv
# Run dlv as pass fooapp as parameter
CMD ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/app/fooapp"]
# ENTRYPOINT ["/bin/bash"]
TA贡献1836条经验 获得超13个赞
长话短说
运行apt-get install musl
,然后/dlv
应该按预期工作。
解释
按着这些次序:
docker run -it <image-name> sh
apt-get install file
file /dlv
然后你可以看到如下输出:
/dlv: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, Go BuildID=xV8RHgfpp-zlDlpElKQb/DOLzpvO_A6CJb7sj1Nxf/aCHlNjW4ruS1RXQUbuCC/JgrF83mgm55ntjRnBpHH, not stripped
令人困惑no such file or directory
(有关相关讨论,请参阅此问题)是由 missing 引起的/lib/ld-musl-x86_64.so.1
。
因此,解决方案是musl
按照其文档安装库。
我的回答是受这个答案的启发。
- 2 回答
- 0 关注
- 168 浏览
添加回答
举报