简体   繁体   English

docker 多阶段构建 Go 映像 - x509:由未知机构签署的证书

[英]docker multi-stage build Go image - x509: certificate signed by unknown authority

I try to build images in private corp network use :我尝试在私有公司网络中使用 docker 构建图像:

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"]

and get x509: certificate signed by unknown authority error并获取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

I tried to find an answer in我试图在

X509: Certificate Signed by Unknown Authority (Running a Go App Inside a Docker Container) X509:由未知机构签署的证书(在 Docker 容器内运行 Go 应用程序)

and

docker build: cannot get the github public repository, x509: certificate signed by unknown authority docker build:无法获取 github 公共存储库,x509:证书由未知机构签名

and

x509 certificate signed by unknown authority - go-pingdom未知权威签署的 x509 证书 - go-pingdom

, but result is the same. ,但结果是一样的。


❗️If add -insecure flag ❗️如果添加-insecure标志

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

to Dockerfile unrecognized import path error wrap previous x509 error and an unreachable package change to golang.org/x/cryptoDockerfile unrecognized import path错误wrap previous x509 error and an unreachable package change to 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

What is the problem❓有什么问题❓

(I understand that problem is in the certificates and authentication when git get dependencies, but I try to make process of building images more common) (我知道问题出在git获得依赖项时的证书和身份验证中,但我尝试使构建映像的过程更常见)

git uses curl to access the https servers so you need to import the certificate into the CA store of the system. git使用curl访问https服务器,因此您需要将证书导入系统的CA store中。

The workaround is to define the environment variable GIT_SSL_NO_VERIFY=1 on your Agent environment variables, but it doesn't work when using go get or go mod download 😭.解决方法是在您的代理环境变量上定义环境变量GIT_SSL_NO_VERIFY=1但是在使用go getgo mod download不起作用😭。

To import the certificate on your system CA store the procedure depends on your OS you have to use openssl .要在您的系统 CA 存储中导入证书,该过程取决于您必须使用的操作系统openssl

For example例如

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 output 👇🏼 docker 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

...

😭 Coping self certificates ( .crt ) helped 😭应对自我证书( .crt )有帮助

1️⃣ add .crt to required dir 1️⃣ 将.crt添加到所需dir

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

2️⃣ COPY certificates to 'builder'-container 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

I'll suggest a couple of things:我会建议几件事:

  • Build your code within the same OS distribution as the final code image, so that you are sure that your code will run in that specific distribution.在与最终代码映像相同的操作系统发行版中构建您的代码,以确保您的代码将在该特定发行版中运行。 Also some distributions require certs to be in different folders, so be aware of that.此外,某些发行版要求证书位于不同的文件夹中,因此请注意这一点。
  • Using alpine for the first image will substantially decrease your build time.将 alpine 用于第一个图像将大大减少您的构建时间。 You can see here latest size is ~260M, but alpine is ~100M.你可以在这里看到latest大小是 ~260M,但alpine是 ~100M。
  • Better will be to use an specific version of alpine, so that you can be sure that your code runs in that version (I leave this at your discretion)最好使用特定版本的 alpine,这样您就可以确保您的代码在该版本中运行(我自行决定)
  • Something very powerful of Golang is that you can run it in an empty docker image called scratch , this means, your final docker images does not contain more than your own executable. Golang 非常强大的一点是,您可以在一个名为scratch的空 docker 镜像中运行它,这意味着,您最终的 docker 镜像所包含的内容不会超过您自己的可执行文件。
  • If you need your own certificates you must have them in your code and copy them before executing update-ca-certificates so that they get included in the final file如果您需要自己的证书,则必须在代码中包含它们并在执行update-ca-certificates之前复制它们,以便将它们包含在最终文件中

Here's an example of the dockerfile with what I explained above这是我上面解释的 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"]

If own certificates replace first docker stage with:如果自己的证书将第一个 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}

Because you use own certificates your final Dockerfile will look like this:因为您使用自己的证书,所以最终的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"]

Feel free to ask me if you have any doubt :)如果您有任何疑问,请随时问我:)

From your error message从你的错误信息

Get "https://proxy.golang.org/github.com/dgrijalva/jwt-go/v4/@v/v4.0.0-preview1.mod": x509: certificate signed by unknown authority获取“https://proxy.golang.org/github.com/dgrijalva/jwt-go/v4/@v/v4.0.0-preview1.mod”:x509:由未知机构签名的证书

It looks like the CA root of proxy.golang.org is not part of the trusted root CAs in your private corp docker environment.看起来 proxy.golang.org 的 CA 根不是您的私有公司 docker 环境中受信任的根 CA 的一部分。

I'd try to install it with :我会尝试安装它:

1 - Get the certificate from proxy.golang.org : 1 - 从 proxy.golang.org 获取证书:

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

If you open golang.cer you should see the certificates chain如果您打开 golang.cer,您应该会看到证书链

在此处输入图片说明

2 - install it in your trusted root CAs : 2 - 将其安装在您信任的根 CA 中:

certutil.exe -addstore root golang.cer

...or on Mac : ...或在 Mac 上:

2a - Double click the certificate file (with ".cer" extension) 2a - 双击证书文件(带有“.cer”扩展名)

2b - Choose "System" from the keychain option. 2b - 从钥匙串选项中选择“系统”。 Then press "OK"然后按“确定”

2c - When the following window pops-up, click the "Always Trust" button. 2c - 当以下窗口弹出时,单击“始终信任”按钮。

For me, installing curl and sudo before go helped.对我来说,在 go 之前安装 curl 和 sudo 有帮助。

RUN apt-get update

# If I remove the next two lines, my build fails with the error above.
RUN apt-get -y install curl
RUN apt-get -y install sudo

RUN apt-get -y install golang-go

RUN ["go", "build", "api.go"]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Docker go 映像 - 无法获取 - x509:由未知机构签名的证书 - Docker go image - cannot go get - x509: certificate signed by unknown authority 由未知机构签署的 x509 证书 - go-pingdom - x509 certificate signed by unknown authority - go-pingdom 码头工人错误:x509:证书由未知授权机构签名 - docker error: x509: certificate signed by unknown authority x509:由未知机构签署的证书 - 使用 docker 和 github - x509: certificate signed by unknown authority - both with docker and with github Docker 私有注册表:x509:由未知权威签名的证书 - Docker Private Registry: x509: certificate signed by unknown authority Docker-X509:Windows 7中未知权限错误签署的证书 - Docker - x509:certificate signed by unknown authority error in windows 7 Docker登录x509:证书由未知权威签署 - Docker login x509: certificate signed by unknown authority x509:构建docker映像时,由未知权限签署的证书 - x509: certificate signed by unknown authority when building docker image Windows上的docker工具箱,然后docker run hello-world获取x509:未知授权机构签名的证书 - docker toolbox on windows then docker run hello-world gets x509: certificate signed by unknown authority minikube - x509:由未知权威机构签署的证书 - minikube - x509: certificate signed by unknown authority
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM