【问题标题】:docker multi-stage build Go image - x509: certificate signed by unknown authoritydocker multi-stage build Go image - x509:由未知权威签署的证书
【发布时间】:2020-10-21 11:51:49
【问题描述】:

我尝试在私人公司网络中构建图像使用

FROM golang:latest as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN  GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}

FROM alpine:latest
LABEL maintainer="Kozmo"
RUN apk add --no-cache bash
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]

并得到x509: certificate signed by unknown authority 错误

Step 1/13 : FROM golang:latest as builder
 ---> 2421885b04da
Step 2/13 : WORKDIR /app
 ---> Using cache
 ---> 6555644dbd16
Step 3/13 : COPY go.mod go.sum ./
 ---> 55d45a30f492
Step 4/13 : RUN go mod download
 ---> Running in 88c21c6b4fab
go: github.com/dgrijalva/jwt-go/v4@v4.0.0-preview1: Get "https://proxy.golang.org/github.com/dgrijalva/jwt-go/v4/@v/v4.0.0-preview1.mod": x509: certificate signed by unknown authority
The command '/bin/sh -c go mod download' returned a non-zero code: 1
make: *** [docker] Error 1

我试图在

中找到答案

X509: Certificate Signed by Unknown Authority (Running a Go App Inside a Docker Container)

docker build: cannot get the github public repository, x509: certificate signed by unknown authority

x509 certificate signed by unknown authority - go-pingdom

,但结果是一样的。


❗️如果添加-insecure标志

...
RUN go env -w GOPROXY=direct GOFLAGS="-insecure"
COPY go.mod go.sum ./
...

Dockerfile ???????? unrecognized import path 错误 wrap 以前的 x509 错误和 无法访问 包更改为 golang.org/x/crypto

go: golang.org/x/crypto@v0.0.0-20200622213623-75b288015ac9: unrecognized import path "golang.org/x/crypto": https fetch: Get "https://golang.org/x/crypto?go-get=1": x509: certificate signed by unknown authority

有什么问题❓

(我知道问题出在git 获取依赖项时的证书和身份验证中,但我尝试使构建图像的过程更常见)

【问题讨论】:

  • 您是否尝试在客户端重新启动 docker.service?
  • @Ashok - 零结果
  • @Peter - 当我使用golang:latest 时,我得到The command '/bin/sh -c apk add --no-cache ca-certificates' returned a non-zero code: 127
  • @Peter - 当我使用golang:alpine 时,我得到go: github.com/dgrijalva/jwt-go/v4@v4.0.0-preview1: git init --bare in /go/pkg/mod/cache/vcs/dbb1616a13223a75321e21a8150b1a7781650b73e761213ecc0ab67568c38ac2: exec: "git": executable file not found in $PATH

标签: go docker-multi-stage-build docker go docker-multi-stage-build go-build go-git


【解决方案1】:

git使用curl访问https服务器,所以需要将证书导入系统的CA store

解决方法是在您的代理环境变量上定义环境变量GIT_SSL_NO_VERIFY=1但在使用go getgo mod download 时不起作用 ?。

要将证书导入系统 CA 存储,过程取决于您的操作系统,您必须使用 openssl

例如

FROM golang:latest as builder

RUN apt-get update && apt-get install -y ca-certificates openssl

ARG cert_location=/usr/local/share/ca-certificates

# Get certificate from "github.com"
RUN openssl s_client -showcerts -connect github.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > ${cert_location}/github.crt
# Get certificate from "proxy.golang.org"
RUN openssl s_client -showcerts -connect proxy.golang.org:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >  ${cert_location}/proxy.golang.crt
# Update certificates
RUN update-ca-certificates

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN  GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}

FROM alpine:latest
LABEL maintainer="Kozmo"
RUN apk add --no-cache bash
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]

docker image build 输出??

...

Step 5/19 : RUN openssl s_client -showcerts -connect github.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > ${cert_location}/github.crt
 ---> Running in bb797e26d4b4
Removing intermediate container bb797e26d4b4
 ---> 6c68ddafd884
Step 6/19 : RUN openssl s_client -showcerts -connect proxy.golang.org:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >  ${cert_location}/proxy.golang.crt
 ---> Running in 61f59939d75e
Removing intermediate container 61f59939d75e
 ---> 72d2b03b11e6
Step 7/19 : RUN update-ca-certificates
 ---> Running in 6cf9aa248776
Updating certificates in /etc/ssl/certs...
2 added, 0 removed; done. ?? 'certificates updated'

...

Step 8/18 : COPY go.mod go.sum ./
 ---> 436263b76050
Step 9/18 : RUN go mod download ?? 'works fine'
 ---> Running in 2387c78147db
Removing intermediate container 2387c78147db
 ---> a37c05c2b531
Step 10/18 : COPY . .
 ---> 01b49c388f59

...

