前提
- GitLab-CIの実行コンテナに、公式dockerイメージ(=Alpine)を使っていた
- AWS CLI v2 のインストールにはglibcが必要
- Alpineイメージのコンテナにはglibcが入ってないので自前でインストールしていた
2021/8/5木昼 急にCI/CDが通らなくなった
ある日いつものようにコードの反映のためにCI/CDの実行結果を待っていたら、CICDジョブが失敗していました。
CI/CDジョブの実行結果にはこんなエラーが・・・
**ERROR: glibc-2.31-r0: trying to overwrite lib64/ld-linux-x86-64.so.2 owned by libc6-compat-1.2.2-r1.**
環境の説明
ここで環境、特にCI/CDまわりの説明をしておきます。
まず、CI/CDにはGitLab-CI(Shared Runner)を使用していて、その実行コンテナとして公式dockerイメージ(= Alpine)を使っていました。
image: docker:latest #<- alpineで作られている services: - docker:dind variables: ...
CI/CDでは実行時の最初に環境構築用のシェルを走らせています。ざっと以下の様な感じです。
#!/bin/sh set -eux GLIBC_VER=2.31-r0 apk --no-cache add binutils curl curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-${GLIBC_VER}.apk curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-i18n-${GLIBC_VER}.apk apk add --no-cache glibc-${GLIBC_VER}.apk glibc-bin-${GLIBC_VER}.apk glibc-i18n-${GLIBC_VER}.apk /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 C.UTF-8 || true curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip unzip -q awscliv2.zip aws/install
エラーの確認
最初に記載したエラーが、まずどの部分で起きているのかを確認してみました。
+ apk add --no-cache glibc-2.31-r0.apk glibc-bin-2.31-r0.apk glibc-i18n-2.31-r0.apk fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz (1/3) Installing glibc (2.31-r0) **ERROR: glibc-2.31-r0: trying to overwrite lib64/ld-linux-x86-64.so.2 owned by libc6-compat-1.2.2-r1.** (2/3) Installing glibc-bin (2.31-r0) (3/3) Installing glibc-i18n (2.31-r0) Executing glibc-bin-2.31-r0.trigger /usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link 1 error; 60 MiB in 31 packages
→glibcインストール部分で失敗している
**ERROR: glibc-2.31-r0: trying to overwrite lib64/ld-linux-x86-64.so.2 owned by libc6-compat-1.2.2-r1.**
この挙動の理由としては、libc6-compatというライブラリパッケージと衝突しているようです。
掘り下げると、glibc内の共有オブジェクトファイルをこちらのライブラリパッケージが入れちゃってるようですね。
急にエラーが起きるようになった原因
公式dockerイメージ:バージョン20.10.8で、dockerfileでlibc6-compatが追加されるようになっていた!!
このエラーが起きた半日前(エラー同日!)に新しいcommitがありそこで追加されていた・・・(Goのためのようです)
対処(+不採用候補)
採用案と不採用案を1つずつ載せておきます。
- ★採用案:libc6-compatが入っている場合はシェル内で消す
- 採用理由
- 単純に公式のバージョンアップに適応した
- 採用はしたが理想ではない
- 入っているものをわざわざ消すという、不格好な対応ではあるので・・・
- そしたらそもそも使うOS変えるとか、違う入れ方するとかの方が綺麗
- そんな時間はなかった(影響範囲も大きかった)
- 対処内容詳細
- 他のイメージだとlibc6-compatが入っていなかったりするので分岐処理を入れといた
- 採用理由
libc6_compat_check=`apk info | grep libc6-compat || true` if [ -n "${libc6_compat_check}" ]; then apk del libc6-compat fi
- 不採用案:コンテナイメージのバージョンにlatestを使用せず、今回の更新が入る前のものに固定
- 不採用理由
- 本来、長期運用を見越した場合にバージョンは指定するのがセオリーだが、まだインストールするモジュール要件が固まっていなかったのと、開発者側がどんどん新しいパッケージを入れたくなる際にその固定したバージョンのイメージだとインストールできなくなる、などのようなことが想定されたため
- そのたびに変更していくのが理想だが中々そうもいかず・・・
- どこかのタイミングで固定します・・・(まだ実はリリース前のプロダクトだったため)
- また、これからどんどん公式でアップデートされていった際にずっと新しいバージョン使えないのは辛い
- それならそのプラットフォームに合わせて構築した方がいい
- 本来、長期運用を見越した場合にバージョンは指定するのがセオリーだが、まだインストールするモジュール要件が固まっていなかったのと、開発者側がどんどん新しいパッケージを入れたくなる際にその固定したバージョンのイメージだとインストールできなくなる、などのようなことが想定されたため
- 不採用理由
最後に
とりあえず、これで何とか動くようになりました。
CI/CD内でdocker buildするためにdockerのイメージを使用して、かつ AWS CLIも一緒に入れることもあると思うので、このエラーにぶつかってる人も少なくないのではと思います・・・