GitLab CI/CD から ECR へ PUSH するところを作りました。つらみがあって大変に時間を溶かしました。
- alpine ベースの Docker Image に AWS CLI v2 をインストールするのがつらい
- Docker のバグを引いてしまって GitLab CI/CD 上での DinD がうまく動かなかったのがつらい
- ECR への PUSH
原理的に何も難しいところはないのですが、つらかったところは以下になります。
- alpine ベースの Docker Image に AWS CLI v2 をインストールするのがつらい
- Docker のバグ(?)を引いてしまい、GitLab CI/CD 上での DinD がうまく動かなかったのでつらい
この辛みはあとで書くとして、.gitlab-ci.yml
の該当箇所はこんな形で良かったです。
事前の Stage で GitLab Container Registroy 上に PUSH されているアプリケーション(backend[12])を、それぞれ ECR に PUSH するという例。
スクリプトは後段に貼ってます。
.deploy-ecr: image: docker:19.03.13 stage: deploy-to-ecr variables: AWS_DEFAULT_REGION: $ECR_AWS_DEFAULT_REGION services: - name: docker:19.03.13-dind only: refs: - master before_script: - .ci/install-awscliv2-on-alpine.sh deploy-backend1-to-ecr: extends: .deploy-ecr variables: IMAGE_PUSHED_TO_ECR: $CI_REGISTRY_IMAGE/backend1:$CI_COMMIT_REF_NAME script: - .ci/deploy-to-ecr.sh deploy-backend2-to-ecr: extends: .deploy-ecr variables: IMAGE_PUSHED_TO_ECR: $CI_REGISTRY_IMAGE/backend2:$CI_COMMIT_REF_NAME script: - .ci/deploy-to-ecr.sh
alpine ベースの Docker Image に AWS CLI v2 をインストールするのがつらい
このツラミについては前に書きました。
だいたい以下のようなスクリプトを書いておけば alpine ベースの Container Image で AWS CLI v2 が使えるようになります。
#!/bin/sh set -eux # https://hub.docker.com/_/docker 等、alpine ベースの Container に対する AWS CLI v2 のインストールには glibc が必要 # see: https://stackoverflow.com/questions/60298619/awscli-version-2-on-alpine-linux/61268529#61268529 GLIBC_VER=2.31-r0 # install glibc 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 apk add --no-cache glibc-${GLIBC_VER}.apk glibc-bin-${GLIBC_VER}.apk # install awscliv2 curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip unzip -q awscliv2.zip aws/install
Docker のバグを引いてしまって GitLab CI/CD 上での DinD がうまく動かなかったのがつらい
GitLab CI/CD で Docker Executor を利用する前提で
docker image push
等の docker コマンドを使おうとすると、DinD が選択肢になります。
しかしこの DinD を使うにあたって docker 19.03.12
を利用していたときにピンポイントでバグ挙動を引いてしまいました。
DinD 利用時に以下のエラーが発生してしまうというものです。
Cannot connect to the Docker daemon at <some address>. Is the docker daemon running?
おおよそ、この 1 年前の issue の状況と酷似しています。
私の場合、19.03.12
でこれを回避するためには、19.03.0
のバグへの以下の回避策が有効でした。
- entrypoint を通るときは
DOCKER_HOST
環境変数を無効化する - TLS 設定をしておく
deploy-backend-to-ecr: image: docker:19.03.12 services: - name: docker:19.03.12-dind entrypoint: ["env", "-u", "DOCKER_HOST"] command: ["dockerd-entrypoint.sh"] variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" DOCKER_DRIVER: overlay2 (略)
19.0.13
を設定すると嘘のようにエラーと遭遇することがなくなり、冒頭で示した通り非常にシンプルになりました。
ECR への PUSH
これは何のひねりもないです。珍しく bash ではなく sh を使っているのは諸々の事情によるものです。
#!/bin/sh # GitLab Container Repository 上の Image ($IMAGE_PUSHED_TO_ECR) にタグ付けした上で ECR に PUSH する set -eux # GitLab Container Registry から、branch に対応する Image を Pull する docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY docker image pull $IMAGE_PUSHED_TO_ECR # ECR 用のタグ付け docker image tag $IMAGE_PUSHED_TO_ECR $ECR_REPOSITORY:$CI_COMMIT_REF_NAME docker image tag $IMAGE_PUSHED_TO_ECR $ECR_REPOSITORY:$CI_COMMIT_SHORT_SHA # master branch への merge の場合は latest タグを付与する if [ "$CI_COMMIT_REF_NAME" == "master" ]; then docker image tag $IMAGE_PUSHED_TO_ECR $ECR_REPOSITORY:latest fi aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REPOSITORY docker image push $ECR_REPOSITORY