今の時代、VM ベースのクラウド基盤だけでなく、Docker や Kubernetes (K8s) などのコンテナ基盤が広く使われています。
こんな時代だと、おうちクラウドを使っている人に限らず、他の人と環境を共有していたり、複数の環境を切り替えて作業しなければならない場面は多いのでは無いでしょうか?
例えば、複数の K8s クラスタを切り替えながらアクセスしないといけない、とか。
PC ----> K8s Cluster A
|
+--> K8s Cluster B
|
+--> K8s Cluster C
: :
例えば、共有の検証環境が VPN 越しにアクセスできる踏み台の先にある、とか。
PC ---(VPN)---> 踏み台 ---> 検証環境
意外とあるあるな状況だと思いますが、あるある過ぎて、この煩わしさを解消することを諦めていたり、そもそも解消する対象ですらなかったりしませんか?
今回は、こんな煩わしさを direnv というツールで解消してしまおう、というお話。
direnv って何?
そもそも direnv ってどんなことができるツールなの?ということから。
(公式) direnv/direnv: unclutter your .profile
まず、一言で紹介すると、
「そのディレクトリに居る間だけ、設定したい環境変数を設定できるツール」
です。
超ざっくり説明なので、語弊はありますが、こんな↓ディレクトリ構造があり、ChildDirB
で direnv を使った場合、
ParentDir
├── ChildDirA
├── ChildDirB <--- ここで direnv を使う
└── ChildDirC
ParentDir
など他のディレクトリから ChildDirB
に移動したタイミングで、あらかじめ用意しておいた環境変数が読み込まれ、ChildDirB
から他のディレクトリに移動したら、その設定を解除することができます。
「ん??何が嬉しいの???」と思う方もいらっしゃるかと思いますが、これが!便利なんですよ!奥さん!!
環境変数って、実は色々な可能性を秘めていて、ご存知の通りではありますが、
- PATH ... (正確な説明は割愛しますが) 実行ファイルが格納されているフォルダのリスト。列挙することで、フルパス指定しなくても実行できるようになる。
- HTTP_PROXY/HTTPS_PROXY ... HTTP/HTTPS リクエストを発行する際のプロキシサーバーを指定。(少なくとも私の中では) 悪名高き環境変数で、こいつのせいで、どれだk...(げふんげふん
- KUBECONFIG ... 実は
kubectl
で利用するkubeconfig
(デフォルトは$HOME/.kube/config
) も指定できる。
などなど、ハックに使えそうな匂いが、もう、プンプンするものが沢山あるんです!
とは言え、まだまだ「え〜?.bashrc
とか .profile
とか書くアレでしょ〜?」という感じかと思いますので、簡単に direnv の使い方を見た後、タイトル通り、便利な活用例を 3つご紹介します。
direnv の使い方
と言っても、そんなに難しくはありません。Unix ライクな OS であれば、一通りインストールできます。詳しくは、GitHub の公式ドキュメントをご参照ください。
(公式) direnv/installation.md at master · direnv/direnv
私は、手元が Mac だったので、Homebrew でインストールしました。
brew install direnv
で、ここで重要ポイントです!!インストールしただけでは、direnv は動作しません!
お使いのシェル (bash とか zsh とか) に direnv をフック (仕込み) してあげる必要があります。
(公式) direnv/hook.md at master · direnv/direnv
私は手元のシェルが Mac のデフォルト zsh だったので、~/.zshrc
の末尾に、下記を追記しました。
# ~/.zshrc の末尾に↓を追記
eval "$(direnv hook zsh)"
これで使う準備は整ったので、活用例を見ながら、動かして行きます。
活用パターン①: 複数 Kubernetes クラスタの切り替え
冒頭に触れた「K8s クラスタが複数あって、切り替えが面倒」への対策例です。
PC ----> K8s Cluster A
|
+--> K8s Cluster B
|
+--> K8s Cluster C
: :
kubectl
などを操作する端末は 1台ですが、管理対象の K8s が複数あるので、同じコマンドを発行するにも
kubectl config use-context <K8s Cluster A>
- コマンド実行
kubectl config use-context <K8s Cluster B>
- コマンド実行
kubectl config use-context <K8s Cluster C>
- コマンド実行
とする必要があります。もちろん、これを解決する方法やツールはたくさんありますが、
「コマンドが 1回きりなんだよね」
「コマンド応答を確認しながら、試したいんだよね」
など、そこまで何か仕組みを使って実施すべきものでもなく、サクッとやりたい場面はあると思います。
この活用例①では、お馴染みの cd
コマンドでディレクトリ移動するような感覚で、K8s クラスタを切り替えられるようにしてみたいと思います。
まず、全体の作業ディレクトリを用意しています。
% pwd
/Users/yusukei/work
K8s Cluster A 用のディレクトリと、その kubeconfig を格納するディレクトリを作成します。
% mkdir -p K8sClusterA/.kube
作成したディレクトリまで移動し、direnv の設定ファイルである .envrc
に、「このフォルダにある kubeconfig を使え」という環境変数を書き込みます。
% cd K8sClusterA
% echo export KUBECONFIG=/Users/yusukei/work/K8sClusterA/.kube/config > .envrc
direnv: error /Users/yusukei/work/K8sClusterA/.envrc is blocked. Run `direnv allow` to approve its content
初回作成した .envrc
なので、「まだ direnv に読み込み許可がないですよ」という警告が出ていますが、期待される動作なので、指示の通りに、direnv allow
を実行していきます。
% direnv allow .
direnv: loading ~/work/K8sClusterA/.envrc
direnv: export +KUBECONFIG
これで、K8sClusterA のディレクトリまで移動した際には、kubeconfig の環境変数が読み込まれます。
確認として env
コマンドを叩くと、その様子が確認できます。
% env
...(snip)...
KUBECONFIG=/Users/yusukei/work/K8sClusterA/.kube/config
...(snip)...
同じ容量で、他のクラスタについても用意すると、こんな↓感じです。
work
├── K8sClusterA
│ ├── .envrc
│ └── .kube
├── K8sClusterB
│ ├── .envrc
│ └── .kube
└── K8sClusterC
├── .envrc
└── .kube
これの準備が手間と言えれば手間ではありますが、一旦、用意さえしてしまえば、cd
コマンドを使って、目的の K8s クラスタ名のディレクトリへ移動するだけで、kubeconfig を切り替えることができます。原始的な感じはしますが、個人的には、cd
コマンドが「なんか移動してる!」感があり、直感的で気に入ってます。また、クラスタ毎にやりたい操作って、似ているようで微妙に違ったり、それぞれにログを残したい場面もあったりするので、ディレクトリに収まる感じも良いです。
ただ、あくまで好みなので、プロンプトに K8s Context を表示したり、kubectx
などのツールを使うのも、全然アリだと思っています。
活用パターン②: リモートアクセス時の環境変数切り替え
こちらも冒頭に触れた「検証環境が踏み台の先にある」という状況を、(ちょっとだけ?) 便利にする方法です。
PC ---(VPN)---> 踏み台 ---> 検証環境
前提として、踏み台に、または同じように手元の PC からアクセスできるところに、HTTP Proxy があることが条件になるので、「ちょっと用意できないよ」という場合には使えません...(すみません)
ですが、RDP や VNC のようにリモートのデスクトップ画面越しに操作するより、手元の PC のブラウザやツール (kubectl
とか) で操作できる方が体感が良いので、個人的にはリモート環境には、HTTP Proxy を立てることが良いと思っています。
踏み台として Linux マシンを使ったり、あるいは入り口のルーターとして VyOS を使ったりする場面も多いかと思いますので、その場合、便利に HTTP Proxy を立てる方法を別の機会に記事にできればと思います。
ちょっと話が逸れましたが、この活用例では、こんな↓感じの構成を想定して、direnv を仕込んでいきます。
PC ---(VPN)---> 踏み台 (HTTP Proxy) ---> 検証環境
まず、全体の作業ディレクトリを用意しています。
% pwd
/Users/yusukei/work
分かりやすく環境名を付けたディレクトリを作成し、そこに移動します。
% mkdir RemoteLab
% cd RemoteLab
リモート環境に立てている HTTP Proxy を環境変数として、.envrc
に書き込んでいきます。
export http_proxy=http://proxy:port
export https_proxy=http://proxy:port
活用パターン①の時と同様に、direnv 読み込みを許可してあげます。
% direnv allow .
direnv: loading ~/work/RemoteLab/.envrc
direnv: export +http_proxy +https_proxy
これにより、~/work/RemoteLab
ディレクトリに移動すると、自動で HTTP Proxy の設定が入るようになりました。
% cd work/RemoteLab
direnv: loading ~/work/RemoteLab/.envrc
direnv: export +http_proxy +https_proxy
HTTP Proxy の設定が入ることで、wget
や curl
はもちろん、kubectl
も!HTTP Proxy 経由で、叩けるので、リモートの検証環境の K8s であっても操作できます。
別の記事で紹介できればと思いますが、Octant という K8s クライアントツールも、この HTTP Proxy 設定が入った状況で実行すれば、リモートであっても活用できるので、とても便利です。
(公式) Octant - Visualize your Kubernetes workloads
とは言え、「いや、普通に HTTP Proxy 設定すれば良いじゃん」という意見もあるかと思います。少なくとも、Firefox などのブラウザに関しては、拡張機能を使って、HTTP Proxy を簡単にスイッチできちゃいます。それすら面倒なら、システム全体の設定として HTTP Proxy を入れてしまえば良いです。
しかし、話が社内環境だったりすると、
「このシステムへのアクセスには HTTP Proxy を Off にしたい」
「いやいや、こっちのシステムには、別の HTTP Proxy があって...」
「あっちの検証環境には、別の HTTP Proxy 立てたから...」
などなど、メインのブラウザ設定がある中、全面的に HTTP Proxy を設定するのが難しかったりもします。
そこので、「こんな技もあるんだな」くらいに見ていただければと思います。
活用パターン③: 実行バイナリの差し替え
こちらは冒頭のお困りごととは関係ないのですが、個人的に便利な使い方だと思っているので、紹介します。
どういうことかと申しますと、こんな↓シーンに対応したいと思います。
「ちょっとお試しで使いたいツールがあるけど、わざわざ Global には入れたくない」
「けど、フルパス指定 or ./
始まりで指定も面倒」
「あ、あと、別バージョンのツールも裏で使うんだよねぇ」
と言った感じのシーンです。
仕組みは単純で、環境変数 PATH
を弄ります。
まず、作業ディレクトリを用意します。
% pwd
/Users/yusukei/work
% mkdir sandbox
% cd sandbox
分かりやすく、このディレクトリに bin
ディレクトリを作成し、そこにパスが通るように仕掛けていきます。
% mkdir bin
% echo export PATH=$PATH:/Users/yusukei/work/sandbox/bin > .envrc
direnv: error /Users/yusukei/work/sandbox/.envrc is blocked. Run `direnv allow` to approve its content
こうすることで、bin
ディレクトリに入れたバイナリは、このディレクトリ (および配下のディレクトリ) に居る間だけ使えるようになります。なので、Global に入れるとセキュリティチェックが煩わしい Mac だったり、検証のために ver を切り替えたいツールがあったりする場合に、便利なサンドボックスが出来上がります。
私は kubectl とかを突っ込んで、ver 更新をバイナリ置き換えだけでできるようにしていたりします。
% ls bin
kubectl kubectl-vsphere
ただし!!セキュリティ的には、全然サンドボックスでもなんでもなく、カレントディレクトリ (.
) にパスを通しちゃうようなザルセキュリティとやってることは変わらないので、扱いにはご注意ください。
まとめ
ツールとしては単に「.profile
ファイルをディレクトリ毎に用意できる」というだけですが、環境変数と組合せるだけで、こんなこともできるので、ぜひぜひご活用ください!
「こんな活用方法もあるよ!」など、コメントいただけると嬉しいです!