概要
scratchイメージで作成したDockerコンテナを実行したところ以下のエラーが発生しました。
コンテナには、AWS上のエンドポイントにHTTPSでリクエストする処理を組み込んでいました。
caused by: Post "https://sqs.ap-northeast-1.amazonaws.com/": x509: certificate signed by unknown authority
このエラーを解決するお話です。
原因
以下の記事で解説されています。Dockerコンテナ内からSSL通信を行っていますが、証明書が無いためエラーとなっています。
x509: certificate signed by unknown authority の対応
ただ、自分の場合scratchイメージからコンテナを作成していたのでコンテナ上でapk
コマンドを使えず、そのままでは証明書を設定することができません。
対処法
DockerのMulti Stage Buildを用います。Multi Stage Buildは以下の記事が大変参考になります。
Docker multi stage buildで変わるDockerfileの常識
ソース例は以下の通りです。
# STEP 1
FROM golang:alpine as builder
RUN apk update && apk add --no-cache ca-certificates && update-ca-certificates
WORKDIR $GOPATH/bin/
COPY ./exe/aws-access .
# STEP 2 build a small image
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /go/bin/aws-access /go/bin/aws-access
ENTRYPOINT ["/go/bin/aws-access"]
- STEP1でalpineのGoコンテナから証明書ファイルを作成
- ローカルから
sqs-access
というexeファイルをaplineコンテナにコピー - STEP2でaplineコンテナからscratchコンテナに証明書ファイル、exeファイルをコピー
- scratchコンテナでexeを実行
このDockerファイルを以下のようにbuildして、docker runすると起動します。
docker build -t multi-build-aws-access .
ちなみに、STEP2から作成されたDockerコンテナは4.5MB
でした。Goのコンパイル時に、不要なリンクを削除したりUPX圧縮しています。scrtachイメージ素晴らしいですね。
具体的な手順は以下記事の例を参考にさせていただきました。Add SSL ca certificatesの部分です。
Create the smallest and secured golang docker image based on scratch
先人の皆様に感謝です。