我有一个 docker 档案,它工作得很好.然而,为了远程调试它,我读到我需要在上面安装dlv,然后我需要运行DLV并传递我试图调试的应用程序的参数.因此,在安装DLV并try 运行它之后.我明白错误所在

exec /dlv: no such file or directory

这是Docker文件

    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的新手,我try 了不同的方法来调试它.我try 使用dive判断并查看路径/dlv中的图像上是否有dlv,结果是这样的.我还附上了一张它的图片

enter image description here

推荐答案

您在基于alpine的发行版中构建了dlv个.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的对接器.例如,替换第一行

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

Really Minimal Image

你用debian:buster-slim来最小化图像,它的大小是80MB.但如果您需要really small映像,则使用busybox,其开销仅为4.86MB.

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

图像大小为25MB,其中18MB来自dlv,2MB来自Hello Worldapply.

在 Select 图像时,应注意具有相同的libc种口味.golang:bullseye个链接对glibc个链接.因此,最小图像必须是基于glibc的.

但如果你想要更舒适一点,使用安装了gcompat包的alpine.它是一个相当丰富的Linux,有很多外部包,只需要额外的6MB,而不是busybox 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

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

Go相关问答推荐

Golang ==错误:OCI运行时创建失败:无法启动容器进程:exec:./" bin:stat./" bin:没有这样的文件或目录:未知

使用Digitorus/pdfsign在GO(Golang)中签署pdf文件

Go中的Slice[:1][0]与Slice[0]

如何配置vscode以在Go中显示不必要的(过度指定的)泛型?

为什么要立即调用内联函数,而不仅仅是调用其包含的函数?

如何使用 sync.WaitGroup 来执行所有的 goroutine?

使用 Go Colly 抓取所有可能的标签并将它们放入一个变量中

Neptune 在连接到启用 IAM 的 Neptune 实例时抛出握手错误错误

如何从 Go 中的 `HijackedResponse` 中删除 Cursor Position ANSI 转义码?

Go:如何在将 float64 转换为 float32 时判断精度损失

将值发送到 Channel 并在就绪时读取输出

Go Colly 如何找到请求的元素?

grpc-gateway:重定向与定义不匹配(原始文件)

从 Makefile 运行时权限被拒绝

如何使用struct的方法清除除某些字段之外的struct值

将shell输出绑定到Go中的 struct 的最佳方法?

切片到数组指针的转换

go mod tidy 错误消息:但是 go 1.16 会 Select

如何从应用程序调用谷歌云身份 API

如何迭代在泛型函数中传递的片的并集?