MicroK8s で kustomization.yaml を apply すると error: accumulating resources になる問題

Pocket

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 操作に支障が出るので注意。

毎回環境変数を指定するのが面倒な場合、 kubectlhelm といったよく使うコマンドで、環境変数 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' のエラーになるだろう。


  1. クエリに 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'. のエラーになる。 

  2. 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 

  3. https://github.com/git/git/blob/v2.45.2/contrib/buildsystems/CMakeLists.txt#L236 

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください