即使在 PATH 中也找不到 Docker Alpine 可执行二进制文件

2024-10-14 08:40:00
admin
原创
80
摘要:问题描述:我有一个高山运行容器,其中包含一些二进制文件usr/local/bin当我得到这个输出ls的内容时:usr/local/bin/usr/local/bin # ls dwg2SVG dwg2dxf dwgadd dwgbmp dwgfilter dwggrep...

问题描述:

我有一个高山运行容器,其中包含一些二进制文件usr/local/bin

当我得到这个输出ls的内容时:usr/local/bin

/usr/local/bin # ls
dwg2SVG     dwg2dxf     dwgadd      dwgbmp      dwgfilter   dwggrep     dwglayers   dwgread     dwgrewrite  dwgwrite    dxf2dwg     dxfwrite

这正是我所期望的。但是,如果我通过调用它来执行其中一个二进制文件,则会收到not found来自 shell 的错误:

/usr/local/bin # dwg2dxf
sh: dwgread: not found
/usr/local/bin # ./dwg2dxf
sh: ./dwgread: not found

我测试了我的$PATH,这似乎是正确的:

/usr/local/bin # echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

我怎样才能使这些二进制文件可调用或“可找到”?我在 Dockerfile 构建中遗漏了什么吗?我猜想ldconfigalpine 中的命令出了问题,但我不确定。

编辑

正如这里的一个答案所建议的那样,我执行了命令file,这里是输出:

/usr/local/bin # file dwg2dxf
dwgread: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=7835d4a42651a5fb7bdfa2bd8a76e40096bacb07, with debug_info, not stripped

这些二进制文件来自LibreDWG 官方存储库以及我的 Dockerfile 的第一部分。这是完整的 Dockerfile:

# podman/docker build -t libredwg .
############################
# STEP 1 build package from latest tar.xz
############################

FROM python:3.7.7-buster AS extracting
# libxml2-dev is broken so we need to compile it by our own
ARG LIBXML2VER=2.9.9
RUN apt-get update && \n    apt-get install -y --no-install-recommends autoconf libtool swig texinfo \n            build-essential gcc libxml2 python3-libxml2 libpcre2-dev libpcre2-32-0 curl \n            libperl-dev libxml2-dev && \n    mkdir libxmlInstall && cd libxmlInstall && \n    wget ftp://xmlsoft.org/libxml2/libxml2-$LIBXML2VER.tar.gz && \n    tar xf libxml2-$LIBXML2VER.tar.gz && \n    cd libxml2-$LIBXML2VER/ && \n    ./configure && \n    make && \n    make install && \n    cd /libxmlInstall && \n    rm -rf gg libxml2-$LIBXML2VER.tar.gz libxml2-$LIBXML2VER
WORKDIR /app
RUN tarxz=`curl --silent 'https://ftp.gnu.org/gnu/libredwg/?C=M;O=D' | grep '.tar.xz<' | \n         head -n1|sed -E 's/.*href="([^"]+)".*//'`; \n    echo "latest release $tarxz"; \n    curl --silent --output "$tarxz" https://ftp.gnu.org/gnu/libredwg/$tarxz && \n    mkdir libredwg && \n    tar -C libredwg --xz --strip-components 1 -xf "$tarxz" && \n    rm "$tarxz" && \n    cd libredwg && \n    ./configure --disable-bindings --enable-release && \n    make -j `nproc` && \n    mkdir install && \n    make install DESTDIR="$PWD/install" && \n    make check DOCKER=1 DESTDIR="$PWD/install"

############################
# STEP 2 install into stable-slim
############################

# pull official base image
FROM osgeo/gdal:alpine-normal-latest

# set work directory
WORKDIR /usr/src/app



# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# copy requirements file
COPY ./requirements.txt /usr/src/app/requirements.txt

