首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Dockerfile问题-为什么没有找到二进制dlv -没有这样的文件或目录

Dockerfile问题-为什么没有找到二进制dlv -没有这样的文件或目录
EN

Stack Overflow用户
提问于 2022-10-30 04:47:52
回答 3查看 100关注 1票数 3

我有个码头文件很好用。然而,为了远程调试它,我读到我需要在上面安装dlv,然后我需要运行dlv并传递我要调试的应用程序的参数。因此,在它上安装dlv并尝试运行它之后。我知道错误了

代码语言:javascript
运行
复制
exec /dlv: no such file or directory

这是码头文件

代码语言:javascript
运行
复制
    FROM golang:1.18-alpine 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 -gcflags="all=-N -l" -o fooapp

# Use the official Debian slim image for a lean production container.
FROM debian:buster-slim

EXPOSE 8000 40000

RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Copy the binary to the production image from the builder stage.
#COPY --from=builder /app/fooapp /app/fooapp #commented this out  

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"]

上述结果在exec /dlv: no such file or directory中的应用

我不知道为什么会这样。作为刚接触到docker的人,我尝试过不同的方法来调试它。我试着使用dive来检查和查看图片上是否有dlv在路径/dlv中,并且确实有。我还附上了一张照片。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-10-30 10:56:19

你在alpine-based发行版中建立了-based。dlv可执行文件是针对libc.musl链接的

代码语言:javascript
运行
复制
# ldd dlv 
        linux-vdso.so.1 (0x00007ffcd251d000)
        libc.musl-x86_64.so.1 => not found

但是,您切换到了glibc-based image debian:buster-slim。该映像没有所需的库。

代码语言:javascript
运行
复制
# find / -name libc.musl*                                        
<nothing found>

这就是为什么不能执行dlv的原因--动态链接器无法找到正确的库。

您需要在glibc-based码头构建。例如,替换第一行

代码语言:javascript
运行
复制
FROM golang:bullseye AS builder

顺便说一下。生成之后,需要以权限模式运行容器。

代码语言:javascript
运行
复制
$ 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生成子进程。

代码语言:javascript
运行
复制
$ 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.86MB。

代码语言:javascript
运行
复制
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应用程序。

在选择图像时,应该注意使用相同风格的libcgolang:bullseyeglibc的链接。因此,最小图像必须是glibc-based。

但是,如果您想要更舒适一点,请使用alpine并安装gcompat包。它是一个相当丰富的linux,与busybox相比,它有很多外部包,只需要额外的6MB。

代码语言:javascript
运行
复制
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"]
票数 1
EN

Stack Overflow用户

发布于 2022-10-30 08:26:45

TL;DR

运行apt-get install musl,那么/dlv将按预期工作。

解释

遵循以下步骤:

  1. docker run -it <image-name> sh
  2. apt-get install file
  3. file /dlv

然后您可以看到以下输出:

代码语言:javascript
运行
复制
/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 (有关讨论请参见这个问题 )是由缺少的/lib/ld-musl-x86_64.so.1造成的。

因此,解决方案是通过遵循musl来安装其文件库。

我的回答受到这个答案的启发。

票数 1
EN

Stack Overflow用户

发布于 2022-11-07 10:48:48

no such file or directory错误指示您的二进制文件不存在,或者您的二进制文件动态链接到不存在的库。

正如在这个回答中所说的,delve是与libc.musl相关联的。因此,对于您的深入构建,您可以禁用CGO,因为这可能导致libc/libmusl的动态链接:

代码语言:javascript
运行
复制
# Build Delve for debugging
RUN CGO_ENABLED=0 go install github.com/go-delve/delve/cmd/dlv@latest
...

这甚至允许您以后对最终目标映像使用划痕构建,并且不要求您安装任何附加包(如musl )或使用任何基于glibc的映像,并要求您以特权模式运行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74250570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档