我有一個運行良好的 docker 檔案。但是要遠程除錯它,我讀到我需要安裝dlv它,然后我需要運行 dlv 并傳遞我要除錯的應用程式的引數。因此,在其上安裝 dlv 并嘗試運行它之后。我得到錯誤
exec /dlv: no such file or directory
這是泊塢窗檔案
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,并且確實如此。我還附上了它的圖片

uj5u.com熱心網友回復:
您內置基于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軟體包。它是一個相當豐富的 linux,與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"]
uj5u.com熱心網友回復:
TL;博士
運行apt-get install musl,然后/dlv應該按預期作業。
解釋
按著這些次序:
docker run -it <image-name> shapt-get install filefile /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(有關相關討論,請參閱此問題)是由于缺少/lib/ld-musl-x86_64.so.1.
因此,解決方案是按照其檔案musl安裝庫。
我的回答受到了這個答案的啟發。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/524140.html
上一篇:有沒有辦法在“dockerstop[container]”和dockerstart[container]之后關閉docker提供的輸出?
下一篇:如何正確地將環境變數發送到影像?