# install dependencies
RUN set -eux \n    && apk add --no-cache --virtual .build-deps build-base \n        py3-pip libressl-dev libffi-dev gcc musl-dev python3-dev postgresql-dev\n    && pip3 install --upgrade pip setuptools wheel \n    && pip3 install -r /usr/src/app/requirements.txt \n    && rm -rf /root/.cache/pip

# Install libredwg binaries
COPY --from=extracting /app/libredwg/install/usr/local/bin/* /usr/local/bin/
COPY --from=extracting /app/libredwg/install/usr/local/include/* /usr/local/include/
COPY --from=extracting /app/libredwg/install/usr/local/lib/* /usr/local/lib/
COPY --from=extracting /app/libredwg/install/usr/local/share/* /usr/local/share/
RUN ldconfig /usr/local/bin/
RUN ldconfig /usr/local/include/
RUN ldconfig /usr/local/lib/
RUN ldconfig /usr/local/share/

# copy project
COPY . /usr/src/app/

解决方案 1:

在 Alpine Linux 上,此not found错误是动态链接失败的典型症状。这确实是 muslldd链接器的一个相当令人困惑的错误。

世界上大多数 Linux 软件都与glibc (GNU libc 库)相链接(libc 提供标准 C 库和 POSIX API)。大多数 Linux 发行版都基于 glibc。另一方面,Alpine Linux 基于musl libc 库,这是一个最小实现,严格符合 POSIX 标准。基于 glibc 发行版构建的可执行文件依赖于/lib/x86_64-linux-gnu/libc.so.6,例如,这在 Alpine 上不可用(除非它们是静态链接的)。

除了这种依赖性之外,值得注意的是,虽然 musl 试图在某种程度上保持 glibc 兼容性,但它远未完全兼容,并且针对 glibc 构建的复杂软件无法与 musl-libc 一起使用,因此简单地符号链接/lib/ld-musl-x86_64.so.1到 glibc 路径可能不会起作用。

一般来说,在 Alpine 上运行 glibc 二进制文件有几种方法:

  1. 安装一个 glibc 兼容包,libc6-compat或gcompat:

# apk add gcompat
apk add libc6-compat

这两个软件包都提供了一个轻量级的 glibc 兼容层,可能适合运行简单的 glibc 应用程序。
libc6-compat实现了 glibc 兼容性 API,并提供了指向 glibc 共享库(如libm.solibpthread.so和)的符号链接libcrypt.so。该gcompat软件包基于 Adelie Linux gcompat 项目,并执行相同的操作,但只提供了一个库libgcompat.so。这两个库都安装了加载器存根。根据应用程序的不同,其中一个可能有效,而另一个则无效,因此最好两个都试一下。

  1. 在 Alpine 上安装适当的 glibc,以提供所有 glibc 方法和功能。Alpine 有可用的 glibc 版本,应按照以下步骤安装(示例):

# Source: https://github.com/anapsix/docker-alpine-java

ENV GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc
ENV GLIBC_VERSION=2.30-r0

RUN set -ex && \n    apk --update add libstdc++ curl ca-certificates && \n    for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \n        do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \n    apk add --allow-untrusted /tmp/*.apk && \n    rm -v /tmp/*.apk && \n    /usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib
  1. 使用静态链接的可执行文件。静态可执行文件不带有动态依赖关系,可以在任何 Linux 上运行。

  2. 或者,也可以在 Alpine 上从源代码构建该软件。

对于 LibreDWG,我们首先验证一下这个问题:

/usr/local/bin # ./dwg2dxf
/bin/sh: ./dwg2dxf: not found
/usr/local/bin
/usr/local/bin # ldd ./dwg2dxf
    /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
    libredwg.so.0 => /usr/local/lib/libredwg.so.0 (0x7fd3744db000)
    libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
Error relocating /usr/local/lib/libredwg.so.0: __strcat_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __snprintf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __memcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __stpcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __strcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __printf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __fprintf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __strncat_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __sprintf_chk: symbol not found
Error relocating ./dwg2dxf: __snprintf_chk: symbol not found
Error relocating ./dwg2dxf: __printf_chk: symbol not found
Error relocating ./dwg2dxf: __fprintf_chk: symbol not found

您可以看到它dwg2dxf依赖于几个 glibc 符号。现在,让我们按照选项 2 安装 glibc:

/usr/src/app # cd /usr/local/bin
/usr/local/bin # ls
dwg2SVG     dwg2dxf     dwgadd      dwgbmp      dwgfilter   dwggrep     dwglayers   dwgread     dwgrewrite  dwgwrite    dxf2dwg     dxfwrite
/usr/local/bin # ./dwg2dxf
/bin/sh: ./dwg2dxf: not found
/usr/local/bin # export GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc && \n> export GLIBC_VERSION=2.30-r0 && \n> apk --update add libstdc++ curl ca-certificates && \n> for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \n>    do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \n> apk add --allow-untrusted /tmp/*.apk && \n> rm -v /tmp/*.apk && \n> /usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
(1/1) Installing curl (7.74.0-r1)
Executing busybox-1.32.1-r3.trigger
OK: 629 MiB in 126 packages
(1/2) Installing glibc (2.30-r0)
(2/2) Installing glibc-bin (2.30-r0)
Executing glibc-bin-2.30-r0.trigger
/usr/glibc-compat/sbin/ldconfig: /usr/local/lib/libredwg.so.0 is not a symbolic link
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link
OK: 640 MiB in 128 packages
removed '/tmp/glibc-2.30-r0.apk'
removed '/tmp/glibc-bin-2.30-r0.apk'
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link

/usr/glibc-compat/sbin/ldconfig: /usr/local/lib/libredwg.so.0 is not a symbolic link

瞧:

/usr/local/bin # ./dwg2dxf

Usage: dwg2dxf [-v[N]] [--as rNNNN] [-m|--minimal] [-b|--binary] DWGFILES...

解决方案 2:

尝试apk add gcompathttps://pkgs.alpinelinux.org/package/edge/community/x86/gcompat)。

gcompat提供/lib64/ld-linux-x86-64.so.2/lib/ld-linux-x86-64.so.2https://pkgs.alpinelinux.org/contents?file=ld-linux-x86-64.so.2)。

解决方案 3:

编辑 :

如需完整的解决方案,请参阅@valiano 的回应。

这是我在阅读@valiano 的回复之前找到的一个解决方法

解决方法

我通过切换到另一个基础映像(基于 Ubuntu)找到了一种解决方法这是新的工作Dockerfile:

# podman/docker build -t libredwg .
############################
# STEP 1 build package from latest tar.xz
############################

FROM python:3.7.7-buster AS extracting
# libxml2-dev is broken so we need to compile it by our own
ARG LIBXML2VER=2.9.9
RUN apt-get update && \n    apt-get install -y --no-install-recommends autoconf libtool swig texinfo \n            build-essential gcc libxml2 python3-libxml2 libpcre2-dev libpcre2-32-0 curl \n            libperl-dev libxml2-dev && \n    mkdir libxmlInstall && cd libxmlInstall && \n    wget ftp://xmlsoft.org/libxml2/libxml2-$LIBXML2VER.tar.gz && \n    tar xf libxml2-$LIBXML2VER.tar.gz && \n    cd libxml2-$LIBXML2VER/ && \n    ./configure && \n    make && \n    make install && \n    cd /libxmlInstall && \n    rm -rf gg libxml2-$LIBXML2VER.tar.gz libxml2-$LIBXML2VER
WORKDIR /app
RUN tarxz=`curl --silent 'https://ftp.gnu.org/gnu/libredwg/?C=M;O=D' | grep '.tar.xz<' | \n         head -n1|sed -E 's/.*href="([^"]+)".*//'`; \n    echo "latest release $tarxz"; \n    curl --silent --output "$tarxz" https://ftp.gnu.org/gnu/libredwg/$tarxz && \n    mkdir libredwg && \n    tar -C libredwg --xz --strip-components 1 -xf "$tarxz" && \n    rm "$tarxz" && \n    cd libredwg && \n    ./configure --disable-bindings --enable-release && \n    make -j `nproc` && \n    mkdir install && \n    make install DESTDIR="$PWD/install" && \n    make check DOCKER=1 DESTDIR="$PWD/install"

