MicroK8s で kustomization.yaml
を apply した際に、 error: accumulating resources
が発生する問題についてのメモ。
端的に言うと、snap でインストールした MicroK8s で、内部的に git コマンドが実行される操作をすると、おかしくなる模様。
発生する問題
snap で MicroK8s をインストールし、 kubectl apply -k
する。
このとき、Kustomize に指定する kustomization.yaml
には、直接的または間接的に remote directory 方式のリソースを参照する。
$ sudo snap install microk8s --classic --channel=latest/stable
$ cat << EOF > ./kustomization.yaml
resources:
- https://github.com/kubernetes-sigs/kustomize//examples/helloWorld/?timeout=120&ref=v3.3.1
EOF
$ microk8s kubectl apply -k .
すると、以下のようなエラーが発生する。
ホストOS に git がインストールされている場合:
error: accumulating resources: accumulation err='accumulating resources from 'https://github.com/kubernetes-sigs/kustomize//examples/helloWorld/?timeout=120&ref=v3.3.1': URL is a git repository': failed to run '/snap/microk8s/6364/usr/bin/git fetch --depth=1 https://github.com/kubernetes-sigs/kustomize v3.3.1': /usr/lib/git-core/git-remote-https: symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0: undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE
: exit status 128
ホストOS に git がインストールされていない場合:
error: accumulating resources: accumulation err='accumulating resources from 'https://github.com/kubernetes-sigs/kustomize//examples/helloWorld/?timeout=120&ref=v3.3.1': URL is a git repository': failed to run '/snap/microk8s/6364/usr/bin/git fetch --depth=1 https://github.com/kubernetes-sigs/kustomize v3.3.1': fatal: unable to find remote helper for 'https'
: exit status 128
ワークアラウンド
以下のように、一時的な環境変数で GIT_EXEC_PATH
が snap 内のパスを指している状態で microk8s を実行する。
$ GIT_EXEC_PATH=/snap/microk8s/current/usr/lib/git-core/ microk8s kubectl apply -k .
configmap/the-map created
service/the-service created
deployment.apps/the-deployment created
システムやシェル全体で環境変数 GIT_EXEC_PATH
を指定すると、 MicroK8s 以外での git 操作に支障が出るので注意。
毎回環境変数を指定するのが面倒な場合、 kubectl
や helm
といったよく使うコマンドで、環境変数 GIT_EXEC_PATH
が設定されるようなエイリアスを設定しておくと良いかもしれない。
$ cat << EOF >> ~/.bash_aliases
alias kubectl='GIT_EXEC_PATH=/snap/microk8s/current/usr/lib/git-core/ microk8s kubectl'
alias helm='GIT_EXEC_PATH=/snap/microk8s/current/usr/lib/git-core/ microk8s helm'
EOF
解説
問題を切り分けしていくと、 Kustomize 内のリソース指定で、以下のような remote directory 方式の書き方をしているとエラーになることがわかる。
resources:
- https://github.com/kubernetes-sigs/kustomize//examples/helloWorld/?ref=v3.3.1
- github.com/kubernetes-sigs/kustomize/examples/helloWorld?ref=v3.3.1
同じ remote directory でも、 git プロトコルや ssh プロトコルで指定している場合はエラーにならない。 1
resources:
- git@github.com:kubernetes-sigs/kustomize//examples/helloWorld/?ref=v3.3.1&submodules=false
- ssh://git@github.com/kubernetes-sigs/kustomize//examples/helloWorld/?ref=v3.3.1&submodules=false
/snap/microk8s/6364/usr/bin/git fetch
で参照されるリモートのパスの指定方法の違いで、エラーが出たり出なかったりするようだ。
git が有る場合のエラーをよく見てみると、 /usr/lib/git-core/git-remote-https
の方でシンボル参照エラーとなっている。
git-remote-https
は Git の一部のコマンドを処理するサブプログラムの一つで、 git
CLI から間接的に呼び出されるものだ。
本来なら、 snap 内の /snap/microk8s/6364/usr/lib/git-core/git-remote-https
が呼び出されるべきなのに、ホストOS のほうが呼び出されてしまっている。
にもかかわらず、そのホストOS側の git-remote-https
が参照するLinux共有ライブラリは、snap 内の /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0
を参照してしまっているために、意図しないリンクとなってシンボル解決エラーとなっているようだ。
つまり、 snap 環境内で、 snap 内の git がホストOS 側の /usr/lib/git-core/git-remote-https
を実行しているのが原因と考えられる。
そう考えると、ホスト OS に git が無い場合のエラーも同じで、ホストOS 側の /usr/lib/git-core/git-remote-https
を実行しようとするものの、それが見つからないために fatal: unable to find remote helper for 'https'
となっていることがわかる。
git プロトコルや ssh プロトコルを使う場合は、 Git のサブコマンドを呼び出さないので、エラーにならないのだろう。
Gitのサブプログラムが置かれているディレクトリは、 GIT_EXEC_PATH
の環境変数で場所を変更できる。 2
このためワークアラウンドでは、 snap 内の microk8s を呼び出す場合だけ GIT_EXEC_PATH
の環境変数により snap 内のパスを参照させることで、エラーを解決している。
おそらく、 snapパッケージ内で GIT_EXEC_PATH
の環境変数を定義してもらえば問題は解決すると思われるが、 Snapcraft にあまり明るくないのでそれが正しい解決方法なのかはわかりかねる。
一応、 GitHub に Issue は立てているが、いつ解決されるは不明。
補足
snap を実行する OS が Ubuntu 以外だと、エラーの発生パターンが異なる場合がある。
Git がサブプログラムを探すディレクトリは git --exec-path
で確認できる。 2
環境変数 GIT_EXEC_PATH
の指定がない場合の規定値が /usr/lib/git-core
となっているのは Debian系 (Ubuntu 等) の一部だけだ。
多くの Linux ディストリビューションでは、 /usr/libexec/git-core
が規定値となっている。 3
MicroK8s の snap ユニバーサルパッケージは、 core20 依存、すなわち Ubuntu 20.04 LTS をベースとした環境になっているので、 /usr/lib/git-core
を探しに行く。
一方、呼び出し元が Fedora 系 (RHEL 等) などの場合は /usr/libexec/git-core
にサブプログラムが存在するので、仮にホストOS側に git がインストールされているとしても unable to find remote helper for 'https'
のエラーになるだろう。
-
クエリに
submodules=false
をつけていないとfailed to run '/snap/microk8s/6364/usr/bin/git submodule update --init --recursive': git: 'submodule' is not a git command. See 'git --help'.
のエラーになる。 ↩ -
https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0 ↩ ↩
-
https://github.com/git/git/blob/v2.45.2/contrib/buildsystems/CMakeLists.txt#L236 ↩