【问题标题】:Cannot execute GO binary file in Docker Containers having Linux Runner无法在具有 Linux Runner 的 Docker 容器中执行 GO 二进制文件
【发布时间】:2020-09-10 05:30:30
【问题描述】:

Go 和二进制文件是我们的 docker 镜像的一部分。

我尝试了所有可能的组合来构建 Go 二进制文件

export GOARCH=386 && export GOOS=linux && go build ./cmd/status
export GOARCH=amd64 && export GOOS=windows && go build ./cmd/status

$ uname -a
 Linux runner-4KP_No95-project-35871-concurrent-0 44.44.444-115.233.amzn1.x86_64 #1 SMP Thu Feb 27 23:49:15 UTC 2020 x86_64 GNU/Linux

得到错误

/pipeline/status: /pipeline/status: cannot execute binary file

docker 文件中的示例部分是 -

ARG GOLANG_VERSION=1.14

FROM golang:${GOLANG_VERSION} as build-helpers

ENV GOPRIVATE=code.abcd.com

RUN mkdir -p /pipeline-helpers

ADD /reusable-aspects/ci-caching/golang-preheat-cache  /golang-preheat-cache
RUN cd /golang-preheat-cache && go mod download

ADD helpers/go-pipeline-commands /pipeline-helpers/
RUN cd /pipeline-helpers && CGO_ENABLED=0 GOOS=linux make

FROM alpine

RUN mkdir -p /pipeline
WORKDIR /pipeline
COPY --from=build-helpers /pipeline-helpers/commit .
COPY --from=build-helpers /pipeline-helpers/status .
RUN chmod a+x commit
RUN chmod a+x status

ENTRYPOINT ["./commit"]
CMD []

下面添加了构建 Go 二进制文件的图像日志

