アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

asdf で複数バージョンのCLI を使い分ける

morishitaです。

今回は asdf について書きます。

いこーよは EKS で運用しており、9 月まで kubenetes 1.17 を利用していました。 EKS を導入しようと移行作業をしていたときにはそれほどアップデートのペースは速くないと思ってのんびり構えていました。
しかし、最近、AWS が頑張ってアップデートのペースを上げ始め、今年の 11 月の初めに 1.17 は EOS というではないですか!
他に忙しいので、もうアップデートは少し先送りしたかったのですが EOS 前にアップデートしなくちゃということで 9 月末に 1.21(現時点の EKS での最新バージョン)にアップデートしました。

当社では既存のクラスターをアップデートするのではなく、新たなクラスターを作成して切り替える方法でアップデートしています。
準備のために検証環境に 1.17 、 1.21 の 2 つのバージョンのクラスターを作成し、検証作業を進めていたところ、1.21 にマニフェストを適用できない事象が発生しました。
使っていた kubeclt が古いのかなと思ってアップデートすると今度は 1.17 のクラスターに対して接続するとバージョンが合わないという警告が出ました。

調べてみると、kubectl はクラスターに対して上下 2 バージョンまでずれても動作するように配慮されているとのこと1
なので、クラスターが古くなると kubectl で接続した場合に警告がでたり、あるいはバージョンが合わなくてうまく動作しない場合があるようです。
複数のバージョンが異なるクラスターに接続する場合には、それぞれ適したバージョンの kubectl を使い分けしたくなります。

asdf とは?

asdf は各種 CLI ツールのバージョン管理ツールです。
例えば、複数のバージョンの awscli を切り替えながら使いたいといったニーズに答える CLI ツールです。

拡張可能となっており、プラグインを追加することにより様々な CLI ツールに対応可能となります。
現状、400 以上のプラグインが利用可能です2

プラグインには rubypython などの主要言語もあり、バラバラのバージョンで開発されている複数のプロダクトをメンテナンスしなければならない場合に便利そうです。

リポジトリ:asdf-vm/asdf: Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more

そして、kubectl のプラグインもあり、これを使えば kubectl の複数のバージョンを切り替えながら利用できそうです。

以降、kubectl を例に asdf で CLI ツールの複数バージョンの使い分ける方法を紹介します。

asdf のインストール

まずは asdf 自体のインストールです。
Mac OS では Homebrew を利用すれば簡単にインストールできます。 その他の環境へのインストールはGetting Started | asdfに記載されています。

kubectl plugin をインストールする

続いて kubectl プラグインを次のコマンドでインストールします。

❯ asdf plugin add kubectl https://github.com/Banno/asdf-kubectl.git

これで kukbectl をバージョン指定してインストールできるようになります。 次のコマンドを実行すればインストール可能な kubectl のバージョンが表示されます。

❯ asdf list all kubectl

上記コマンドの結果から接続先の Kubernetes クラスタのバージョンに対応したもの探してインストールします。
次のコマンドはバージョン 1.17.17 と 1.22.1 インストールする場合の例です。

❯ asdf install kubectl 1.17.17
❯ asdf install kubectl 1.22.1

インストールしたバージョンを確認します。

❯ asdf list kubectl
  1.17.17
  1.22.1

ちゃんとありますね。

さて、ここまで目的のバージョンの kubectl がインストールできました。
実際に利用するにはもうひと手間必要で、次のコマンドを実行すると指定したバージョンの kubectl が利用可能となります。

❯ asdf global kubectl 1.22.1

上記は、kubectl のバージョン1.22.1 をグローバルに利用する例です。
実行すると $HOME/.tool-versions に指定したバージョンが記録され、そのバージョンの kubectl が実行されるようになります。

特定のディレクトリ以下でバージョンを指定したい場合には次のコマンドを実行します。

❯ asdf local kubectl 1.22.1

上記を実行するとそのディレクトリに .tool-versions に指定したバージョンが記録されています。

バージョンの切り替えを確認してみましょう。

❯ asdf local kubectl 1.17.17
❯ asdf current kubectl
kubectl         1.17.17         /tmp/.tool-versions
❯ kubectl version --client
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.17", GitCommit:"f3abc15296f3a3f54e4ee42e830c61047b13895f", GitTreeState:"clean", BuildDate:"2021-01-13T13:21:12Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"darwin/amd64"}

❯ asdf local kubectl 1.22.1
❯ asdf current kubectl
kubectl         1.22.1          /tmp/.tool-versions
❯ kubectl version --client
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.1", GitCommit:"632ed300f2c34f6d6d15ca4cef3d3c7073412212", GitTreeState:"clean", BuildDate:"2021-08-19T15:45:37Z", GoVersion:"go1.16.7", Compiler:"gc", Platform:"darwin/amd64"}

切り替わっていますね。 こうして、必要な kubectl のバージョンをインストールして使い分けることできるようになりました。

まとめ

kubectl のバージョンを使い分ける必要性から asdf を利用してそれを実現する方法を紹介しました。
kubectl の様にクライアントとなる CLI のバージョンにセンシティブな場合では便利ですが、他の一般的な CLI ツールでは複数バージョンを使い分けたい局面というのはそれほど多くないように思います。
しかし、asdf のプラグインには各種プログラミング言語もあり、例えば次の言語が利用可能です。

  • python
  • ruby
  • elixir
  • golang
  • julia
  • nodejs

私は今の所これらの言語の複数バージョン管理に anyenv を利用していますが、 asdf に切り替えてもいいかなと思い始めています。
asdf を使う場合 rbenv-gemset に相当するツールがないようです。今後も作られる様子はなく、gemset より bundler を使えばいいじゃないという考えのようです3
これまで便利に gemset を利用してきた私的には残念ですが、まあ、それもそうかなと思い始めている次第です。

おまけ:asdf Tips

以下は kubeclt とは関係ない一般的な asdf の運用でよく使うサブコマンドです。
自分の備忘録を兼ねて紹介します。

利用できるpluginの一覧を表示する
❯ asdf plugin list all
インストールされているpluginの一覧を表示する
❯ asdf plugin list
インストールしている特定の plugin のバージョン一覧を表示する
❯ asdf list <plugin名>
特定のpluginの利用可能なバージョンの一覧を表示する
❯ asdf list all <plugin名>
現在有効なすべてのpluginのバージョンを表示する
❯ asdf current

最後に

アクトインディではエンジニアを募集しています。

actindi.net