3
5

More than 3 years have passed since last update.

カスタムイメージを使ってCodebuildでbuildするまで。

Last updated at Posted at 2020-06-09

マニュアル見ろよ、という話しではあるんだが。
私はなんか突っかかるまでマニュアル読まないタイプの人なので。

やりたかったこと

  • マネージドイメージ内でカスタムイメージをビルド。ビルドしたイメージをECRにPush
  • カスタムイメージ内で、golangのpackeageをビルド。ビルドした生成物をS3にアップロード

カスタムイメージの作成まで

DOWNLOAD_SOURCEでi/o timeout for primary source

GitHubへのoAuth設定をCodeBuildから行うと、こんなエラーが出る。GitHub側で問題おきていることは考えにくいので、CodeBuild側の問題。

CLIENT_ERROR: Get https://github.com/XXXXXXXXXXX/sample.git/info/refs?service=git-upload-pack:
 dial tcp 13.114.40.48:443: i/o timeout for primary source

CodeBuildはVPC内に設定してあり、NAT-Gateway経由でGitHubに接続しているのだが、そこが問題だろう。13.114.40.48はGithub.comのIPv4アドレスなので、DNS変換は出来ているが、git cloneで問題が起きているようだ。

対応

SecurityGroupの指定に問題あったようで、SGに何らかのインバウンド許可をつけることでNATを通過し通信が届くようになった。
※以下codebuidに付与したSGのインバウントに3389ポートを許可し、ビルドした際のcodebuildのログ
YAML_FILE_ERROR: YAML file does not exist
この時点でカスタムイメージを作成するためのbuildspec.yamlはまだ作成してなかったので想定通りなのだが、接続部分で既にエラーが起きるというのは先が思いやられる…。

余談

CodeBuildのDOWNLOAD_SOURCEフェーズではログが出ないため、原因を切り分けるのに大変分かりにくい。せめてbashが使えればもっと早く解決できるのに…。

INSTALLでCOMMAND_EXECUTION_ERROR

https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-docker-custom-image.html
を参考にしながら流用しつつそれっぽくyaml作って再実行してみるとまたエラー

COMMAND_EXECUTION_ERROR: Error while executing command: timeout 15 sh -c "until docker info; do echo .; sleep 1; done". Reason: exit status 124

ログを見るとこんなエラーが出てるなあ。Dockerが動いてない。

Server:
ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
errors pretty printing info
.
time="2020-06-05T05:53:33.864814126Z" level=info msg="Starting up"
time="2020-06-05T05:53:33.903326219Z" level=warning msg="could not change group /var/run/docker.sock to docker: group docker not found"
time="2020-06-05T05:53:33.903422360Z" level=warning msg="[!] DON'T BIND ON ANY IP ADDRESS WITHOUT setting --tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING [!]"

対応

「特権付与」が必要。

このビルドプロジェクトを使用して Docker イメージをビルドするため、[Privileged] を選択します
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-docker.html

よく読めば書いてはあるんだよ。あるんだけど、わかりにくいよねえ。
image.png

「環境」の箇所から上記をチェック

PRE_BUILDでCOMMAND_EXECUTION_ERROR

一歩進んで二歩下がる?

COMMAND_EXECUTION_ERROR: Error while executing command: $(aws ecr get-login --no-include-email). Reason: exit status 255

対応

CodeBuildに権限足りてない。

今度はIAMかよ。

BUILD/POST BUILDでCOMMAND_EXECUTION_ERROR

ECRにリポジトリも作成し、さてそろそろ完成かな、と思ったらやっぱりエラー。
本当に一歩ずつだな!

COMMAND_EXECUTION_ERROR: Error while executing command: docker build -t XXX-build .. Reason: exit status 1
COMMAND_EXECUTION_ERROR: Error while executing command: docker push ${REPOSITORY_URI}:latest. Reason: exit status 1

対応

buildspec.ymlをどこぞから流用して作ったんだけど、

buildspec.yml
  build:
    commands:
      - docker build -t XXX-build .
      - docker tag XXX-build:latest ${REPOSITORY_URI}:latest

XXX-buildの部分ってECRのリポジトリの部分と一致していないとダメなのか。そうなのかー。あんまり気づいておらず、適当に修正してしまっていた。
image.png
ECRの当該リポジトリのプッシュコマンドをちゃんと見て、それとbuildspec.ymlを合わせないとうまく動作しないね!

BUILDでCOMMAND_EXECUTION_ERROR - take2