############################
# STEP 2 install into stable-slim
############################

# pull official base image
FROM osgeo/gdal:ubuntu-small-latest

# set work directory
WORKDIR /usr/src/app



# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# copy requirements file
COPY ./requirements.txt /usr/src/app/requirements.txt

# install dependencies
RUN set -eux \n    && apt-get update && apt-get install -y --no-install-recommends build-essential \n        libc6 python3-pip libffi-dev musl-dev gcc python3-dev postgresql-server-dev-all\n    && pip3 install --upgrade pip setuptools wheel \n    && pip3 install -r /usr/src/app/requirements.txt \n    && rm -rf /root/.cache/pip

# Install libredwg binaries
COPY --from=extracting /app/libredwg/install/usr/local/bin/* /usr/local/bin/
COPY --from=extracting /app/libredwg/install/usr/local/include/* /usr/local/include/
COPY --from=extracting /app/libredwg/install/usr/local/lib/* /usr/local/lib/
COPY --from=extracting /app/libredwg/install/usr/local/share/* /usr/local/share/
RUN ldconfig

# copy project
COPY . /usr/src/app/

基本上我只是改变了

FROM osgeo/gdal:alpine-normal-latest

FROM osgeo/gdal:ubuntu-small-latest

我已经更新了依赖项安装以及(从apk addalpine PM 切换到apt-get

对于我来说这不是一个理想的解决方案,因为使用基于 Alpine 的图像可以生成更轻量的容器,但它正在发挥作用,所以我将其发布为一种可能的解决方案。

@valiano 的回复是最佳解决方案。如果您关心轻量级图像,请参考它。

解决方案 4:

我是这样解决的:

rm /usr/glibc-compat/lib/ld-linux-x86-64.so.2
ln -s /usr/glibc-compat/sbin/ldconfig /usr/glibc-compat/lib/ld-linux-x86-64.so.2

编辑:解释:/usr/glibc-compat/sbin/ldconfig/usr/glibc-compat/lib/ld-linux-x86-64.so.2都是docker容器中的普通文件,所以我尝试了其中一个。

首先,我删除了/usr/glibc-compat/sbin/ldconfig它并将其设为符号链接。但我收到了错误,不记得是哪个了。接下来,我尝试删除它ld-linux-x86-64.so.2并将其设为符号链接。成功了。

解决方案 5:

它可能不是您在相关系统上可以使用的二进制格式。请检查您的体系结构和文件格式(例如使用命令file)。

编辑:/lib64/ld-linux-x86-64.so.2存在吗?你能运行它吗?

进一步编辑:这里的一般想法是,动态链接二进制文件可以被视为带有解释器的脚本。请参阅此LWN 文章以获取更多详细信息,以了解此处可能发生的情况。如果您的二进制文件适用于错误的平台,则需要新的二进制文件,或者您需要在正确的平台上运行它们。

您可以检查的另一件事是该二进制文件的输出是否与正常工作的二进制文件file的输出不同(例如)。file`/bin/ls`

解决方案 6:

现在我们可以用来docker compose替换docker-compose

对于 Alpine Linux,安装方式如下:

apk add docker-cli-compose

如果你仍然愿意docker-compose,你可以使用 a+x 在 /usr/local/bin/docker-compose 下保存一个文件:

#!/bin/sh
docker compose $@

然后您仍然可以运行使用 的旧脚本docker-compose

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用