【讨论】:

    【解决方案2】:

    ? 应对自我证书 (.crt) 有帮助

    1️⃣将.crt添加到所需的dir

    .
    └── backend
        ├── Dockerfile
        ├── Makefile
        ├── cmd
        │   └── main.go
        ├── etc
        │   ├── ssl
        │   │   └── github.crt #❗️a copy of the self certificate 
    

    2️⃣COPY'builder'-container 证书

    FROM golang:latest as builder
    COPY  etc/ssl/ /etc/ssl/certs/ #❗️add certificates to the container 
    WORKDIR /app
    COPY go.mod go.sum ./
    RUN go mod download
    

    【讨论】:

      【解决方案3】:

      我会建议几件事:

      • 在与最终代码映像相同的操作系统发行版中构建您的代码,以确保您的代码将在该特定发行版中运行。此外,某些发行版要求证书位于不同的文件夹中,因此请注意这一点。
      • 对第一个映像使用 alpine 将大大减少构建时间。你可以看到herelatest的大小约为260M,而alpine的大小约为100M。
      • 最好使用特定版本的 alpine,这样您就可以确保您的代码在该版本中运行(这由您自行决定)
      • Golang 非常强大的一点是,您可以在名为 scratch 的空 docker 镜像中运行它,这意味着,您最终的 docker 镜像不包含您自己的可执行文件。
      • 如果您需要自己的证书,则必须在代码中包含它们并在执行 update-ca-certificates 之前复制它们,以便它们包含在最终文件中

      这是我上面解释过的 dockerfile 示例

      FROM golang:alpine as builder
      WORKDIR /app
      
      # This will download all certificates (ca-certificates) and builds it in a
      # single file under /etc/ssl/certs/ca-certificates.crt (update-ca-certificates)
      # I also add git so that we can download with `go mod download` and
      # tzdata to configure timezone in final image
      RUN apk --update add --no-cache ca-certificates openssl git tzdata && \
      update-ca-certificates
      
      COPY go.mod go.sum ./
      RUN go mod download
      COPY . .
      RUN  GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}
      
      # Golang can run in a scratch image, so that, the only thing that your docker 
      # image contains is your executable
      FROM scratch
      LABEL maintainer="Kozmo"
      COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
      
      # This line will copy all certificates to final image
      COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
      WORKDIR /app
      COPY --from=builder /app/main .
      EXPOSE 8080
      CMD ["./main"]
      

      如果自己的证书将第一个 docker 阶段替换为:

      FROM golang:alpine as builder
      WORKDIR /app
      
      RUN apk --update add --no-cache ca-certificates openssl git tzdata
      
      COPY your/cert/path /usr/local/share/ca-certificates/your-cert-name
      
      RUN update-ca-certificates
      
      COPY go.mod go.sum ./
      RUN go mod download
      COPY . .
      RUN  GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}
      

      因为您使用自己的证书,所以您的最终 Dockerfile 将如下所示:

      FROM golang:alpine as builder
      WORKDIR /app
      
      RUN apk --update add --no-cache ca-certificates openssl git tzdata
      
      COPY your/cert/path /usr/local/share/ca-certificates/your-cert-name
      
      RUN update-ca-certificates
      
      COPY go.mod go.sum ./
      RUN go mod download
      COPY . .
      RUN  GO111MODULE="on" CGO_ENABLED=0 GOOS=linux go build -o main ${MAIN_PATH}
      
      FROM scratch
      LABEL maintainer="Kozmo"
      COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
      
      # This line will copy all certificates to final image
      COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
      WORKDIR /app
      COPY --from=builder /app/main .
      EXPOSE 8080
      CMD ["./main"]
      

      如果您有任何疑问,请随时问我:)

      【讨论】:

      • 我在步骤RUN go mod download?? 有同样的错误 (x509: certificate signed by unknown authority),因为我尝试在 private corp 网络中构建图像。在我们公司我们可以使用nexus作为go proxy,也许我必须尝试通过nexus构建图像......
      • 你有什么建议为什么我得到x509: certificate signed by unknown authority 使用Dockerfile 就像你提供的那样❓
      • 您是否按照第二部分的说明复制了证书?另外我忘了提到它们必须是.pem 格式才能让update-ca-certificates 提取它们并将它们添加到受信任的证书中
      • 如果我使用golang:latest as builder 并复制自我证书(查看我的 答案)?? 它有效,但是当我尝试使用@ 987654340@ like your first example 我有一个错误:x509: certificate signed by unknown authority
      • 我的意思是复制您自己的证书作为我答案的第二部分。将它们复制到舞台golang:latest as builder中的/usr/local/share/ca-certificates/
      【解决方案4】:

      来自您的错误消息

      获取 “https://proxy.golang.org/github.com/dgrijalva/jwt-go/v4/@v/v4.0.0-preview1.mod”: x509: 未知权威签署的证书

      proxy.golang.org 的 CA 根似乎不是您私有 corp docker 环境中受信任的根 CA 的一部分。

      我会尝试安装它:

      1 - 从 proxy.golang.org 获取证书:

      echo -n | openssl s_client -connect proxy.golang.org:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./golang.cer
      

      如果你打开 golang.cer,你应该会看到证书链

      2 - 将其安装在您信任的根 CA 中:

      certutil.exe -addstore root golang.cer
      

      ...或在 Mac 上:

      2a - 双击证书文件(扩展名为“.cer”)

      2b - 从钥匙串选项中选择“系统”。然后按“确定”

      2c - 弹出以下窗口时,单击“始终信任”按钮。

      【讨论】:

      • 请为 mac/nix 添加install it in your trusted root CAs ...
      猜你喜欢
      • 2018-04-22
      • 1970-01-01
      • 2021-02-08
      • 1970-01-01
      • 2019-11-16
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2015-05-30
      相关资源
      最近更新 更多