YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

skaffoldのdefault repoの設定はグローバルでなくkubectlのコンテキスト依存

何が起きたか

GKEで新たなクラスタを建てて skaffold dev をしたら次のエラーで止まった。

exiting dev mode because first run failed: build failed: building [xxxxxx]: tagging: pushing: denied: requested access to the resource is denied

後半はDockerでレポジトリのアクセスが出来ない時のエラーなので、ログをちょっと遡ると原因となるものがあった。

The push refers to repository [docker.io/library/xxxxxx]

本当なら docker.io/library ではなくて gcr.io/<MY REPOSITORY> を見ていないといけない。

どうしてこうなったか

まず skaffold.yamlartifacts でターゲットのレポジトリの設定をしていないから。

しかし設定していない理由があって、skaffold.yaml でレポジトリの設定をしてしまうと、テストとかで動かすときにいちいち書き換えなければならないので面倒。 固定でいいならはじめから artifacts にレポジトリを明示的に指定しておけば良い。こんな具合に。

apiVersion: skaffold/v1alpha1
kind: Config
build:
  artifacts:
  - imageName: gcr.io/<MY REPOSITORY>/foo
    workspace: ./foo
...

skaffold には新しいオプションが加わって、最近レポジトリを動的に差し込めるようになった。

skaffold.dev

どうせ自分のテスト環境はレポジトリ1個しかないので「グローバルの設定」で済まそうと思って3つめのオプションを選択。 最初に設定したときはこれで問題なかったが、テスト用に新たにGKEクラスターを作って古い方を消したときに上記の問題が起きた。

再度手順を振り返って一つずつコマンドを叩いて確認してみると

$ skaffold config set default-repo gcr.io/yoshifumi-cloud-demo
set value default-repo to gcr.io/yoshifumi-cloud-demo for context gkc_yoshifumi-cloud-demo_<ZONE>_<CLUSTER_NAME> 

これは普通に kubectl のコンテキストに紐付いていて、実際に skaffold の設定ファイル(~/.skaffold/config)を見るとそうなっている。

kubeContexts:
- kube-context: gke_yoshifumi-cloud-demo_<ZONE>_<CLUSTER_NAME>
  default-repo: gcr.io/yoshifumi-cloud-demo

というわけで

  • skaffold.yamlartifacts でイメージ名内に明示的に指定していなかったこと(これは意図的)
  • グローバルに設定されると思ってたがそれがドキュメントバグらしいということ

の2つが原因だった。

どうするのがいいか

とりあえず2つめのオプションである SKAFFOLD_DEFAULT_REPO を都度渡すというのが良さそう。つまり

$ SKAFFOLD_DEFUALT_REPO=gcr.io/yoshifumi-cloud-demo skaffold dev

のような形にするということ。この辺りの処理はこの辺で実装されている。(2019.01.23現在 master)

github.com

しかしこのドキュメントは明らかにミスリードなので報告しとこう。。。

Change the explanation of "default repo" setting in the doc to reflect actual implementation · Issue #1516 · GoogleContainerTools/skaffold · GitHub