ちょっと進んだけどやっぱりエラー。しかもExitStatusは一緒…。わけわからん。

COMMAND_EXECUTION_ERROR: Error while executing command: docker build -t custom-image-build .. Reason: exit status 1

対応

これ元々こんな感じのシェルをDockerfileから呼び出してRedisをインストールするようにしていたのだけど(これもどこぞから流用した)、redis-5.0.4-1.el7このパッケージがもうないんだよね。他にもこういうのに悩まされた。

install.sh
#!/bin/sh

# 必要なリポジトリの有効化
yum -y install epel-release
yum -y install wget
wget http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
rpm -Uvh remi-release-7.rpm
yum-config-manager --enable epel epel-release remi remi-release

# Redisのインストール
yum -y install --enablerepo=epel,remi redis-5.0.4-1.el7.remi.x86_64

CodeBuildにこんなログ出てはいるんだけど、完全に見落としてて、ずっと他の部分を調査してた。

Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
 * base: d36uatko69830t.cloudfront.net
 * epel: d2lzkl7pfhq30w.cloudfront.net
 * extras: d36uatko69830t.cloudfront.net
 * remi: ftp.riken.jp
 * remi-safe: ftp.riken.jp
 * updates: d36uatko69830t.cloudfront.net
No package redis-5.0.4-1.el7.remi.x86_64 available.

No packageとかNot Foundとかを見逃さないこと。ErrorとかWarning表記になってないので、ちゃんとログを見ないとわからない。

余談

CodebuildのExit status一覧どこにあるのよマジで。ちらっと探しただけだと見つからないし。

カスタムイメージを用いたビルドまで。

pull access denied

buildspec.ymlを適当にかいてCodebuildで動作させてみると、PROVISIONINGでエラーが出る。

BUILD_CONTAINER_UNABLE_TO_PULL_IMAGE: Unable to pull customer's container image. 
CannotPullContainerError: Error response from daemon: pull access denied for 
XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/custom-docker-image, repository does not exist or may require 'docker login'

docker login?特権権限がないから?、と思って再度やってみてもやっぱりエラーが出る。そこまで安易じゃなかった。

対応

[アクション] で、プル専用アクションとして [ecr:GetDownloadUrlForLayer]、[ecr:BatchGetImage]、および [ecr:BatchCheckLayerAvailability] を選択します。
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-ecr.html

ECRにCodebuildからpullできる権限付与が必要なのである。CodeBuildからECRにアクセスする権限も必要だし、なんか色々めんどいな。

PRE_BUILDでCOMMAND_EXECUTION_ERROR

まあ上記を修正しても当然のようにエラー。

COMMAND_EXECUTION_ERROR: Error while executing command: make setup. Reason: exit status 127

ログは…(流石にログの見方も段々慣れてきた。)

[Container] 2020/06/09 02:43:58 Running command make setup
/codebuild/output/tmp/script.sh: line 4: make: command not found

はあ。make入ってないですか。そうですか。そうですね。インストールしなきゃね。

対応

カスタムイメージ側に以下の対処。BuildしてECRに再PUSH

yum -y install gcc
yum -y install make

PRE_BUILDでCOMMAND_EXECUTION_ERROR - take2

またかよ!Status変わってるし。

COMMAND_EXECUTION_ERROR: Error while executing command: make setup. Reason: exit status 2

ログを見ると

golint -set_exit_status ./...
make: golint: Command not found
make: *** [lint] Error 127

あーもう。PATHが通ってない。
というわけでhttps://github.com/golang/lint を参考にどこにインストールされているか調べてみると、

go list -f {{.Target}} golang.org/x/lint/golint
/codebuild/output/src813842990/bin/golint

ここである。$GOPATHが/codebuild/output/src813842990を指していたので、その下にPATHを通せばよいことが判明。

対応

https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html
じゃあ上記を参考にbuildspec.ymlのenvシーケンスに書けばいいのね?と思ったら、envシーケンス内はリテラルになるため変数展開できないことが判明。
マニュアルに書いとけよ。読んでも分かんないよ。

つまり、

buildspec.yml
env:
  variables:
    PATH: ${GOPATH}/bin:${PATH}

は駄目で、↓のようにする必要がある。

buildspec.yml
  pre_build:
    commands:
      - export PATH=${GOPATH}/bin:${PATH} && echo ${PATH}

これで完了!やったね!
ってS3アップロードまで出来てない気がする。もう疲れた。

結論

FAQに入れとけよと思うよマジで。
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/troubleshooting.html

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5