inductor's blog

nothing but self note :)

KUBECONFIGのすべて

はじめに

このエントリーは、Google Cloudのエンジニアである@ahmetb氏ブログ記事を日本語訳したものです。

以下のツイートを見つけて、良さそうだったので翻訳の許可をいただきました。

KUBECONFIGのすべて

kubectlが動作するその裏側には、kubeconfigというファイルの存在があります。このファイルは一般的には$HOME/.kube/configに存在しています。私がkubectxを作るなかで、このようなTips記事が書けるくらいにはkubeconfigと長く戯れてきました。

もしkubeconfigファイルがなんだかわからないと言う場合は、最初にこの記事をお読みください。

Tip 1: kubeconfigの優先順位について知る

kubectlを使うにあたって、使用したいkubeconfigを指定するための設定には優先順位があります。

  1. 指定がある場合に、--kubeconfigフラグを使う
  2. 指定がある場合に、環境変数KUBECONFIGを使う
  3. $HOME/.kube/configのファイルを使う

こうすることで、コマンドの実行単位ごとに使いたいkubeconfigの指定先を簡単に上書きできます。

kubectl get pods --kubeconfig=file1
kubectl get pods --kubeconfig=file2

# or:

KUBECONFIG=file1 kubectl get pods
KUBECONFIG=file2 kubectl get pods

この優先順位は公式には明言されていませんが、コード上に残されています

Kubernetes用のクライアントツールを開発している場合、この標準仕様(--kubeconfigフラグ及び$KUBECONFIG関連をプログラム内で検知する)を適用するためにcli-runtimeの利用を検討すべきでしょう。

Tip 2: 複数のkubeconfigを同時に使う

複数のkubeconfigがあって(例えば、クラスターごとにファイルが分割されている場合)、それらを同時に使いたい場合があったとします。kubectlkubectxなどのツールでは複数のコンテキストを同時に指定しても動作します。

これを行うためには、マージ済みのkubeconfigファイルが必要です。Tips 3では複数のkubeconfigを単一のファイルにマージして扱うための方法が説明されていますが、そうせずにインメモリでマージを行うこともできます。

環境変数KUBECONFIG内で複数ファイルを指定することで、kubectlの中で一時的に複数のkubeconfigを一緒に使うことができます。

export KUBECONFIG=file1:file2
kubectl get pods --context=cluster-1
kubectl get pods --context=cluster-2

Tip 3: 複数のkubeconfigファイルをマージする

kubeconfigはYAMLの構造をしているため、複数のファイルを単に結合させるだけでは一つの大きなkubeconfigを得ることはできません。しかし、kubectlを以下のように使うことで複数ファイルをマージすることができます。

KUBECONFIG=file1:file2:file3 kubectl config view --merge --flatten > out.txt

Tip 4: kubeconfigファイルからコンテキストを抽出する

Tips 3に従ってマージ済みのkubeconfigがあるとします。単一のクラスターに関する情報を取り出したいときに、このファイルから接続するのに必要な情報だけを取り出したい場合、以下を実行します。

KUBECONFIG=in.txt kubectl config view \
    --minify --flatten --context=context-1 > out.txt

このコマンドでは、複数クラスターの情報を含むin.txtからcontext-1に関する情報を取り出して、out.txtに保存しています。--minifyフラグは特定のコンテキストだけを取り出すために使われ、--flattenフラグは秘匿情報に手を入れないために使われています。

Tip 5: kubeconfigを使わずにkubectlを使う

kubectlコマンドは、kubeconfigファイルから読み取るほとんどすべての情報をオーバーライドできるようにする一連のコマンドラインフラグ(kubectl optionsを使うと見れます)を提供します。

例えば、ローカル環境にあるDocker for Mac上のクラスターをkubeconfigなしで使いたい場合、kubectl config view --context=docker-for-desktopを使ってクラスター接続用の情報を確認したあと、以下のようにフラグを組み合わせてデータを渡します。

KUBECONFIG= kubectl get nodes \
    --server https://localhost:6443 \
    --user docker-for-desktop \
    --client-certificate my.cert \
    --client-key my.key \
    --insecure-skip-tls-verify

この方法は、ご自身のkubeconfigが複雑に慣ればなるほどやりづらくなります(最終的には、不可能になるでしょう)。例えば複数のフィールドを持つためにCLI上で設定が難しいような認証プラグイン(訳注: awsのIAM authenticatorとかですかね、多分)を使う場合などがそうです。

これを実行後は余計な事故を防ぐために$KUBECONFIGを空にするのを忘れないでください。

(ボーナス)Tip 6: ディレクトリベースの自動$KUBECONFIG

多くの人が、間違ったクラスター上でコマンドを叩いてしまった、と文句を言うのを見かけます。ほとんどの場合、これはcluster-1用のマニフェストが存在するディレクトリ上でcluster-2のコンテキストをアクティブにしたままapplyを実行してしまうことが原因で発生します。

こうしたシナリオを防ぐためには、direnvを使うことで特定のディレクトリごとに違う環境変数を読み込ませると言う方法があります。こうすると、cluster-1用マニフェストが存在するディレクトリに移動してきたときに、direnvが自動的に$KUBECONFIGをcluster-1用に変更してくれ、災害を防ぐことができます。

(ボーナス)Tip 7: どのコンテキストに向いてるかを知る

これはKUBECONFIGファイルに直接関係ない対応ですが、kube-ps1(まだツールとしては十分に枯れていないことに注意してください)がお使いのbash/zshに現在アクティブなネームスペース/コンテキストを表示してくれます。

$ kubeon
{|N/A:N/A} $ export KUBECONFIG=f2
{|docker-for-desktop:default} $ export KUBECONFIG=f1
{|gke_ahmetb-samples-playground_us-central1-b_demo:kube-system} $ kubens default
Active namespace is "default".
{|gke_ahmetb-samples-playground_us-central1-b_demo:default} $ kubeoff
$

シェルごとにON/OFFを切り替えることもできますし、-gフラグを渡すことでグローバルにON/OFFを切り替えることもできます。

(ボーナス)Tip 8: GKEコンテキストを複数ファイルに分けて保存する

通常、gcloudコマンドを使ってGKEクラスターを作成(もしくは、認証情報の取得)すると、デフォルトの~/.kube/configが書き換えられます。しかし、コマンド実行時に$KUBECONFIGを指定することでgcloudが保存するファイルを指定することができます。

KUBECONFIG=c1.yaml gcloud container clusters get-credentials "cluster-1"