GCP に関する投稿を表示しています

Google Cloud Build + kaniko を試す

Cloud Build のドキュメントを見ていたら、ビルドを高速化するのに kaniko を使うソリューションがあるよ、と書かれていたので、試してみる。

Kaniko キャッシュの使用 | Cloud Build | Google Cloud
GitHub - GoogleContainerTools/kaniko: Build Container Images In Kubernetes

kaniko っていうのはすごいざっくりと理解したのは Docker なしに k8s 上で Docker イメージをビルドできるよ、というもの。
で、そのとき対象の Dockerfile に関して、レイヤーごとに全部キャッシュを取ってくれるので、差分があった部分以降をビルドするだけになり docker build よりも高速化できる、という話っぽい。通常 docker build するときも、レイヤーごとの情報を持っていて、変わった部分以降をビルドすることができる。できるが、そのキャッシュのバックエンドとか、マルチステージにしたときのビルドステップの進め方とかをいい感じにしたっていう話なんじゃあないかなあ。(それ以上の理解はできていない)

さて、ビルドする対象となる Dockerfile はこういう具合。
マルチステージで go で書かれたアプリケーションサーバのビルド、からのそのアプリケーションコンテナのイメージを作る。

FROM golang:1.12 as builder
ARG GITHUB_TOKEN
ARG VERSION
ENV GO111MODULE=on

WORKDIR /go/src/github.com/foo/bar

COPY go.mod go.sum ./
RUN echo "machine github.com login ${GITHUB_TOKEN}" > ~/.netrc
RUN go mod download

COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go install -v -ldflags "-X main.version=${VERSION}" github.com/foo/bar/cmd/server

FROM alpine:latest

RUN apk add --update --no-cache ca-certificates tzdata
COPY --from=builder /go/bin/server /bin/server
CMD ["/bin/server"]

それでもとの cloudbuild.yaml はこうなっている。
変数をバケツリレーしていく。

steps:
- name: gcr.io/cloud-builders/docker
  args:
  - build
  - -t
  - $_IMAGE
  - --build-arg
  - GITHUB_TOKEN=$_GITHUB_TOKEN
  - --build-arg
  - VERSION=$_VERSION
  - -f
  - $_DOCKERFILE_PATH
  - .
images:
  - $_IMAGE

で、これを kaniko に対応させるとこうなる。

steps:
- name: 'gcr.io/kaniko-project/executor:latest'
  args:
  - --destination=$_IMAGE
  - --dockerfile=$_DOCKERFILE_PATH
  - --cache=true
  - --cache-ttl=6h
  - --build-arg=GITHUB_TOKEN=$_GITHUB_TOKEN
  - --build-arg=VERSION=$_VERSION

その他 GCP 設定や Dockerfile などなどはそのままで実行することはできた。

できたが結果はちょっと微妙で、めっちゃ早くなったかというとそうでもない。。。

ビルド時、主に時間がかかるのが go mod download と go install (実際は go build が時間かかる)のふたつで、アプリケーションのコードを変えただけの場合は go mod のキャッシュが効いてくれるが、レイヤーを持ってくる(?)のにやっぱり時間がかかるので、プラスマイナスみて、ややマイナス、みたいな状態。。

具体的な時間としては kaniko を使う前の元々ので 5 分くらい。 kaniko してフルキャッシュ状態(再実行しただけ)で 1-2 分。 go mod のキャッシュが効いてて 2-4 分くらい。キャッシュがまったくなし = go.mod が変更された場合で 5-7 分くらい。ちゃんと測ってなくて数回ためした程度で、実はもっと早いかもしれない。そこは試す余地がある。

あとは単純にお財布で戦って、マシンサイズを上げて強い子にすると早くなるんじゃないかなあ~。


そもそも、コンテナイメージの作成を早くするのが目的なら CI 上でクロスコンパイルしたバイナリを Docker にいれちゃうのがよさそう。
というか CI 上でも golang:1.12 なイメージでビルドするならば別にクロスコンパイルでもないのか。

マルチステージな Dockerfile でアプリケーションのビルドもまるっと!と Cloud Build でビルドすると、余計なゴミが入りにくい、という良い点はありそう。

とはいえ、ワークスペースをアタッチしない、かつ go mod だけ共有してビルドしちゃえば Cloud Build でやるのとほぼ同じ環境になりそうな気がする。そうしてできたバイナリをコンテナ内に COPY して、コンテナレジストリに登録しちゃえばいいんじゃないかな。

gcloud ssh をいろんな Google Compute Engine インスタンスに向けるアレ

都合、ひとつの GCP プロジェクトにある多数の GCE に繋いだりする場合がある、かもしれない。
で、このインスタンス、増えたり減ったり変わったりして、毎回丁寧にエイリアスを組むのが厳しいので、シュッと選択出来るようなスクリプトを書いた。

このあたりが必要。

#!/bin/sh

__check_command() {
    which $1 > /dev/null
    if [ $? = 1 ]; then
        echo "$1: command not found"
        return 1
    fi
}

export gcloudssh_default_project=""

gcloudssh() {
    __check_command "gcloud"
    if [ $? = 1 ]; then
        return 1
    fi
    __check_command "peco"
    if [ $? = 1 ]; then
        return 1
    fi

    gcloud="gcloud --project \"$gcloudssh_default_project\""
    filter="peco"

    if [ $# = 1 ]; then
        opt="--filter=$1"
        filter="grep $1"
    fi

    echo 'Loading gcloud instances...'
    instance=$(eval "$gcloud compute instances list $opt" | grep -v NAME | eval "$filter" | sed -e 's/  */ /g')
    name=$(echo $instance | cut -d ' ' -f 1 | tr -d ' ')
    zone=$(echo $instance | cut -d ' ' -f 2 | tr -d ' ')

    if [ "$name" = "" ]; then
        echo "Stopped."
        return
    fi
    if [ "$zone" = "" ]; then
        echo "Stopped."
        return
    fi

    echo "Name=$name / Zone=$zone"
    echo "Connecting..."
    echo

    eval "$gcloud compute ssh --zone $zone $name"
}

export gcloudssh_default_project=""のあたりをよしなにして、IAM ロールが問題なければ source gcloudssh.sh とかして、

$ gcloudssh 

で GCE インスタンスの一覧を peco なインタラクティブな選択ができる。あとは選べば gcloud ssh でつないでくれる。

$ gcloudssh hoge-instance-001

とかでも接続できる。

gcloud --filter | grep で見に行くので、インスタンス名ドンピシャじゃなくて hoge とか大雑把な引数でも大丈夫。
zsh や fish なんかではよしなに読み替えて貰う必要がありそう、特に fish だと。


ちなみに gcloud ssh の説明はここ
インスタンスに接続する | Compute Engine ドキュメント | Google Cloud

前後の記事

Next:
Prev: