問題
cloudbuildでビルドしたGo言語のプログラム(ELF形式)を、dockerコンテナ( ubuntu:latest
)上で実行しようとしすると実行に失敗する。
# file myapp myapp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, not stripped # ./myapp bash: ./myapp: No such file or directory
原因
ELFファイルを readelf
すると以下のように、 ubuntu:latest
上には存在しない ld-musl-x86_64
に対しinternal linkが張られていることがわかる。
# readelf -a ./myapp | grep Requesting [Requesting program interpreter: /lib/ld-musl-x86_64.so.1]
go言語のビルド設定である、 cloudbuild.yaml
のビルド設定は以下のようにしていた。以下の書き方の場合、明示的にタグを指定していないため latest
タグのついたイメージが取得される。
- name: 'gcr.io/cloud-builders/go' id: 'GO_BUILD' args: ['install', '.'] env: - 'PROJECT_ROOT=github.com/shinmatsuzaki/myapp'
gcr.io/cloud-builders/go
の場合、latest
タグはalpineベースのイメージに対し付与される。
そのために、go言語のビルドが実行される際、ELFに対しalpine linux上のライブラリがリンクされる。同名のライブラリがubuntuイメージ上にない場合、ELFの実行に失敗する。
$ gcloud container images list-tags gcr.io/cloud-builders/go | head -4 DIGEST TAGS TIMESTAMP dfabdc5d6ad7 debian 2020-02-15T18:23:35 c3bf65790cab alpine,latest 2020-02-15T18:23:12
対処
不足するライブラリをubuntuイメージにインストールする方向で、Dockerfileに RUN apt update && apt install -y musl-dev
を追加。
※以下の記事のように、 cloudbuild.yaml
でgoのbuildに指定するイメージとして gcr.io/cloud-builders/go:debian
を指定する方法でも問題を解消できると思います。
参考