[0KRunning with gitlab-runner 11.11.2 (ac2a293c)
[0;m[0K  on aws-build-runner-scheduler 8616255e
[0;msection_start:1590231123:prepare_executor
[0K[0KUsing Docker executor with image gcr.io/kaniko-project/executor:debug ...
[0;m[0KPulling docker image gcr.io/kaniko-project/executor:debug ...
[0;m[0KUsing docker image sha256:adasdasdasdasdasdasdasdsa for gcr.io/kaniko-project/executor:debug ...
[0;msection_end:1590231124:prepare_executor
[0Ksection_start:1590231124:prepare_script
[0KRunning on runner-8616123e-project-12312-concurrent-0 via ip-12-122-122-122...
section_end:1590231125:prepare_script
[0Ksection_start:1590231125:get_sources
[0KReinitialized existing Git repository in /builds/abcde/pipeline/projetname/.git/
[32;1mFetching changes...[0;m
From https://code.abc.com/abcde/pipeline/projetname
 * [new ref]         refs/pipelines/5679048 -> refs/pipelines/5679048
   0286714..043832e  feat/qaPipelineDeploy  -> origin/feat/qaPipelineDeploy
[32;1mChecking out 043832ea as feat/qaPipelineDeploy...[0;m
Removing helpers/bash-commons/src/welcome/version-info-pipeline.txt

[32;1mSkipping Git submodules setup[0;m
section_end:1590231128:get_sources
[0Ksection_start:1590231128:restore_cache
[0Ksection_end:1590231130:restore_cache
[0Ksection_start:1590231130:download_artifacts
[0Ksection_end:1590231132:download_artifacts
[0Ksection_start:1590231132:build_script
[0K[32;1m$ mkdir -p /kaniko/.docker[0;m
[32;1m$ export IMAGE_TAG=${CI_COMMIT_TAG:=$CI_COMMIT_REF_SLUG}[0;m
[32;1m$ imagename=$CI_REGISTRY_IMAGE/helpers:$IMAGE_TAG[0;m
[36mINFO[0m[0001] Resolved base name golang:1.14 to build-helpers 
[36mINFO[0m[0001] Retrieving image manifest golang:1.14        
[36mINFO[0m[0002] Retrieving image manifest golang:1.14        
[36mINFO[0m[0003] Retrieving image manifest alpine             
[36mINFO[0m[0004] Retrieving image manifest alpine             
[36mINFO[0m[0005] Built cross stage deps: map[0:[/pipeline-helpers/commit /pipeline-helpers/status]] 
[36mINFO[0m[0005] Retrieving image manifest golang:1.14        
[36mINFO[0m[0005] Retrieving image manifest golang:1.14        
[36mINFO[0m[0006] Executing 0 build triggers                   
[36mINFO[0m[0006] Unpacking rootfs as cmd RUN mkdir -p /pipeline-helpers requires it. 
[36mINFO[0m[0021] ENV GOPRIVATE=code.abc.com               
[36mINFO[0m[0021] RUN mkdir -p /pipeline-helpers               
[36mINFO[0m[0021] Taking snapshot of full filesystem...        
[36mINFO[0m[0022] Resolving 28120 paths                        
[36mINFO[0m[0025] cmd: /bin/sh                                 
[36mINFO[0m[0025] args: [-c mkdir -p /pipeline-helpers]        
[36mINFO[0m[0025] Running: [/bin/sh -c mkdir -p /pipeline-helpers] 
[36mINFO[0m[0025] Taking snapshot of full filesystem...        
[36mINFO[0m[0025] Resolving 28121 paths                        
[36mINFO[0m[0027] Using files from context: [/builds/abcde/pipeline/projetname/projetname-reusable-aspects/ci-caching/golang-preheat-cache] 
[36mINFO[0m[0027] ADD /projetname-reusable-aspects/ci-caching/golang-preheat-cache  /golang-preheat-cache 
[36mINFO[0m[0027] Resolving 3 paths                            
[36mINFO[0m[0027] Taking snapshot of files...                  
[36mINFO[0m[0027] RUN cd /golang-preheat-cache && go mod download 
[36mINFO[0m[0027] cmd: /bin/sh                                 
[36mINFO[0m[0027] args: [-c cd /golang-preheat-cache && go mod download] 
[36mINFO[0m[0027] Running: [/bin/sh -c cd /golang-preheat-cache && go mod download] 
[36mINFO[0m[0033] Taking snapshot of full filesystem...        
[36mINFO[0m[0033] Resolving 50967 paths                        
[36mINFO[0m[0045] Using files from context: [/builds/abcde/pipeline/projetname/helpers/go-pipeline-commands] 
[36mINFO[0m[0045] ADD helpers/go-pipeline-commands /pipeline-helpers/ 
[36mINFO[0m[0045] Resolving 25 paths                           
[36mINFO[0m[0045] Taking snapshot of files...                  
[36mINFO[0m[0045] RUN cd /pipeline-helpers && CGO_ENABLED=0 GOOS=linux make 
[36mINFO[0m[0045] cmd: /bin/sh                                 
[36mINFO[0m[0045] args: [-c cd /pipeline-helpers && CGO_ENABLED=0 GOOS=linux make] 
[36mINFO[0m[0045] Running: [/bin/sh -c cd /pipeline-helpers && CGO_ENABLED=0 GOOS=linux make] 
[34m > Download dependencies [0m 
[37m > Tidy dependencies [0m 
[34m go mod tidy [0m 
[37m > Building the binary [0m 
[34m go build ./cmd/commit [0m 
[34m go build ./cmd/query-qa-pipeline-status [0m 
[37m > Format code [0m 
[34m go fmt ./... [0m 
[37m > Run unit tests [0m 
[34m go test -run TestUnit ./... [0m 
ok      code.abc.com/abcde/pipeline/projetname/helpers/cmd/commit   0.005s
ok      code.abc.com/abcde/pipeline/projetname/helpers/cmd/status   0.005s
[37m > Find static code issues [0m 
[34m go vet ./... [0m 
[36mINFO[0m[0055] Taking snapshot of full filesystem...        
[36mINFO[0m[0056] Resolving 52425 paths                        
[36mINFO[0m[0061] RUN echo "  Golang version:      `go version`" >> /pipeline-helpers/version-info-pipeline.txt 
[36mINFO[0m[0061] cmd: /bin/sh                                 
[36mINFO[0m[0061] args: [-c echo "  Golang version:      `go version`" >> /pipeline-helpers/version-info-pipeline.txt] 
[36mINFO[0m[0061] Running: [/bin/sh -c echo "  Golang version:      `go version`" >> /pipeline-helpers/version-info-pipeline.txt] 
[36mINFO[0m[0061] Taking snapshot of full filesystem...        
[36mINFO[0m[0065] Resolving 52426 paths                        
[36mINFO[0m[0069] RUN echo "  projetname type:           Helpers" >> /pipeline-helpers/version-info-pipeline.txt 
[36mINFO[0m[0069] cmd: /bin/sh                                 
[36mINFO[0m[0069] args: [-c echo "  projetname type:           Helpers" >> /pipeline-helpers/version-info-pipeline.txt] 
[36mINFO[0m[0069] Running: [/bin/sh -c echo "  projetname type:           Helpers" >> /pipeline-helpers/version-info-pipeline.txt] 
[36mINFO[0m[0069] Taking snapshot of full filesystem...        
[36mINFO[0m[0069] Resolving 52426 paths                        
[36mINFO[0m[0072] RUN echo "  Commit hash:         `echo ${CI_COMMIT_SHA}`" >> /pipeline-helpers/version-info-pipeline.txt 
[36mINFO[0m[0072] cmd: /bin/sh                                 
[36mINFO[0m[0072] args: [-c echo "  Commit hash:         `echo ${CI_COMMIT_SHA}`" >> /pipeline-helpers/version-info-pipeline.txt] 
[36mINFO[0m[0072] Running: [/bin/sh -c echo "  Commit hash:         `echo ${CI_COMMIT_SHA}`" >> /pipeline-helpers/version-info-pipeline.txt] 
[36mINFO[0m[0072] Taking snapshot of full filesystem...        
[36mINFO[0m[0072] Resolving 52426 paths                        
[36mINFO[0m[0076] Saving file pipeline-helpers/commit for later use 
[36mINFO[0m[0076] Saving file pipeline-helpers/version-info-pipeline.txt for later use 
[36mINFO[0m[0076] Saving file pipeline-helpers/status for later use 
[36mINFO[0m[0076] Deleting filesystem...                       
[36mINFO[0m[0077] Retrieving image manifest alpine             
[36mINFO[0m[0079] Retrieving image manifest alpine             
[36mINFO[0m[0080] Executing 0 build triggers                   
[36mINFO[0m[0080] Unpacking rootfs as cmd RUN mkdir -p /pipeline requires it. 
[36mINFO[0m[0080] RUN mkdir -p /pipeline                       
[36mINFO[0m[0080] Taking snapshot of full filesystem...        
[36mINFO[0m[0080] Resolving 482 paths                          
[36mINFO[0m[0080] cmd: /bin/sh                                 
[36mINFO[0m[0080] args: [-c mkdir -p /pipeline]                
[36mINFO[0m[0080] Running: [/bin/sh -c mkdir -p /pipeline]     
[36mINFO[0m[0080] Taking snapshot of full filesystem...        
[36mINFO[0m[0080] Resolving 483 paths                          
[36mINFO[0m[0080] WORKDIR /pipeline                            
[36mINFO[0m[0080] cmd: workdir                                 
[36mINFO[0m[0080] Changed working directory to /pipeline       
[36mINFO[0m[0080] COPY --from=build-helpers /pipeline-helpers/commit . 
[36mINFO[0m[0080] Resolving 1 paths                            
[36mINFO[0m[0080] Taking snapshot of files...                  
[36mINFO[0m[0080] Resolving 1 paths                            
[36mINFO[0m[0080] Taking snapshot of files...                  
[36mINFO[0m[0081] Resolving 1 paths                            
[36mINFO[0m[0081] Taking snapshot of files...                  
[36mINFO[0m[0081] COPY --from=build-helpers /pipeline-helpers/status . 
[36mINFO[0m[0081] Resolving 1 paths                            
[36mINFO[0m[0081] Taking snapshot of files...                  
[36mINFO[0m[0081] RUN chmod a+x commit                    
[36mINFO[0m[0081] cmd: /bin/sh                                 
[36mINFO[0m[0081] args: [-c chmod a+x commit]             
[36mINFO[0m[0081] Running: [/bin/sh -c chmod a+x commit]  
[36mINFO[0m[0081] Taking snapshot of full filesystem...        
[36mINFO[0m[0081] Resolving 487 paths                          
[36mINFO[0m[0081] No files were changed, appending empty layer to config. No layer added to image. 
[36mINFO[0m[0081] cmd: /bin/sh                                 
[36mINFO[0m[0081] Taking snapshot of full filesystem...        
[36mINFO[0m[0081] Resolving 487 paths                          
[36mINFO[0m[0081] No files were changed, appending empty layer to config. No layer added to image. 
[36mINFO[0m[0081] RUN chmod a+x status       
[36mINFO[0m[0081] cmd: /bin/sh                                 
[36mINFO[0m[0081] args: [-c chmod a+x status] 
[36mINFO[0m[0081] Running: [/bin/sh -c chmod a+x status] 
[36mINFO[0m[0081] Taking snapshot of full filesystem...        
[36mINFO[0m[0081] Resolving 487 paths                          
[36mINFO[0m[0081] No files were changed, appending empty layer to config. No layer added to image. 
[36mINFO[0m[0081] CMD []                                       
[32;1m$ echo projetname_IMAGE_TAG=${IMAGE_TAG}[0;m
projetname_IMAGE_TAG=feat-qapipelinedeploy
section_end:1590231218:build_script
[0Ksection_start:1590231218:after_script
[0Ksection_end:1590231219:after_script
[0Ksection_start:1590231219:archive_cache
[0Ksection_end:1590231220:archive_cache
[0Ksection_start:1590231220:upload_artifacts_on_success
[0Ksection_end:1590231222:upload_artifacts_on_success
[0K[32;1mJob succeeded

从 Docker GIT.YML 文件中,我正在调用 bash ./status 命令。由于无法执行二进制文件而引发错误

在构建上述 docker 映像之后,还有一个 docker 文件在不同的阶段构建。此 docker 镜像用于在 YML 文件中进行测试。

RG GO_VERSION=1.14
# Install OpenAPI Validator
FROM golang:${GO_VERSION} AS openapivalidatorbuilder
WORKDIR /work
ENV GOPRIVATE=code.abcd.com
COPY /reusable-aspects/enforcement/open-api-check/  .
RUN go build .

ARG PIPELINE_HELPER=docker.abcd.com/projectName/pipeline/projects/helpers:master
FROM ${PIPELINE_HELPER} as helper

FROM golang:${GO_VERSION}

ENV GOPRIVATE=code.abcd.com

ADD /reusable-aspects/ci-caching/golang-preheat-cache  /golang-preheat-cache
RUN cd /golang-preheat-cache && go mod download

RUN curl -L https://github.com/a8m/envsubst/releases/download/v1.1.0/envsubst-`uname -s`-`uname -m` -o envsubst

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    nodejs \
    npm \
    unzip

RUN npm --version
RUN npm install -g \
    npm@6.11 \
    serverless@1.51

RUN apt-get install -y \
    # Install ruby and CFN_NAG
    ruby-dev \
    ruby-json \
    ruby \
    ruby-bundler \
    # Install AWS CLI
    awscli \
    jq \
    figlet

RUN rm -rf /var/cache/apk/*

RUN gem install cfn-nag --no-rdoc --no-ri

RUN mkdir /pipeline

ADD helpers/bash-commons/src/welcome /pipeline

RUN echo "  Golang version:               `go version`" >> /pipeline/version-info-pipeline.txt
RUN echo "  Node version:                 `node -v`" >> /pipeline/version-info-pipeline.txt
RUN echo "  Serverless version:           `serverless -v`" >> /pipeline/version-info-pipeline.txt
RUN echo "  projects type:                    Information Serverless Golang" >> /pipeline/version-info-pipeline.txt

COPY --from=openapivalidatorbuilder /work/open-api-check /pipeline/open-api-check
RUN chmod a+x /pipeline/open-api-check

COPY --from=helper /pipeline/hash /pipeline
COPY --from=helper /pipeline/status /pipeline

【问题讨论】:

  • 您能否为您的映像至少包含 FROM 行,以及您生成二进制文件的早期构建阶段? (您显示的构建命令会生成 32 位 Linux 和 64 位 Windows 二进制文件,而这两者都会产生您显示的错误。)
  • 已添加。你能检查一下吗?
  • 这里令人惊讶的是有 2 个二进制文件,提交(这是项目开始时编写的非常旧的一个)和新写入的状态。提交运行良好。
  • 正在构建的二进制文件是否使用 CGO? Alpine linux 使用与大多数发行版不同的 C 运行时。出现“无法执行二进制文件”的错误,通常是因为存在二进制文件时缺少依赖 DLL。
  • 另外我不知道你为什么要搞乱 GOARCH 和 GOOS。 GOOS 将为 Linux 或 Windows 构建二进制文件。它应该与容器操作系统匹配。例如“来自阿尔卑斯山”。然后你会期望 GOOS 是 linux (这是在 Linux 上构建 Go 应用程序的默认设置。Arch 将默认取决于 32 位或 64 位。现在大多数系统都是 64 位......所以不要管它。按照指示检查对 c 运行时的依赖关系在我之前的评论中。

标签: docker ubuntu go


【解决方案1】:

golang:1.14 不是alpine 基数,而是debian 基数。所以当然你不能在 alpine 镜像中运行 debian build 二进制文件。

尝试替换

FROM golang:${GOLANG_VERSION} as build-helpers

FROM golang:${GOLANG_VERSION}-alpine as build-helpers

并添加以下行以下载构建二进制文件所需的库

RUN apk update && \
  apk --update upgrade && \
  apk add --no-cache ca-certificates gcc musl-dev git && \
  update-ca-certificates && \
  rm -rf /var/cache/apk/*

更新

添加make并将apk更新并添加到FROM golang:...

FROM golang:${GOLANG_VERSION}-alpine as build-helpers

RUN apk update && \
  apk --update upgrade && \
  apk add --no-cache ca-certificates gcc musl-dev git make && \
  update-ca-certificates && \
  rm -rf /var/cache/apk/*

OP 更新问题后更新

由于您要将alpine 构建状态二进制文件从helper 复制到您的最终映像,基址为golang:${VERSION},即debian 环境,它当然无法运行。

我建议您对所有构建阶段或最终 docker 映像仅使用一种环境(alpinedebian)。

所以你第一个 docker 镜像的第一个构建状态应该是

FROM golang:${GOLANG_VERSION}

最后的图片请使用debian而不是alpine

FROM debian

【讨论】:

  • 进行上述更改后,出现以下错误 - INFO[0037] Running: [/bin/sh -c cd /pipeline-helpers && CGO_ENABLED=0 GOOS=linux make] /bin/sh : make: 未找到
  • 更新了将make添加到apk add的答案
  • 更换docker后,我没有收到任何错误。但是,我仍然收到错误,因为无法执行二进制文件... $ uname -m x86_64 $ uname -a Linux runner-4KR_No93-project-12345-concurrent-04.44.111-105.231.amzn1.x86_64 #1 SMP Thu Feb 27 23:49:15 UTC 2020 x86_64 GNU/Linux $ bash /pipeline/status -GITLAB_API_TOKEN=$PERSONAL_API_TOKEN /pipeline/status: /pipeline/status: 无法执行二进制文件错误:作业失败:退出代码 1
  • 我已经更新了我的问题。还有一个在不同阶段构建的 docker 文件。此 docker 映像用于在 YML 文件中进行测试。在第一阶段 GoLangMaker 作业被执行。在这个 docker 文件中,我根据您的建议进行了更改。在第二阶段,构建另一个 docker 映像,称为无服务器 docker。 tis docker文件生成的镜像用于测试。
  • 您正在从 alpine 辅助映像复制状态二进制文件以在 debian 环境中运行。这就是它不起作用的原因。您应该只对所有构建阶段和最终映像使用 alpine 或 debian。
猜你喜欢
  • 2017-12-17
  • 2022-08-06
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多