4

我尝试使用私有公司网络中构建图像:

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:由未知机构签署的证书(在 Docker 容器中运行 Go 应用程序)

docker build:无法获取 github 公共存储库,x509:证书由未知机构签名

未知权威签署的 x509 证书 - go-pingdom

,但结果是一样的。


❗️如果加-insecureflag

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

Dockerfile unrecognized import path错误包装先前的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

有什么问题❓</p>

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

4

4 回答 4

14

git用于curl访问https服务器,因此您需要将证书导入CA store系统。

解决方法是GIT_SSL_NO_VERIFY=1在您的 Agent 环境变量上定义环境变量,但在使用or时不起作用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

...
于 2020-12-23T07:26:20.787 回答
4

应对自我证书 ( .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

于 2020-10-21T15:06:15.277 回答
1

我会建议几件事:

  • 在与最终代码映像相同的操作系统发行版中构建您的代码,以便您确定您的代码将在该特定发行版中运行。此外,某些发行版要求证书位于不同的文件夹中,因此请注意这一点。
  • 对第一个图像使用 alpine 将大大减少您的构建时间。您可以在这里 latest看到大小约为 260M,但alpine约为 100M。
  • 最好使用特定版本的 alpine,这样您就可以确保您的代码在该版本中运行(我让您自行决定)
  • Golang 非常强大的一点是你可以在一个名为 的空 docker 镜像中运行它scratch,这意味着你最终的 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"]

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

于 2020-10-21T15:46:09.700 回答
-1

从你的错误信息

获取“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 - 弹出以下窗口时,单击“始终信任”按钮。

于 2020-10-30T06:53:29.997 回答